From 8d9b24b1b84107c90a77d94c86a810cc068fe073 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 19 Feb 2020 22:14:12 +0100 Subject: Fix rendering of texture with multiple frames --- src/RenderBackend/OpenGL/DeviceFrame.cpp | 39 --------------- src/RenderBackend/OpenGL/DeviceMemory.cpp | 80 ++++++++++++------------------ src/RenderBackend/OpenGL/ShaderFrame.cpp | 54 ++++++++++++++++++++ src/RenderBackend/OpenGL/ShaderProgram.cpp | 57 +-------------------- src/RenderBackend/OpenGL/Texture2D.cpp | 24 ++++++++- 5 files changed, 111 insertions(+), 143 deletions(-) delete mode 100644 src/RenderBackend/OpenGL/DeviceFrame.cpp create mode 100644 src/RenderBackend/OpenGL/ShaderFrame.cpp (limited to 'src/RenderBackend') diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp deleted file mode 100644 index 2132f83..0000000 --- a/src/RenderBackend/OpenGL/DeviceFrame.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp" -#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp" -#include "../../../include/RenderBackend/OpenGL/opengl.hpp" -#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp" - -namespace amalgine -{ - DeviceFrame::DeviceFrame() - { - glGenVertexArrays(1, &vertexArrayObjectId); - } - - DeviceFrame::~DeviceFrame() - { - for(DeviceMemory *deviceMemory : buffers) - { - delete deviceMemory; - } - glDeleteVertexArrays(1, &vertexArrayObjectId); - } - - DeviceMemory* DeviceFrame::alloc() - { - glBindVertexArray(vertexArrayObjectId); - DeviceMemory *deviceMemory = new DeviceMemory(); - buffers.push_back(deviceMemory); - return deviceMemory; - } - - void DeviceFrame::draw(ShaderProgram *shader) { - shader->use(); - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - for(DeviceMemory *deviceMemory : buffers) - { - deviceMemory->draw(); - } - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } -} diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp index a82cdaa..7447657 100644 --- a/src/RenderBackend/OpenGL/DeviceMemory.cpp +++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp @@ -2,12 +2,9 @@ #include "../../../include/RenderBackend/OpenGL/opengl.hpp" #include -namespace amalgine -{ - u32 getOpenglStorageType(DeviceMemory::StorageType storageType) - { - switch(storageType) - { +namespace amalgine { + u32 getOpenglStorageType(DeviceMemory::StorageType storageType) { + switch(storageType) { case DeviceMemory::StorageType::STATIC: return GL_STATIC_DRAW; case DeviceMemory::StorageType::DYNAMIC: return GL_DYNAMIC_DRAW; case DeviceMemory::StorageType::STREAM: return GL_STREAM_DRAW; @@ -15,58 +12,47 @@ namespace amalgine } } - DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0), type(DeviceMemoryType::NONE) - { - glGenBuffers(1, &vertexBufferObjectId); + DeviceMemory::DeviceMemory(u32 vertex_array_object_id, i32 attrib_location) : + vertex_array_object_id(vertex_array_object_id), vertex_buffer_object_id(-1), attrib_location(attrib_location), + num_vertices(0), memory_type(DeviceMemoryType::NONE) { + glGenBuffers(1, &vertex_buffer_object_id); } - DeviceMemory::~DeviceMemory() - { - glDeleteBuffers(1, &vertexBufferObjectId); + DeviceMemory::~DeviceMemory() { + glDeleteBuffers(1, &vertex_buffer_object_id); } - void DeviceMemory::use() const - { - // TODO: Bind vao here? - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); + void DeviceMemory::use() { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id); } - /* - void DeviceMemory::copy(const DataView &data, StorageType storageType, PrimitiveType primitiveType) - { - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); - glBufferData(GL_ARRAY_BUFFER, data.getByteSize(), data.data, getOpenglStorageType(storageType)); - this->primitiveType = getOpenglPrimitiveType(primitiveType); - numVertices = getPrimitiveTypePointsPerVertices(primitiveType); - } - */ - void DeviceMemory::copy(const DataView &texture_coords, StorageType storageType) { - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); + + void DeviceMemory::set(const DataView &texture_coords, StorageType storageType) { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id); glBufferData(GL_ARRAY_BUFFER, texture_coords.getByteSize(), texture_coords.data, getOpenglStorageType(storageType)); - primitiveType = GL_TRIANGLES; - numVertices = texture_coords.size * 2; - type = DeviceMemoryType::VEC2; + num_vertices = texture_coords.size * 2; + memory_type = DeviceMemoryType::VEC2; + + glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object + glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0); } - void DeviceMemory::copy(const DataView &triangles, StorageType storageType) - { - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); + void DeviceMemory::set(const DataView &triangles, StorageType storageType) { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id); glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType)); - primitiveType = GL_TRIANGLES; - numVertices = triangles.size * 2; - type = DeviceMemoryType::VEC2; + num_vertices = triangles.size * 2; + memory_type = DeviceMemoryType::VEC2; + + glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object + glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0); } - void DeviceMemory::copy(const DataView &triangles, StorageType storageType) - { - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); + void DeviceMemory::set(const DataView &triangles, StorageType storageType) { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id); glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType)); - primitiveType = GL_TRIANGLES; - numVertices = triangles.size * 3; - type = DeviceMemoryType::VEC3; - } - - void DeviceMemory::draw() - { - glDrawArrays(primitiveType, 0, numVertices); + num_vertices = triangles.size * 3; + memory_type = DeviceMemoryType::VEC3; + + glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object + glVertexAttribPointer(attrib_location, 3, GL_FLOAT, GL_FALSE, 0, 0); } } diff --git a/src/RenderBackend/OpenGL/ShaderFrame.cpp b/src/RenderBackend/OpenGL/ShaderFrame.cpp new file mode 100644 index 0000000..3f7ff01 --- /dev/null +++ b/src/RenderBackend/OpenGL/ShaderFrame.cpp @@ -0,0 +1,54 @@ +#include "../../../include/RenderBackend/OpenGL/ShaderFrame.hpp" +#include "../../../include/RenderBackend/OpenGL/opengl.hpp" + +namespace amalgine { + ShaderFrame::ShaderFrame(u32 shader_program_id) : shader_program_id(shader_program_id), vertex_array_object_id(-1) { + glGenVertexArrays(1, &vertex_array_object_id); + } + + ShaderFrame::~ShaderFrame() { + glDeleteVertexArrays(1, &vertex_array_object_id); + } + + DeviceMemory* ShaderFrame::get_input_by_name(const char *name) { + auto it = shader_inputs.find(name); + if(it != shader_inputs.end()) + return it->second.get(); + + GLint attrib_location = glGetAttribLocation(shader_program_id, name); + if(attrib_location == -1) { + fprintf(stderr, "No such attribute in shader: %s\n", name); + return nullptr; + } + + glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object + DeviceMemory *device_memory_ptr = new DeviceMemory(vertex_array_object_id, attrib_location); + std::unique_ptr device_memory(device_memory_ptr); + device_memory->use(); + glEnableVertexAttribArray(attrib_location); + + shader_inputs[name] = std::move(device_memory); + return device_memory_ptr; + } + + Result ShaderFrame::get_uniform_by_name(const char *name) { + GLint uniform_id = glGetUniformLocation(shader_program_id, name); + if(uniform_id == -1) + return Result::Err(std::string("Uniform with name ") + name + " was not found"); + + Uniform uniform(uniform_id, shader_program_id); + return Result::Ok(std::move(uniform)); + } + + void ShaderFrame::draw() { + glUseProgram(shader_program_id); + glBindVertexArray(vertex_array_object_id); // Set the active shader to use the data encapsulated by the vertex array object + // TODO: Cache this num_vertices count (and reset it when device memory has changed) + int num_vertices = 0; + for(const auto &it : shader_inputs) { + num_vertices = std::max(num_vertices, it.second->get_num_vertices()); + } + // TODO: Allow specifying mode different than GL_TRIANGLES + glDrawArrays(GL_TRIANGLES, 0, num_vertices); + } +} diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp index 7990a82..ba0e6dd 100644 --- a/src/RenderBackend/OpenGL/ShaderProgram.cpp +++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp @@ -28,26 +28,6 @@ namespace amalgine { delete []attachedShaders; } - #if 0 - bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader) - { - if(!pixelShader) return false; - - // TODO: Do not allow adding shader if the program has already been built - glAttachShader(shaderProgramId, pixelShader->getShaderId()); - - const auto &pixelAttributes = pixelShader->getPixelAttributes(); - for(const auto &pixelAttribute : pixelAttributes) - { - const string &attributeName = pixelAttribute.first; - i32 attributeLocation = pixelAttribute.second; - glBindFragDataLocation(shaderProgramId, attributeLocation, attributeName.c_str()); - } - - return true; - } - #endif - // static Result> ShaderProgram::build(const std::vector &shaders) { u32 shader_program_id = glCreateProgram(); @@ -64,40 +44,7 @@ namespace amalgine { return Result>::Ok(std::move(shader_program)); } - Result ShaderProgram::get_uniform_by_name(const char *name) { - GLint uniform_id = glGetUniformLocation(program_id, name); - if(uniform_id == -1) - return Result::Err(std::string("Uniform with name ") + name + " was not found"); - - Uniform uniform(uniform_id, program_id); - return Result::Ok(std::move(uniform)); - } - - int ShaderProgram::set_input_data(const char *name, const DeviceMemory &data) { - GLint attrib_location = glGetAttribLocation(program_id, name); - if(attrib_location == -1) { - fprintf(stderr, "No such attribute in shader: %s\n", name); - return -1; - } - - data.use(); - glEnableVertexAttribArray(attrib_location); - switch(data.get_type()) { - case DeviceMemoryType::NONE: - return -1; - case DeviceMemoryType::VEC2: { - glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0); - break; - } - case DeviceMemoryType::VEC3: { - glVertexAttribPointer(attrib_location, 3, GL_FLOAT, GL_FALSE, 0, 0); - break; - } - } - return 0; - } - - void ShaderProgram::use() { - glUseProgram(program_id); + ShaderFrame ShaderProgram::create_frame() { + return { program_id }; } } diff --git a/src/RenderBackend/OpenGL/Texture2D.cpp b/src/RenderBackend/OpenGL/Texture2D.cpp index dcb9cef..f4326a8 100644 --- a/src/RenderBackend/OpenGL/Texture2D.cpp +++ b/src/RenderBackend/OpenGL/Texture2D.cpp @@ -39,6 +39,10 @@ namespace amalgine { static TextureIdAllocator *texture_id_allocator = nullptr; + Texture2D::Texture2D() : texture_id(-1), texture_ref(-1) { + + } + Texture2D::Texture2D(Image *image) { assert(image); @@ -46,6 +50,8 @@ namespace amalgine { texture_id_allocator = new TextureIdAllocator(); texture_id = texture_id_allocator->get_free_texture_id(); + printf("texture id: %d\n", texture_id); + texture_ref = -1; glGenTextures(1, &texture_ref); glActiveTexture(GL_TEXTURE0 + texture_id); glBindTexture(GL_TEXTURE_2D, texture_ref); @@ -60,7 +66,21 @@ namespace amalgine { Texture2D::~Texture2D() { - texture_id_allocator->free_texture_id(texture_id); - glDeleteTextures(1, &texture_ref); + if(texture_ref != -1) { + texture_id_allocator->free_texture_id(texture_id); + glDeleteTextures(1, &texture_ref); + } + } + + Texture2D::Texture2D(Texture2D &&other) { + this->operator=(std::move(other)); + } + + Texture2D& Texture2D::operator=(Texture2D &&other) { + texture_id = other.texture_id; + texture_ref = other.texture_ref; + other.texture_id = -1; + other.texture_ref = -1; + return *this; } } -- cgit v1.2.3