From ffe9dac56488ebfc9f5c37c4e400f4f5469a8a46 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 26 Dec 2017 17:29:28 +0100 Subject: Add device memory, device frame. Rendering works --- src/RenderBackend/OpenGL/CompiledShader.cpp | 7 ++-- src/RenderBackend/OpenGL/DeviceFrame.cpp | 36 ++++++++++++++++++++ src/RenderBackend/OpenGL/DeviceMemory.cpp | 51 +++++++++++++++++++++++------ src/RenderBackend/OpenGL/PixelShader.cpp | 2 +- src/RenderBackend/OpenGL/ShaderProgram.cpp | 17 ++++++++-- src/RenderBackend/OpenGL/ShaderVec.cpp | 31 ++++++++++++++++++ src/RenderBackend/OpenGL/VertexShader.cpp | 16 ++++++--- src/main.cpp | 29 ++++++++++------ 8 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 src/RenderBackend/OpenGL/DeviceFrame.cpp (limited to 'src') diff --git a/src/RenderBackend/OpenGL/CompiledShader.cpp b/src/RenderBackend/OpenGL/CompiledShader.cpp index 6707b7a..f4a1fec 100644 --- a/src/RenderBackend/OpenGL/CompiledShader.cpp +++ b/src/RenderBackend/OpenGL/CompiledShader.cpp @@ -1,6 +1,8 @@ #include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" +using namespace std; + namespace amalgine { CompiledVertexShader::CompiledVertexShader(u32 _shaderId) : @@ -19,8 +21,9 @@ namespace amalgine return shaderId; } - CompiledPixelShader::CompiledPixelShader(u32 _shaderId) : - shaderId(_shaderId) + CompiledPixelShader::CompiledPixelShader(u32 _shaderId, unordered_map &&_pixelAttributes) : + shaderId(_shaderId), + pixelAttributes(_pixelAttributes) { } diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp new file mode 100644 index 0000000..9d60597 --- /dev/null +++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp @@ -0,0 +1,36 @@ +#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp" +#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp" +#include "../../../include/RenderBackend/OpenGL/opengl.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() + { + for(DeviceMemory *deviceMemory : buffers) + { + deviceMemory->draw(); + } + } +} diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp index 9e33ac9..faf2943 100644 --- a/src/RenderBackend/OpenGL/DeviceMemory.cpp +++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp @@ -3,7 +3,33 @@ namespace amalgine { - DeviceMemory::DeviceMemory() + 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; + } + } + + u32 getOpenglPrimitiveType(DeviceMemory::PrimitiveType primitiveType) + { + switch(primitiveType) + { + case DeviceMemory::PrimitiveType::TRIANGLE: return GL_TRIANGLES; + } + } + + u32 getPrimitiveTypePointsPerVertices(DeviceMemory::PrimitiveType primitiveType) + { + switch(primitiveType) + { + case DeviceMemory::PrimitiveType::TRIANGLE: return 3; + } + } + + DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0) { glGenBuffers(1, &vertexBufferObjectId); } @@ -13,24 +39,29 @@ namespace amalgine glDeleteBuffers(1, &vertexBufferObjectId); } - void DeviceMemory::copyAsStatic(const DataView &data) + void DeviceMemory::operator delete(void *data) { - copy(data, GL_STATIC_DRAW); + free(data); } - void DeviceMemory::copyAsDynamic(const DataView &data) + void DeviceMemory::use() const { - copy(data, GL_DYNAMIC_DRAW); + // TODO: Bind vao here? + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); } - void DeviceMemory::copyAsStream(const DataView &data) + void DeviceMemory::copy(const DataView &data, StorageType storageType, PrimitiveType primitiveType) { - copy(data, GL_STREAM_DRAW); + 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 &data, i32 storageType) + void DeviceMemory::draw() { - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId); - glBufferData(GL_ARRAY_BUFFER, data.getByteSize(), data.data, storageType); + if(primitiveType == 0) + throw DeviceMemoryEmpty("Unable to draw buffer as no data has been copied to device memory"); + glDrawArrays(primitiveType, 0, 3); } } diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp index 2af68e5..8aa4d9a 100644 --- a/src/RenderBackend/OpenGL/PixelShader.cpp +++ b/src/RenderBackend/OpenGL/PixelShader.cpp @@ -131,7 +131,7 @@ namespace amalgine { if(!compileLog.empty()) printf("Pixel shader compile log:\n%s", compileLog.c_str()); - return Result::Ok(new CompiledPixelShader(fragmentShaderId)); + return Result::Ok(new CompiledPixelShader(fragmentShaderId, move(pixelAttributes))); } else return Result::Err(compileLog); diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp index f76903e..40f5b6c 100644 --- a/src/RenderBackend/OpenGL/ShaderProgram.cpp +++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp @@ -36,17 +36,30 @@ namespace amalgine // TODO: Before adding shader to program, check if it has already been added - bool ShaderProgram::addVertexShader(CompiledVertexShader *vertexShader) + bool ShaderProgram::setVertexShader(CompiledVertexShader *vertexShader) { + if(!vertexShader) return false; + // TODO: Do not allow adding shader if the program has already been built glAttachShader(shaderProgramId, vertexShader->getShaderId()); return true; } - bool ShaderProgram::addPixelShader(CompiledPixelShader *pixelShader) + 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; } diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp index 6411650..3bbe0be 100644 --- a/src/RenderBackend/OpenGL/ShaderVec.cpp +++ b/src/RenderBackend/OpenGL/ShaderVec.cpp @@ -2,16 +2,47 @@ #include "../../../include/RenderBackend/OpenGL/VertexShader.hpp" #include "../../../include/RenderBackend/OpenGL/PixelShader.hpp" #include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp" +#include "../../../include/RenderBackend/OpenGL/opengl.hpp" +#include +#include using namespace std; namespace amalgine { + AttributeType getAttributeTypeByName(const char *attributeName) + { + if(strncmp(attributeName, "vec2", 4) == 0) + { + return AttributeType::VEC2; + } + + return AttributeType::NONE; + } + const string& ShaderInputVec2::getName() const { return vertexShader->getInputAttributeName(attributeIndex); } + void ShaderInputVec2::setData(const DeviceMemory &data) + { + data.use(); + AttributeType attributeType = vertexShader->getInputAttributeType(attributeIndex); + switch(attributeType) + { + case AttributeType::VEC2: + { + glVertexAttribPointer(attributeIndex, 2, GL_FLOAT, GL_FALSE, 0, 0); + break; + } + default: + assert(false); + break; + } + glEnableVertexAttribArray(attributeIndex); + } + const string& ShaderOutputVec4::getName() const { return pixelShader->getOutputAttributeName(attributeIndex); diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp index 1505ff4..ac9a159 100644 --- a/src/RenderBackend/OpenGL/VertexShader.cpp +++ b/src/RenderBackend/OpenGL/VertexShader.cpp @@ -1,5 +1,4 @@ #include "../../../include/RenderBackend/OpenGL/VertexShader.hpp" -#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" #include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" @@ -37,10 +36,16 @@ namespace amalgine writeHeader("#version 330 core\n\n"); } - const string& VertexShader::getInputAttributeName(i32 attributeIndex) + const string& VertexShader::getInputAttributeName(i32 attributeIndex) const { assert(attributeIndex < vertexAttributeNames.size()); - return vertexAttributeNames[attributeIndex]; + return vertexAttributeNames[attributeIndex].name; + } + + AttributeType VertexShader::getInputAttributeType(i32 attributeIndex) const + { + assert(attributeIndex < vertexAttributeNames.size()); + return getAttributeTypeByName(vertexAttributeNames[attributeIndex].typeName); } ShaderInputVec2 VertexShader::defineInputVec2(const std::string &name) @@ -75,7 +80,10 @@ namespace amalgine i32 attributeIndex = locationCounter; vertexAttributes[variableName] = locationCounter; - vertexAttributeNames.push_back(variableName); + ShaderAttribute shaderAttribute; + shaderAttribute.name = variableName; + shaderAttribute.typeName = typeName; + vertexAttributeNames.push_back(shaderAttribute); writeHeader("layout(location = "); writeHeader(to_string(locationCounter)); diff --git a/src/main.cpp b/src/main.cpp index b1a0d62..0e72df0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,16 @@ #include -#include -#include -#include +#include "../include/RenderBackend/OpenGL/opengl.hpp" #include "../include/RenderBackend/OpenGL/VertexShader.hpp" #include "../include/RenderBackend/OpenGL/PixelShader.hpp" #include "../include/RenderBackend/OpenGL/ShaderProgram.hpp" #include "../include/RenderBackend/OpenGL/DeviceMemory.hpp" +#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp" + +// TODO: Disallow shader variables that begin with "gl_" as reserved variables +// start with that. What about hlsl? + +// TODO: Creating buffers etc should be somehow created/drawn using the window object, since they are associated with the window +// opengl context using namespace amalgine; using namespace std; @@ -14,7 +19,7 @@ void initGlfw(); void initGlew(); GLFWwindow *createWindow(); -CompiledVertexShader* createVertexShader(); +CompiledVertexShader* createVertexShader(const DeviceMemory &inputData); CompiledPixelShader* createPixelShader(); int main() @@ -22,22 +27,24 @@ int main() initGlfw(); GLFWwindow *window = createWindow(); + DeviceFrame frame; + f32 verticesRaw[] = { 0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f }; + DeviceMemory *triangle = frame.alloc(); DataView vertices(verticesRaw, 6); - DeviceMemory triangle; - triangle.copyAsStatic(vertices); + triangle->copy(vertices, DeviceMemory::StorageType::STATIC); - CompiledVertexShader *vertexShader = createVertexShader(); + CompiledVertexShader *vertexShader = createVertexShader(*triangle); CompiledPixelShader *pixelShader = createPixelShader(); ShaderProgram shaderProgram; - shaderProgram.addVertexShader(vertexShader); - shaderProgram.addPixelShader(pixelShader); + shaderProgram.setVertexShader(vertexShader); + shaderProgram.setPixelShader(pixelShader); Result shaderBuildResult = shaderProgram.build(); if(!shaderBuildResult) { @@ -52,6 +59,7 @@ int main() glfwSetWindowShouldClose(window, GL_TRUE); shaderProgram.use(); + frame.draw(); glfwSwapBuffers(window); } @@ -102,10 +110,11 @@ GLFWwindow* createWindow() return window; } -CompiledVertexShader* createVertexShader() +CompiledVertexShader* createVertexShader(const DeviceMemory &inputData) { VertexShader vertexShader; ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position"); + inputPosition.setData(inputData); vertexShader.defineMain([&inputPosition]() { -- cgit v1.2.3