#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" #include "../include/Triangle2D.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; void glfwErrorHandler(int errorCode, const char *errorDescription); void initGlfw(); void initGlew(); GLFWwindow *createWindow(); CompiledVertexShader* createVertexShader(const DeviceMemory &inputData); CompiledPixelShader* createPixelShader(); int main() { initGlfw(); glfwSetErrorCallback(glfwErrorHandler); GLFWwindow *window = createWindow(); DeviceFrame frame; Triangle2D cpuTriangle( Vertex2D(0.0f, 0.5f), Vertex2D(0.5f, -0.5f), Vertex2D(-0.5f, -0.5f) ); DataView cpuTriangles(&cpuTriangle, 1); DeviceMemory *gpuTriangle = frame.alloc(); gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC); 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); } while(!glfwWindowShouldClose(window)) { glfwPollEvents(); if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); // Set color for clearing 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(); glfwSwapBuffers(window); } glfwTerminate(); return 0; } void glfwErrorHandler(int errorCode, const char *errorDescription) { printf("GLFW error code: %d, description: %s\n", errorCode, errorDescription); } void initGlfw() { if(!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); exit(-1); } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); } void initGlew() { glewExperimental = true; if(glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); glfwTerminate(); exit(-1); } } GLFWwindow* createWindow() { GLFWwindow *window = glfwCreateWindow(1280, 720, "Amalgine", nullptr, nullptr); if(!window) { fprintf(stderr, "Failed to open GLFW window\n"); glfwTerminate(); exit(10); } glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwMakeContextCurrent(window); glfwSwapInterval(0); initGlew(); return window; } CompiledVertexShader* createVertexShader(const DeviceMemory &inputData) { VertexShader vertexShader; ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position"); inputPosition.setData(inputData); 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); } return compiledVertexShader.unwrap(); } 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); } return compiledPixelShader.unwrap(); }