Compare commits

...

5 Commits

Author SHA1 Message Date
rubenwardy 1f12be0238 More 3d 2019-10-06 14:57:38 +01:00
rubenwardy eb5c69a1b1 Add RenderDevice and model/view/perspective matrix calculation 2019-08-22 18:22:22 +01:00
rubenwardy 188b49e962 Add variable arg overload of addComponent() 2019-08-08 17:23:19 +01:00
rubenwardy 62dc516cf4 Add Texture class 2019-08-08 17:23:19 +01:00
rubenwardy 2439edb8fd Merge ShaderProgram and Shader into a single Shader class 2019-08-08 17:23:19 +01:00
16 changed files with 223 additions and 115 deletions

View File

@ -36,13 +36,15 @@ set(SOURCE_LIST
src/main.cpp
src/engine/Window.cpp
src/engine/Shader.cpp
src/engine/ShaderProgram.cpp
src/engine/ShaderProgram.hpp
src/engine/Shader.hpp
src/graph/Node.cpp
src/graph/Component.cpp
src/game/MeshDrawComponent.cpp
src/tests/tests.cpp
src/libs/stb_image.c src/engine/Image.cpp src/engine/Image.hpp)
src/libs/stb_image.c
src/engine/Image.cpp
src/engine/Texture.cpp
src/engine/RenderDevice.cpp)
file(MAKE_DIRECTORY "bin")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")

View File

@ -2,13 +2,14 @@
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
uniform mat4 model;
uniform mat4 viewprojection;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
void main() {
gl_Position = viewprojection * model * vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}

View File

