diff --git a/assets/shaders/shader.frag b/assets/shaders/shader.frag index f123dc5..d8ad859 100644 --- a/assets/shaders/shader.frag +++ b/assets/shaders/shader.frag @@ -1,24 +1,9 @@ #version 150 core -uniform sampler2D tex; -uniform float time; - in vec3 color; -in vec2 coord; out vec4 outColor; void main() { - vec2 sampleCoord; - - if(coord.y < 0.75) { - sampleCoord = coord; - } else { - sampleCoord = vec2( - coord.x + 0.025 * sin(time * 1.5 + coord.y * 80.0), - (1.0 - coord.y) * 3 - ); - } - - outColor = texture(tex, sampleCoord) * vec4(color, 1.0); + outColor = vec4(color, 1.0); } diff --git a/assets/shaders/shader.vert b/assets/shaders/shader.vert index 3882ee6..eb09037 100644 --- a/assets/shaders/shader.vert +++ b/assets/shaders/shader.vert @@ -1,18 +1,13 @@ #version 150 core -in vec3 inPos; +in vec3 inPosition; in vec3 inColor; -in vec2 inCoord; out vec3 color; -out vec2 coord; -uniform mat4 model; -uniform mat4 view; -uniform mat4 proj; +uniform mat4 inTransformation; void main() { color = inColor; - coord = inCoord; - gl_Position = proj * view * model * vec4(inPos, 1.0); + gl_Position = inTransformation * vec4(inPosition, 1.0); } diff --git a/source/app/src/App.cpp b/source/app/src/App.cpp index 71aa212..0fbbdfb 100644 --- a/source/app/src/App.cpp +++ b/source/app/src/App.cpp @@ -1,5 +1,6 @@ #include "App.hpp" +#include #include #include @@ -13,6 +14,8 @@ #include "stb_image.h" #include "TimestampLog.hpp" +constexpr std::array, 36> getCubeVertices(); + namespace ugly { int App::main(std::vector &args) { @@ -64,100 +67,74 @@ void App::key_callback_s(GLFWwindow *window, int key, int scancode, int action, App::App(GLFWwindow *window): mpWindow{window}, mShaderProgram{} { + // To allow key_callback_s to access member functions glfwSetWindowUserPointer(mpWindow, this); glfwSetKeyCallback(mpWindow, key_callback_s); - float vertices[] = { - // Position(3), Color(3), TexCoord(2) - -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left - 1.0f, 1.0f, 0.0f, 0.f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right - 1.0f, -1.0f, 0.0f, 0.f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right - - 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Bottom-left - -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f // Top-left - }; - - GLuint vbo; - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - GLuint shaderProgram = ShaderProgramBuilder{} + // Prepare shader + mShaderProgram = ShaderProgramBuilder{} .attachFromFile(GL_VERTEX_SHADER, "assets/shaders/shader.vert") .attachFromFile(GL_FRAGMENT_SHADER, "assets/shaders/shader.frag") .link(); - glUseProgram(shaderProgram); - mShaderProgram = shaderProgram; + GLint posAttrib = glGetAttribLocation(mShaderProgram, "inPosition"); + GLint colorAttrib = glGetAttribLocation(mShaderProgram, "inColor"); - GLuint tex; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - int x, y, n; - auto data = stbi_load("assets/textures/bliss.jpg", &x, &y, &n, 3); - if(data == nullptr) { - log("stbi_load() failed!"); - } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(data); + glCreateVertexArrays(1, &mVAO); + glBindVertexArray(mVAO); - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - GLint posAttrib = glGetAttribLocation(shaderProgram, "inPos"); - GLint colorAttrib = glGetAttribLocation(shaderProgram, "inColor"); - GLint coordAttrib = glGetAttribLocation(shaderProgram, "inCoord"); - glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), 0); - glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(3*sizeof(float))); - glVertexAttribPointer(coordAttrib, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float))); + // Upload vertice attributes (position and color) + const auto vertices = getCubeVertices(); + GLuint vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), (void*)(&vertices), GL_STATIC_DRAW); + + // Vertex format = { x, y, z, r, g, b } + glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0); + glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float))); glEnableVertexAttribArray(posAttrib); glEnableVertexAttribArray(colorAttrib); - glEnableVertexAttribArray(coordAttrib); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } void App::game_loop() { - GLint timeUniform = glGetUniformLocation(mShaderProgram, "time"); - GLint modelUniform = glGetUniformLocation(mShaderProgram, "model"); - GLint viewUniform = glGetUniformLocation(mShaderProgram, "view"); - GLint projUniform = glGetUniformLocation(mShaderProgram, "proj"); - + // Generate view and projection tranforms int width, height; glfwGetWindowSize(mpWindow, &width, &height); - auto projMatrix = glm::perspective(60.0f, float(width) / height, 0.01f, 1000.f); - + auto projMatrix = glm::perspective(glm::radians(60.0f), float(width) / height, 0.01f, 1000.f); auto viewMatrix = glm::lookAt( glm::vec3{0.f, 0.f, 0.f}, - glm::vec3{0.f, 0.f, -1.f}, - glm::vec3{0.f, -1.f, 0.f} + glm::vec3{0.f, 0.f, 1.f}, + glm::vec3{0.f, 1.f, 0.f} ); - auto modelMatrix = glm::identity(); - modelMatrix = glm::translate(modelMatrix, glm::vec3{0.f, 0.f, -.2f}); - - glUniformMatrix4fv(viewUniform, 1, GL_FALSE, glm::value_ptr(viewMatrix)); - glUniformMatrix4fv(projUniform, 1, GL_FALSE, glm::value_ptr(projMatrix)); - glUniformMatrix4fv(modelUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix)); - glEnable(GL_DEPTH_TEST); - - auto prevTime = glfwGetTime(); - auto elapsed = 0.0; + GLint matrixUniform = glGetUniformLocation(mShaderProgram, "inTransformation"); + float startTime = glfwGetTime(); while(!glfwWindowShouldClose(mpWindow)) { glfwPollEvents(); - auto now = glfwGetTime(); - auto dt = now - prevTime; - elapsed += dt; - prevTime = now; - - modelMatrix = glm::rotate(modelMatrix, glm::radians(float(dt) * 18.0f), glm::vec3{0.08f, 0.05f, 1.f}); - glUniformMatrix4fv(modelUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix)); - glUniform1f(timeUniform, 4.f * elapsed); + // Rotate the cube each frame + float dt = glfwGetTime() - startTime; + auto modelMatrix = glm::identity(); + modelMatrix = glm::translate(modelMatrix, glm::vec3{0.f, 0.f, 2.f}); + modelMatrix = glm::rotate(modelMatrix, glm::radians(20.f * dt), glm::vec3{1.f, 1.f, 0.f}); + auto finalMatrix = projMatrix * viewMatrix * modelMatrix; + // Draw logic glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDrawArrays(GL_TRIANGLES, 0, 6); + glEnable(GL_DEPTH_TEST); + glUseProgram(mShaderProgram); + glBindVertexArray(mVAO); + + glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, glm::value_ptr(finalMatrix)); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); + glUseProgram(0); + glDisable(GL_DEPTH_TEST); glfwSwapBuffers(mpWindow); } } @@ -170,3 +147,51 @@ void App::key_callback(int key, int scancode, int action, int mods) { } } + + +constexpr std::array, 36> getCubeVertices() { + // The eight vertices of a cube + const float cubeVertices[8][3] = { + { -0.5f, -0.5f, -0.5f }, + { -0.5f, +0.5f, -0.5f }, + { +0.5f, +0.5f, -0.5f }, + { +0.5f, -0.5f, -0.5f }, + { -0.5f, -0.5f, +0.5f }, + { -0.5f, +0.5f, +0.5f }, + { +0.5f, +0.5f, +0.5f }, + { +0.5f, -0.5f, +0.5f } + }; + + // Color for each of the six faces + const float cubeColors[6][3] = { + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f }, + { 1.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 1.0f } + }; + + // Each face consists of two triangles, so 36 unique vertices total + const int vertexIndices[36] = { + 0, 1, 2, 2, 3, 0, // B + 4, 5, 1, 1, 0, 4, // L + 7, 6, 5, 5, 4, 7, // F + 3, 2, 6, 6, 7, 3, // R + 0, 3, 7, 7, 4, 0, // D + 2, 1, 5, 5, 6, 2 // U + }; + + // Construct an array suitable for OpenGL - concatenates position and color for each vertex + // { x, y, z, r, g, b } + std::array, 36> vertices; + for(int i = 0; i < 36; i++) { + vertices[i][0] = cubeVertices[vertexIndices[i]][0]; + vertices[i][1] = cubeVertices[vertexIndices[i]][1]; + vertices[i][2] = cubeVertices[vertexIndices[i]][2]; + vertices[i][3] = cubeColors[i/6][0]; + vertices[i][4] = cubeColors[i/6][1]; + vertices[i][5] = cubeColors[i/6][2]; + } + return vertices; +} diff --git a/source/app/src/App.hpp b/source/app/src/App.hpp index db1836f..15bb7f8 100644 --- a/source/app/src/App.hpp +++ b/source/app/src/App.hpp @@ -17,6 +17,7 @@ private: private: GLFWwindow *mpWindow; unsigned int mShaderProgram; + unsigned int mVAO; private: App(GLFWwindow *window);