diff --git a/OpenGL/cube/cube.a b/OpenGL/cube/cube.a index 45a39f4..7fabf89 100755 Binary files a/OpenGL/cube/cube.a and b/OpenGL/cube/cube.a differ diff --git a/OpenGL/cube/shaders/simple.frag b/OpenGL/cube/shaders/simple.frag new file mode 100644 index 0000000..70d8620 --- /dev/null +++ b/OpenGL/cube/shaders/simple.frag @@ -0,0 +1,7 @@ +#version 150 core + +out vec4 outColour; + +void main() { + outColour = vec4(1.0, 1.0, 1.0, 1.0); +} diff --git a/OpenGL/cube/shaders/simple.vert b/OpenGL/cube/shaders/simple.vert new file mode 100644 index 0000000..03753f9 --- /dev/null +++ b/OpenGL/cube/shaders/simple.vert @@ -0,0 +1,8 @@ +#version 150 core + +in vec2 position; + +void main() { + gl_position = vec4(position, 0.0, 1.0); + // Equivilent to vec4(position.x, position.y, 0.0, 1.0) +} diff --git a/OpenGL/cube/src/main.cpp b/OpenGL/cube/src/main.cpp index 59c0108..3770f2e 100644 --- a/OpenGL/cube/src/main.cpp +++ b/OpenGL/cube/src/main.cpp @@ -1,6 +1,10 @@ #include #include #include +#include +#include +#include +#include class Game { public: @@ -9,6 +13,76 @@ public: bool isWindowClosed = true; }; +std::map VertexShaders; +std::map FragmentShaders; +std::map ShaderPrograms; + +std::string readShader(std::string source) { + std::ifstream t(source); + std::string shaderCode((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); + return shaderCode; +} + +bool loadShader(std::string shaderSource, GLenum type, std::string shader) { + const char* source = shader.c_str(); + + if (type == GL_VERTEX_SHADER) { + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &source, NULL); + glCompileShader(vertexShader); + + GLint status; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); + if (status == GL_TRUE) { + char buf[512]; + glGetShaderInfoLog(vertexShader, 512, NULL, buf); + std::cerr << buf << std::endl; + return false; + } + + VertexShaders[shader] = vertexShader; + } else if (type == GL_FRAGMENT_SHADER) { + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &source, NULL); + glCompileShader(fragmentShader); + + GLint status; + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); + if (status == GL_TRUE) { + char buf[512]; + glGetShaderInfoLog(fragmentShader, 512, NULL, buf); + std::cerr << buf << std::endl; + return false; + } + + FragmentShaders[shader] = fragmentShader; + } + return true; +} + +void makeShaderProgram(std::string vert, std::string frag, std::string program) { + GLuint shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, VertexShaders[vert]); + glAttachShader(shaderProgram, FragmentShaders[frag]); + ShaderPrograms[program] = shaderProgram; +} + +void applySimpleShaders(std::string program) { + glBindFragDataLocation(ShaderPrograms[program], 0, "outColour"); + GLint posAttrib = glGetAttribLocation(ShaderPrograms[program], "position"); + glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(posAttrib); +} + +void linkShader(std::string shader) { + glLinkProgram(ShaderPrograms[shader]); +} + +void applyShader(std::string shader) { + glUseProgram(ShaderPrograms[shader]); +} + int main(int argc, char** argv) { Game* game = new Game(); SDL_Init(SDL_INIT_EVERYTHING); @@ -31,23 +105,59 @@ int main(int argc, char** argv) { GLenum GLEWStatus = glewInit(); if (GLEWStatus != GLEW_OK) { std::cerr << "FAILED TO INITALIZE GLEW" << std::endl; + return 0; } // SDL_WarpMouseInWindow(m_window, width / 2, height / 2); // SDL_SetRelativeMouseMode(SDL_TRUE); + game->isWindowClosed = false; glClearColor(0.1f, 0.45f, 0.9f, 1.0f); + // GL Screen coordinates of a 2D triangle + float verticies[] = { + 0.0f, 0.5f, // Vertex 1 (X, Y) + 0.5f, -0.5f, // Vertex 2 (X, Y) + -0.5f, -0.5f // Vertex 3 (X, Y) + }; + + // Generate a vertex array object + GLuint vao; + glGenVertexArrays(1, &vao); + // Bind array to GPU + glBindVertexArray(vao); + + // Generate a vertex buffer object + GLuint vbo; + glGenBuffers(1, &vbo); + // Binding buffer to GPU + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // Copy vertex data to the vertex buffer already on the GPU + glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW); + + // Load, compile, apply and link shader programs + if (!loadShader(readShader("shaders/simple.frag"), GL_FRAGMENT_SHADER, "simpleFrag") || + !loadShader(readShader("shaders/simple.vert"), GL_VERTEX_SHADER , "simpleVert")) { + return 0; + } + makeShaderProgram("simpleVert", "simpleFrag", "simpleProc"); + applySimpleShaders("simpleProc"); + linkShader("simpleProc"); + SDL_Event event; while (!game->isWindowClosed) { - glClear(GL_COLOR_BUFFER_BIT); - + // Input handling while (SDL_PollEvent(&event) != 0) if (event.key.keysym.sym == SDLK_ESCAPE) game->isWindowClosed = true; + // Render + glClear(GL_COLOR_BUFFER_BIT); + applyShader("simpleProc"); + glDrawArrays(GL_TRIANGLES, 0, 3); + // Swap buffers SDL_GL_SwapWindow(game->window); } @@ -55,4 +165,6 @@ int main(int argc, char** argv) { SDL_GL_DeleteContext(game->glContext); SDL_DestroyWindow(game->window); SDL_Quit(); + + return 0; }