@ -0,0 +1,21 @@
#include "RenderDevice.hpp"
#include "Window.hpp"
#include <glm/gtc/matrix_transform.hpp>
RenderDevice::RenderDevice():
window(), viewProjection() {
updateViewProjectionMatrix();
}
void RenderDevice::updateViewProjectionMatrix() {
// model ((view perspective))
// model --------> world -------> camera --------------> screen
//
glm::mat4 view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
auto size = window.getSize();
float ratio = (float)size.x / (float)size.y;
viewProjection = glm::perspective(glm::radians(45.0f), ratio, 0.1f, 100.0f) * view;
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <memory>
#include "Window.hpp"
class RenderDevice {
Window window;
glm::mat4 viewProjection;
public:
RenderDevice();
RenderDevice(const RenderDevice &other) = delete;
inline Window &getWindow() { return window; }
inline const glm::mat4 &getViewProjectionMatrix() const { return viewProjection; }
private:
void updateViewProjectionMatrix();
};

View File

@ -1,9 +1,17 @@
#include <fstream>
#include <assert.h>
#include <iostream>
#include <fstream>
#include "Shader.hpp"
#include "gl.hpp"
Shader::Shader(ShaderType type, const char *source) {
#include <glm/gtc/type_ptr.hpp>
bool loadShader(int &handle, int type, const std::string &path) {
std::ifstream t(path);
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
const char *source = str.c_str();
handle = glCreateShader(type);
glShaderSource(handle, 1, &source, NULL);
glCompileShader(handle);
@ -14,18 +22,38 @@ Shader::Shader(ShaderType type, const char *source) {
if (!success) {
glGetShaderInfoLog(handle, 512, NULL, infoLog);
std::cout << "Failed to compile shader:\n" << infoLog << "\nSource:\n" << source << std::endl;
return false;
}
return true;
}
Shader::Shader(const std::string &vpath, const std::string &fpath) {
int vert, frag;
loadShader(vert, GL_VERTEX_SHADER, vpath);
loadShader(frag, GL_FRAGMENT_SHADER, fpath);
handle = glCreateProgram();
glAttachShader(handle, vert);
glAttachShader(handle, frag);
glLinkProgram(handle);
int success;
glGetProgramiv(handle, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(handle, 512, NULL, infoLog);
std::cout << "Failed to compile shader program:\n" << infoLog << std::endl;
}
}
Shader Shader::Load(ShaderType type, const std::string &path) {
std::ifstream t(path);
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
return Shader(type, str.c_str());
void Shader::use() const {
glUseProgram(handle);
}
Shader::~Shader() {
glDeleteShader(handle);
void Shader::setUniform(const std::string& name, glm::mat4 mat4) const {
int modelLoc = glGetUniformLocation(handle, name.c_str());
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(mat4));
}

View File

@ -1,23 +1,13 @@
#pragma once
#include <string>
enum ShaderType {
FRAGMENT = 0x8B30,
VERTEX = 0x8B31
};
#include <glm/glm.hpp>
class Shader {
unsigned int handle;
public:
Shader(ShaderType type, const char *source);
Shader(const Shader &other) = delete;
~Shader();
Shader(const std::string &vpath, const std::string &fpath);
void use() const;
static Shader Load(ShaderType type, const std::string &path);
operator unsigned int() const {
return handle;
}
void setUniform(const std::string& name, glm::mat4 mat4) const;
};

View File

@ -1,30 +0,0 @@
#include <assert.h>
#include <iostream>
#include "ShaderProgram.hpp"
#include "gl.hpp"
ShaderProgram::ShaderProgram() {
handle = glCreateProgram();
}
void ShaderProgram::attach(const Shader &shader) {
assert(!locked);
glAttachShader(handle, shader);
}
void ShaderProgram::link() {
glLinkProgram(handle);
locked = true;
int success;
glGetProgramiv(handle, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(handle, 512, NULL, infoLog);
std::cout << "Failed to compile shader program:\n" << infoLog << std::endl;
}
}
void ShaderProgram::use() const {
glUseProgram(handle);
}

View File

@ -1,14 +0,0 @@
#pragma once
#include "Shader.hpp"
class ShaderProgram {
unsigned int handle;
bool locked = false;
public:
ShaderProgram();
void attach(const Shader &shader);
void link();
void use() const;
};

23
src/engine/Texture.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "Texture.hpp"
#include "gl.hpp"
void Texture::load(const Image &image) {
glGenTextures(1, &handle);
bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getSize().x, image.getSize().y, 0, GL_RGB, GL_UNSIGNED_BYTE, image.getData());
glGenerateMipmap(GL_TEXTURE_2D);
}
void Texture::bind() const {
glBindTexture(GL_TEXTURE_2D, handle);
}
void Texture::unload() {
glDeleteTextures(1, &handle);
handle = 0;
}

18
src/engine/Texture.hpp Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "Image.hpp"
class Texture {
unsigned int handle = 0;
public:
Texture() = default;
explicit Texture(const Image &image) { load(image); }
Texture(const Texture &texture) = delete;
~Texture() { unload(); }
void load(const Image &image);
void bind() const;
void unload();
};

View File

@ -44,9 +44,12 @@ void Window::swapBuffers() {
glfwSwapBuffers(window);
}
void Window::clear(const glm::vec4 &color) {
glClearColor(color.r, color.g, color.b, color.a);
glClear(GL_COLOR_BUFFER_BIT);
}
glm::ivec2 Window::getSize() const {
return { 800, 600 };
}

View File

@ -12,4 +12,6 @@ public:
bool run();
void swapBuffers();
void clear(const glm::vec4 &color);
glm::ivec2 getSize() const;
};

View File

@ -4,20 +4,58 @@
#include "../engine/Image.hpp"
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
const std::string MeshDrawComponent::className = "MeshDrawComponent";
MeshDrawComponent::MeshDrawComponent(Node::Ptr node, const ShaderProgram &shader):
Component(std::move(node)), shader(shader) {
MeshDrawComponent::MeshDrawComponent(Node::Ptr node, RenderDevice *device, const Shader &shader):
Component(std::move(node)), device(device), shader(shader) {
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glGenVertexArrays(1, &vao);
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
unsigned int indices[] = { // note that we start from 0!
0, 1, 3, // first triangle
@ -51,19 +89,8 @@ MeshDrawComponent::MeshDrawComponent(Node::Ptr node, const ShaderProgram &shader
//
// Textures
//
{
Image image("assets/container.jpg");
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getSize().x, image.getSize().y, 0, GL_RGB, GL_UNSIGNED_BYTE, image.getData());
glGenerateMipmap(GL_TEXTURE_2D);
}
Image image("assets/container.jpg");
texture.load(image);
glBindVertexArray(0);
@ -76,11 +103,17 @@ void MeshDrawComponent::update(float delta) {
}
void MeshDrawComponent::draw() const {
shader.use();
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
shader.use();
texture.bind();
shader.setUniform("model", model);
shader.setUniform("viewprojection", device->getViewProjectionMatrix());
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
}

View File

@ -1,14 +1,18 @@
#pragma once
#include "../graph/Component.hpp"
#include "../engine/ShaderProgram.hpp"
#include "../engine/Shader.hpp"
#include "../engine/Texture.hpp"
#include "../engine/RenderDevice.hpp"
class MeshDrawComponent : public Component {
unsigned int vbo, ebo, vao, texture;
const ShaderProgram &shader;
unsigned int vbo, ebo, vao;
Texture texture;
const Shader &shader;
RenderDevice *device;
public:
MeshDrawComponent(Node::Ptr node, const ShaderProgram &shader);
MeshDrawComponent(Node::Ptr node, RenderDevice *device, const Shader &shader);
void update(float delta) override;
void draw() const;

View File

@ -24,11 +24,20 @@ public:
updateGlobalPosition();
}
template<class T>
template<typename T>
void addComponent(T *comp) {
_components[T::className] = std::unique_ptr<Component>(comp);
}
template<typename T, typename... _Args>
inline T *addComponent(_Args&&... __args) {
auto ptr = std::make_unique<T>(std::forward<_Args>(__args)...);
T *rptr = ptr.get();
_components[T::className] = std::move(ptr);
return rptr;
}
template<class T>
void recurseComponents(const std::function<bool(T*)> &cb) {
auto &name = T::className;

View File

@ -1,7 +1,7 @@
#include <iostream>
#include "engine/Window.hpp"
#include "engine/Shader.hpp"
#include "engine/ShaderProgram.hpp"
#include "engine/Shader.hpp"
#include "graph/Node.hpp"
#include "game/MeshDrawComponent.hpp"
#include "tests/tests.hpp"
@ -13,22 +13,18 @@ int main() {
return 0;
}
Window window;
ShaderProgram shaderProgram;
shaderProgram.attach(Shader::Load(ShaderType::VERTEX, "assets/shaders/base.vert.glsl"));
shaderProgram.attach(Shader::Load(ShaderType::FRAGMENT, "assets/shaders/base.frag.glsl"));
shaderProgram.link();
RenderDevice device;
Shader shaderProgram("assets/shaders/base.vert.glsl", "assets/shaders/base.frag.glsl");
auto root = std::make_shared<Node>();
{
auto square = std::make_shared<Node>();
square->addComponent<MeshDrawComponent>(new MeshDrawComponent(square, shaderProgram));
square->addComponent<MeshDrawComponent>(square, &device, shaderProgram);
root->addChild(square);
}
while (window.run()) {
window.clear({ 0.2f, 0.3f, 0.3f, 1.0f });
while (device.getWindow().run()) {
device.getWindow().clear({ 0.2f, 0.3f, 0.3f, 1.0f });
root->recurseComponents<MeshDrawComponent>([](auto x) {
// TODO: visibility
@ -36,6 +32,6 @@ int main() {
return true;
});
window.swapBuffers();
device.getWindow().swapBuffers();
}
}