From 23a37b2cdd8ffde8bb85a4159888bf3a7ec35966 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 4 Nov 2019 00:50:45 +0100 Subject: Use external shaders instead of generating shader code from c++ code... --- src/RenderBackend/OpenGL/CommonShader.cpp | 20 --- src/RenderBackend/OpenGL/CompiledShader.cpp | 40 ------ src/RenderBackend/OpenGL/DeviceFrame.cpp | 9 +- src/RenderBackend/OpenGL/DeviceMemory.cpp | 10 +- src/RenderBackend/OpenGL/PixelShader.cpp | 47 ------- src/RenderBackend/OpenGL/Shader.cpp | 198 ++++++---------------------- src/RenderBackend/OpenGL/ShaderProgram.cpp | 116 ++++++++-------- src/RenderBackend/OpenGL/ShaderVec.cpp | 69 ---------- src/RenderBackend/OpenGL/VertexShader.cpp | 45 ------- src/main.cpp | 116 ++++++---------- 10 files changed, 145 insertions(+), 525 deletions(-) delete mode 100644 src/RenderBackend/OpenGL/CommonShader.cpp delete mode 100644 src/RenderBackend/OpenGL/CompiledShader.cpp delete mode 100644 src/RenderBackend/OpenGL/PixelShader.cpp delete mode 100644 src/RenderBackend/OpenGL/ShaderVec.cpp delete mode 100644 src/RenderBackend/OpenGL/VertexShader.cpp (limited to 'src') diff --git a/src/RenderBackend/OpenGL/CommonShader.cpp b/src/RenderBackend/OpenGL/CommonShader.cpp deleted file mode 100644 index ea88f62..0000000 --- a/src/RenderBackend/OpenGL/CommonShader.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp" -#include "../../../include/RenderBackend/OpenGL/opengl.hpp" - -using namespace std; - -namespace amalgine -{ - string getShaderCompileLog(u32 shaderId) - { - string result; - GLint shaderLogLength; - glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength); - if(shaderLogLength > 0) - { - result.resize(shaderLogLength); - glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]); - } - return result; - } -} diff --git a/src/RenderBackend/OpenGL/CompiledShader.cpp b/src/RenderBackend/OpenGL/CompiledShader.cpp deleted file mode 100644 index f4a1fec..0000000 --- a/src/RenderBackend/OpenGL/CompiledShader.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" -#include "../../../include/RenderBackend/OpenGL/opengl.hpp" - -using namespace std; - -namespace amalgine -{ - CompiledVertexShader::CompiledVertexShader(u32 _shaderId) : - shaderId(_shaderId) - { - - } - - CompiledVertexShader::~CompiledVertexShader() - { - glDeleteShader(shaderId); - } - - u32 CompiledVertexShader::getShaderId() const - { - return shaderId; - } - - CompiledPixelShader::CompiledPixelShader(u32 _shaderId, unordered_map &&_pixelAttributes) : - shaderId(_shaderId), - pixelAttributes(_pixelAttributes) - { - - } - - CompiledPixelShader::~CompiledPixelShader() - { - glDeleteShader(shaderId); - } - - u32 CompiledPixelShader::getShaderId() const - { - return shaderId; - } -} diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp index e79dfa1..2132f83 100644 --- a/src/RenderBackend/OpenGL/DeviceFrame.cpp +++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp @@ -1,6 +1,7 @@ #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 { @@ -26,13 +27,13 @@ namespace amalgine return deviceMemory; } - void DeviceFrame::draw() - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + 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); + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp index 0dd3e89..2d40569 100644 --- a/src/RenderBackend/OpenGL/DeviceMemory.cpp +++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp @@ -33,7 +33,7 @@ namespace amalgine } } - DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0) + DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0), type(DeviceMemoryType::NONE) { glGenBuffers(1, &vertexBufferObjectId); } @@ -43,11 +43,6 @@ namespace amalgine glDeleteBuffers(1, &vertexBufferObjectId); } - void DeviceMemory::operator delete(void *data) - { - free(data); - } - void DeviceMemory::use() const { // TODO: Bind vao here? @@ -68,12 +63,11 @@ namespace amalgine glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType)); primitiveType = GL_TRIANGLES; numVertices = triangles.size * 3; + type = DeviceMemoryType::VEC2; } void DeviceMemory::draw() { - if(primitiveType == 0) - throw DeviceMemoryEmpty("Unable to draw buffer as no data has been copied to device memory"); glDrawArrays(primitiveType, 0, numVertices); } } diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp deleted file mode 100644 index e6006f2..0000000 --- a/src/RenderBackend/OpenGL/PixelShader.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp" -#include "../../../include/RenderBackend/OpenGL/opengl.hpp" -#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" - -namespace amalgine -{ - PixelShader::PixelShader() - { - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxAttribs); - } - - void PixelShader::defineMain(PixelShaderMainFunc mainFunc) - { - if(mainFuncDefined) - throw ShaderFunctionAlreadyDefined("main"); - - writeBody("void main() {\n"); - mainFunc(); - mainFuncDefined = true; - writeBody("}\n\n"); - } - - Result PixelShader::compile() - { - if(!mainFuncDefined) - return Result::Err("main function not defined (defineMain not called)"); - - GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); - std::string verterShaderSource = build(); - const char *verterShaderSourcePtr = verterShaderSource.c_str(); - printf("Vertex shader:\n%s\n", verterShaderSourcePtr); - glShaderSource(fragmentShaderId, 1, &verterShaderSourcePtr, NULL); - glCompileShader(fragmentShaderId); - - GLint status; - glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status); - std::string compileLog = getShaderCompileLog((u32)fragmentShaderId); - if(status == GL_TRUE) - { - if(!compileLog.empty()) - printf("Pixel shader compile log:\n%s", compileLog.c_str()); - return Result::Ok(new CompiledPixelShader(fragmentShaderId, move(inputAttributes))); - } - else - return Result::Err(compileLog); - } -} diff --git a/src/RenderBackend/OpenGL/Shader.cpp b/src/RenderBackend/OpenGL/Shader.cpp index fad1702..3b6563f 100644 --- a/src/RenderBackend/OpenGL/Shader.cpp +++ b/src/RenderBackend/OpenGL/Shader.cpp @@ -1,169 +1,55 @@ #include "../../../include/RenderBackend/OpenGL/Shader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" -#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" -#include - -using namespace std; namespace amalgine { - ShaderTooManyAttributes::ShaderTooManyAttributes(i32 maxAttributes) : - runtime_error(string("Attempting to define more than ") + to_string(maxAttributes) + " attributes") - { - - } - - ShaderAttributeAlreadyDefined::ShaderAttributeAlreadyDefined(const std::string &attributeName) : - runtime_error(string("An attribute with the name ") + attributeName + " has already been defined") - { - - } - - ShaderInvalidAttributeName::ShaderInvalidAttributeName(const std::string &attributeName) : - runtime_error(string("Attribute name ") + attributeName + " is invalid") - { - - } - - ShaderFunctionAlreadyDefined::ShaderFunctionAlreadyDefined(const std::string &funcName) : - runtime_error(string("Shader function already defined: ") + funcName) - { - - } - - Shader::Shader() : inputLocationCounter(0), outputLocationCounter(0), mainFuncDefined(false) - { - writeHeader("#version 330 core\n\n"); - } - - const string& Shader::getOutputAttributeName(i32 attributeIndex) - { - assert(attributeIndex < (i32)outputAttributeNames.size()); - return outputAttributeNames[attributeIndex].name; + static GLuint to_opengl_shader_type(Shader::Type type) { + switch(type) { + case Shader::Type::VERTEX: + return GL_VERTEX_SHADER; + case Shader::Type::PIXEL: + return GL_FRAGMENT_SHADER; + } + assert(false); } - const string& Shader::getInputAttributeName(i32 attributeIndex) const - { - assert(attributeIndex < (i32)inputAttributeNames.size()); - return inputAttributeNames[attributeIndex].name; - } - - AttributeType Shader::getInputAttributeType(i32 attributeIndex) const - { - assert(attributeIndex < (i32)inputAttributeNames.size()); - return getAttributeTypeByName(inputAttributeNames[attributeIndex].typeName); - } - - ShaderOutputVec4 Shader::defineOutputVec4(const std::string &name) - { - i32 attributeIndex = defineOutputVariable(name, "vec4"); - return ShaderOutputVec4(this, attributeIndex); - } - - // TODO: Generate warning if global variable is defined but not assigned to? - ShaderGlobalVec3 Shader::defineGlobalVec3(const std::string &name) - { - if(!isShaderVariableNameValid(name.c_str())) - throw ShaderInvalidAttributeName(name); - - if(uniforms.find(name) != uniforms.end()) - throw ShaderAttributeAlreadyDefined(name); - - writeHeader("uniform vec3 "); - writeHeader(name); - writeHeader(";\n"); - - ShaderGlobalVec3 globalVec(name); - uniforms[name] = globalVec.getVecObject(); - return ShaderGlobalVec3(globalVec); - } - - i32 Shader::defineOutputVariable(const string &variableName, const char *typeName) - { - if(!isShaderVariableNameValid(variableName.c_str())) - throw ShaderInvalidAttributeName(variableName); - - if(outputLocationCounter + 1 > maxAttribs) - throw ShaderTooManyAttributes(maxAttribs); - - if(outputAttributes.find(variableName) != outputAttributes.end()) - throw ShaderAttributeAlreadyDefined(variableName); - - i32 attributeIndex = outputLocationCounter; - outputAttributes[variableName] = outputLocationCounter; - writeHeader("out "); - writeHeader(typeName); - writeHeader(" "); - writeHeader(variableName); - writeHeader(";\n"); - - ShaderAttribute shaderAttribute; - shaderAttribute.name = variableName; - shaderAttribute.typeName = typeName; - outputAttributeNames.push_back(shaderAttribute); - ++outputLocationCounter; - return attributeIndex; - } - - ShaderInputVec2 Shader::defineInputVec2(const std::string &name) - { - i32 attributeIndex = defineInputVariable(name, "vec2"); - return ShaderInputVec2(this, attributeIndex); - } - - i32 Shader::defineInputVariable(const string &variableName, const char *typeName) - { - if(!isShaderVariableNameValid(variableName.c_str())) - throw ShaderInvalidAttributeName(variableName); - - if(inputLocationCounter + 1 > maxAttribs) - throw ShaderTooManyAttributes(maxAttribs); - - if(inputAttributes.find(variableName) != inputAttributes.end()) - throw ShaderAttributeAlreadyDefined(variableName); - - i32 attributeIndex = inputLocationCounter; - inputAttributes[variableName] = inputLocationCounter; - ShaderAttribute shaderAttribute; - shaderAttribute.name = variableName; - shaderAttribute.typeName = typeName; - inputAttributeNames.push_back(shaderAttribute); - - writeHeader("layout(location = "); - writeHeader(to_string(inputLocationCounter)); - ++inputLocationCounter; - writeHeader(") in "); - writeHeader(typeName); - writeHeader(" "); - writeHeader(variableName); - writeHeader(";\n"); - return attributeIndex; - } - - void Shader::assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable) - { - writeBody(lhsVariable.getName()); - writeBody(" = "); - writeBody(rhsVariable.getOutput()); - writeBody(";\n"); - } - - string Shader::build() const + static std::string get_shader_compile_log(GLuint shaderId) { std::string result; - result.reserve(header.size() + 2 + body.size()); - result += header; - result += "\n"; - result += body; + GLint shaderLogLength; + glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength); + if(shaderLogLength > 0) { + result.resize(shaderLogLength); + glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]); + } return result; } - - void Shader::writeHeader(const string &code) - { - header += code; + + Shader::Shader(u32 shader_id) : id(shader_id) { + } - - void Shader::writeBody(const string &code) - { - body += code; + + Shader::~Shader() { + glDeleteShader(id); + } + + // static + Result> Shader::compile(Type type, const char *str, int size) { + GLuint shader_id = glCreateShader(to_opengl_shader_type(type)); + GLint shader_lengths[1] = { size }; + glShaderSource(shader_id, 1, &str, shader_lengths); + glCompileShader(shader_id); + + GLint status; + glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status); + std::string compileLog = get_shader_compile_log(shader_id); + if(status == GL_TRUE) { + if(!compileLog.empty()) + fprintf(stderr, "Shader compile log:\n%s", compileLog.c_str()); + std::unique_ptr shader; + shader.reset(new Shader(shader_id)); + return Result>::Ok(std::move(shader)); + } + else + return Result>::Err(compileLog); } } diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp index aceda3b..e613668 100644 --- a/src/RenderBackend/OpenGL/ShaderProgram.cpp +++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp @@ -1,56 +1,34 @@ #include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp" + +#include "../../../include/RenderBackend/OpenGL/Shader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" -#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" using namespace std; -namespace amalgine -{ - ShaderProgramUsedBeforeBuilt::ShaderProgramUsedBeforeBuilt() : - runtime_error("Shader program was used before it was built") - { +namespace amalgine { + ShaderProgram::ShaderProgram(u32 shader_program_id) : program_id(shader_program_id) { } - ShaderProgramNonExistingGlobalVariable::ShaderProgramNonExistingGlobalVariable(const char *variableName) : - runtime_error(string("There is no shader global variable with the name '") + variableName + "'") - { - - } - - ShaderProgram::ShaderProgram() : built(false) - { - shaderProgramId = glCreateProgram(); - } - ShaderProgram::~ShaderProgram() { GLint numAttachedShaders; - glGetProgramiv(shaderProgramId, GL_ATTACHED_SHADERS, &numAttachedShaders); + glGetProgramiv(program_id, GL_ATTACHED_SHADERS, &numAttachedShaders); GLuint *attachedShaders = new GLuint[numAttachedShaders]; - glGetAttachedShaders(shaderProgramId, numAttachedShaders, nullptr, attachedShaders); + glGetAttachedShaders(program_id, numAttachedShaders, nullptr, attachedShaders); for(int i = 0; i < numAttachedShaders; ++i) { GLuint attachedShaderId = attachedShaders[i]; - glDetachShader(shaderProgramId, attachedShaderId); + glDetachShader(program_id, attachedShaderId); } - glDeleteProgram(shaderProgramId); - } - - // TODO: Before adding shader to program, check if it has already been added - - 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; + glDeleteProgram(program_id); + delete []attachedShaders; } + #if 0 bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader) { if(!pixelShader) return false; @@ -68,41 +46,55 @@ namespace amalgine return true; } + #endif - Result ShaderProgram::build() - { - if(built) - return Result::Err("Shader program already built"); + // static + Result> ShaderProgram::build(const std::vector &shaders) { + u32 shader_program_id = glCreateProgram(); + if(shader_program_id == 0) + return Result>::Err("Failed to create shader program"); - glLinkProgram(shaderProgramId); - built = true; - return Result::Ok(true); - } - - void ShaderProgram::use() - { - if(built) - { - glUseProgram(shaderProgramId); - } - else - { - throw ShaderProgramUsedBeforeBuilt(); + for(Shader *shader : shaders) { + glAttachShader(shader_program_id, shader->id); } + + glLinkProgram(shader_program_id); + std::unique_ptr shader_program; + shader_program.reset(new ShaderProgram(shader_program_id)); + return Result>::Ok(std::move(shader_program)); } - - ShaderProgramGlobalVec3 ShaderProgram::getGlobalVec3(const char *name) - { - if(built) - { - GLint uniformId = glGetUniformLocation(shaderProgramId, name); - if(uniformId == -1) - throw ShaderProgramNonExistingGlobalVariable(name); - return ShaderProgramGlobalVec3(this, uniformId); + + int ShaderProgram::set_uniform(const char *name, const vec3f &value) { + GLint uniformId = glGetUniformLocation(program_id, name); + if(uniformId == -1) + return -1; + use(); + glUniform3f(uniformId, value.x, value.y, value.z); + return 0; + } + + int ShaderProgram::set_vertex_input(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; } - else - { - throw ShaderProgramUsedBeforeBuilt(); + + data.use(); + 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: assert(false); return -1; } + glEnableVertexAttribArray(attrib_location); + return 0; + } + + void ShaderProgram::use() { + glUseProgram(program_id); } } diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp deleted file mode 100644 index 8897b84..0000000 --- a/src/RenderBackend/OpenGL/ShaderVec.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/ShaderVec.hpp" -#include "../../../include/RenderBackend/OpenGL/Shader.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; - } - else if(strncmp(attributeName, "vec3", 4) == 0) - { - return AttributeType::VEC3; - } - else if(strncmp(attributeName, "vec4", 4) == 0) - { - return AttributeType::VEC4; - } - - assert(false); - return AttributeType::NONE; - } - - void ShaderProgramGlobalVec3::set(f32 x, f32 y, f32 z) - { - shaderProgram->use(); - glUniform3f(uniformId, x, y, z); - } - - const string& ShaderInputVec2::getName() const - { - return shader->getInputAttributeName(attributeIndex); - } - - void ShaderInputVec2::setData(const DeviceMemory &data) - { - data.use(); - AttributeType attributeType = shader->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 shader->getOutputAttributeName(attributeIndex); - } - - void ShaderOutputVec4::operator=(const ShaderVec4 &shaderVec4) - { - shader->assign(*this, shaderVec4); - } -} diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp deleted file mode 100644 index 19705b6..0000000 --- a/src/RenderBackend/OpenGL/VertexShader.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp" -#include "../../../include/RenderBackend/OpenGL/opengl.hpp" -#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" - -namespace amalgine { - VertexShader::VertexShader() - { - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); - } - - void VertexShader::defineMain(VertexShaderMainFunc mainFunc) - { - if(mainFuncDefined) - throw ShaderFunctionAlreadyDefined("main"); - - writeBody("void main() {\n"); - ShaderVec4 glPosition = mainFunc(); - mainFuncDefined = true; - writeBody("gl_Position = "); - writeBody(glPosition.getOutput()); - writeBody(";\n}\n\n"); - } - - Result VertexShader::compile() - { - GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER); - std::string verterShaderSource = build(); - const char *verterShaderSourcePtr = verterShaderSource.c_str(); - printf("Vertex shader:\n%s\n", verterShaderSourcePtr); - glShaderSource(vertexShaderId, 1, &verterShaderSourcePtr, NULL); - glCompileShader(vertexShaderId); - - GLint status; - glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status); - std::string compileLog = getShaderCompileLog((u32)vertexShaderId); - if(status == GL_TRUE) - { - if(!compileLog.empty()) - printf("Vertex shader compile log:\n%s", compileLog.c_str()); - return Result::Ok(new CompiledVertexShader(vertexShaderId)); - } - else - return Result::Err(compileLog); - } -} diff --git a/src/main.cpp b/src/main.cpp index 24ef4f8..f6f827f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,6 @@ #include #include "../include/RenderBackend/OpenGL/opengl.hpp" -#include "../include/RenderBackend/OpenGL/VertexShader.hpp" -#include "../include/RenderBackend/OpenGL/PixelShader.hpp" +#include "../include/RenderBackend/OpenGL/Shader.hpp" #include "../include/RenderBackend/OpenGL/ShaderProgram.hpp" #include "../include/RenderBackend/OpenGL/DeviceMemory.hpp" #include "../include/RenderBackend/OpenGL/DeviceFrame.hpp" @@ -16,13 +15,11 @@ using namespace amalgine; using namespace std; -void glfwErrorHandler(int errorCode, const char *errorDescription); -void initGlfw(); -void initGlew(); -GLFWwindow *createWindow(); - -CompiledVertexShader* createVertexShader(const DeviceMemory &inputData); -CompiledPixelShader* createPixelShader(); +static void glfwErrorHandler(int errorCode, const char *errorDescription); +static void initGlfw(); +static void initGlew(); +static GLFWwindow *createWindow(); +static std::unique_ptr load_shader_from_file(const char *filepath, Shader::Type shader_type); int main() { @@ -40,25 +37,19 @@ int main() DataView cpuTriangles(&cpuTriangle, 1); DeviceMemory *gpuTriangle = frame.alloc(); gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC); + + std::unique_ptr vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX); + std::unique_ptr pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL); - CompiledVertexShader *vertexShader = createVertexShader(*gpuTriangle); - CompiledPixelShader *pixelShader = createPixelShader(); - - ShaderProgram shaderProgram; - shaderProgram.setVertexShader(vertexShader); - shaderProgram.setPixelShader(pixelShader); - // Make ShaderProgram.build return an object which we can do things on? since some operations - // require the shader to be built to be used - Result shaderBuildResult = shaderProgram.build(); - - ShaderProgramGlobalVec3 triangleColor = shaderProgram.getGlobalVec3("triangleColor"); - triangleColor.set(1.0f, 0.0f, 0.0f); - - if(!shaderBuildResult) - { - fprintf(stderr, "Failed to build shader program: %s\n", shaderBuildResult.getErrorMsg().c_str()); - exit(20); + Result> shader_program_result = ShaderProgram::build({ vertex_shader.get(), pixel_shader.get() }); + if(!shader_program_result) { + fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str()); + exit(13); } + std::unique_ptr shader_program = std::move(shader_program_result.unwrap()); + + shader_program->set_vertex_input("position", *gpuTriangle); + shader_program->set_uniform("triangle_color", vec3f{ 1.0f, 0.0f, 0.0f }); while(!glfwWindowShouldClose(window)) { @@ -70,8 +61,7 @@ int main() glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Do the actual screen clearing, using the color set using glClearColor glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - shaderProgram.use(); - frame.draw(); + frame.draw(shader_program.get()); glfwSwapBuffers(window); } @@ -128,53 +118,31 @@ GLFWwindow* createWindow() return window; } -CompiledVertexShader* createVertexShader(const DeviceMemory &inputData) -{ - VertexShader vertexShader; - ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position"); - inputPosition.setData(inputData); - #if 0 - ShaderGlobalMat4x4 model = vertexShader.defineGlobalMat4x4("model"); - ShaderGlobalMat4x4 view = vertexShader.defineGlobalMat4x4("view"); - ShaderGlobalMat4x4 proj = vertexShader.defineGlobalMat4x4("proj"); - - vertexShader.defineMain([&inputPosition, &model, &view, &proj]() - { - return proj * view * model * ShaderVec4(inputPosition, 0.0f, 1.0f); - }); - #endif - vertexShader.defineMain([&inputPosition]() - { - return ShaderVec4(inputPosition, 0.0f, 1.0f); - }); - - Result compiledVertexShader = vertexShader.compile(); - if(!compiledVertexShader) - { - fprintf(stderr, "Failed to compile vertex shader:\n%s", compiledVertexShader.getErrorMsg().c_str()); - exit(2); +static int file_read_all(const char *filepath, std::string &result) { + FILE *file = fopen(filepath, "rb"); + if(!file) { + perror("file_read_all"); + return errno; } - - return compiledVertexShader.unwrap(); + + fseek(file, 0, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0, SEEK_SET); + result.resize(file_size); + fread(&result[0], 1, result.size(), file); + fclose(file); + return 0; } -CompiledPixelShader* createPixelShader() -{ - PixelShader pixelShader; - ShaderGlobalVec3 triangleColor = pixelShader.defineGlobalVec3("triangleColor"); - ShaderOutputVec4 outColor = pixelShader.defineOutputVec4("outColor"); - - pixelShader.defineMain([&triangleColor, &outColor]() - { - outColor = ShaderVec4(triangleColor, 1.0f); - }); - - Result compiledPixelShader = pixelShader.compile(); - if(!compiledPixelShader) - { - fprintf(stderr, "Failed to compile pixel shader:\n%s", compiledPixelShader.getErrorMsg().c_str()); - exit(2); +std::unique_ptr load_shader_from_file(const char *filepath, Shader::Type shader_type) { + std::string file_content; + if(file_read_all(filepath, file_content) != 0) + exit(13); + + Result> vertex_shader_result = Shader::compile(shader_type, file_content.data(), file_content.size()); + if(!vertex_shader_result) { + fprintf(stderr, "Failed to compile shader, error: %s\n", vertex_shader_result.getErrorMsg().c_str()); + exit(12); } - - return compiledPixelShader.unwrap(); -} + return std::move(vertex_shader_result.unwrap()); +} \ No newline at end of file -- cgit v1.2.3