#ifdef RENDERER_OPENGL #ifndef RENDERER_OPENGL_H #define RENDERER_OPENGL_H #include "pch.hpp" #include "utils/Renderer/Renderer.h" #define GLEW_STATIC #include namespace Archimedes { class RendererOpenGL : public Renderer { public: typedef void renderCmd(); RendererOpenGL() {}; ~RendererOpenGL() {}; bool init() override { bool ok = glewInit() == GLEW_OK; if(ok) { glEnable(GL_DEPTH_TEST); } return ok; }; void render() override { glViewport(0, 0, w, h); glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } Shader createShader(const std::string& vs, const std::string& fs, const Shader::LoadType& lt) override { Shader shader(vs, fs, lt); std::string vss = shader.getVSource(); std::string fss = shader.getFSource(); const char* vsc = vss.c_str(); const char* fsc = fss.c_str(); unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vsc, NULL); glCompileShader(vertexShader); // check for shader compile errors int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // fragment shader unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fsc, NULL); glCompileShader(fragmentShader); // check for shader compile errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // link shaders unsigned int shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); shader.id = shaderProgram; return shader; } void useShader(Shader& shader) override { std::string vss = shader.getVSource(); std::string fss = shader.getFSource(); const char* vsc = vss.c_str(); const char* fsc = fss.c_str(); unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vsc, NULL); glCompileShader(vertexShader); // check for shader compile errors int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // fragment shader unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fsc, NULL); glCompileShader(fragmentShader); // check for shader compile errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // link shaders unsigned int shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); shader.id = shaderProgram; } RenderTarget createRenderTarget(VertexBuffer vb, IndexArray ia, VertexLayout layout, Shader& s) override { auto rt = RenderTarget(vb, ia, layout, s); glGenVertexArrays(1, &rt.vertexArray.id); glGenBuffers(1, &rt.vertexBuffer.id); glBindVertexArray(rt.vertexArray.id); glBindBuffer(GL_ARRAY_BUFFER, rt.vertexBuffer.id); glBufferData(GL_ARRAY_BUFFER, vb.getSize(), vb.getData(), GL_STATIC_DRAW); glGenBuffers(1, &rt.indexArray.id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.id); glBufferData(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.getCount() * sizeof(unsigned int), rt.indexArray.getIndicies(), GL_STATIC_DRAW); glUseProgram(s.id); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); return rt; }; void useRenderTarget(RenderTarget& rt) override { glGenVertexArrays(1, &rt.vertexArray.id); glGenBuffers(1, &rt.vertexBuffer.id); glBindVertexArray(rt.vertexArray.id); glBindBuffer(GL_ARRAY_BUFFER, rt.vertexBuffer.id); glBufferData(GL_ARRAY_BUFFER, rt.vertexBuffer.getSize(), rt.vertexBuffer.getData(), GL_STATIC_DRAW); glGenBuffers(1, &rt.indexArray.id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.id); glBufferData(GL_ELEMENT_ARRAY_BUFFER, rt.indexArray.getCount() * sizeof(unsigned int), rt.indexArray.getIndicies(), GL_STATIC_DRAW); glUseProgram(rt.shader.id); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); }; void draw(const RenderTarget& rt) override { glUseProgram(rt.shader.id); unsigned int transformLoc = glGetUniformLocation(rt.shader.id, "model"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(rt.transform)); unsigned int resLoc = glGetUniformLocation(rt.shader.id, "res"); glUniform2ui(resLoc, w, h); unsigned int ccLoc = glGetUniformLocation(rt.shader.id, "clearColor"); glUniform4f(ccLoc, clearColor.r, clearColor.g, clearColor.b, clearColor.a); glBindVertexArray(rt.vertexArray.id); glDrawElements(GL_TRIANGLES, rt.indexArray.getCount(), GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); } RendererOpenGL* getRendererImpl() override { return this; } }; } #endif #endif