diff --git a/include/scene.h b/include/scene.h index 3b69356..c59fa85 100644 --- a/include/scene.h +++ b/include/scene.h @@ -8,12 +8,18 @@ #include "fbo.h" +struct Vertex { + glm::vec3 position; + glm::vec2 texCoord; +}; + class Scene { public: Scene(int width, int height); ~Scene(); void Init(); + void GenerateGrid(int divisions, std::vector& verts, std::vector& inds); void Display(GLFWwindow* window); void DrawGui(GLFWwindow* window); void Idle(); diff --git a/source/scene.cpp b/source/scene.cpp index 49dde28..1bb6a15 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -39,6 +39,9 @@ const std::string kHGTPath = "hgt/N02E016.hgt"; GLuint tex_id = -1; +std::vector vertices; +std::vector indices; + } // namespace Scene::Scene(int width, int height) @@ -70,7 +73,7 @@ void Scene::Init() { // GL_DEPTH_TEST causes artifacts in meshes made up of multiple triangles // disabling for now //glEnable(GL_DEPTH_TEST); - //glEnable(GL_CULL_FACE); + glEnable(GL_CULL_FACE); fbo_.Init(window_width, window_height); post_fbo_.Init(window_width, window_height); @@ -87,33 +90,70 @@ void Scene::Init() { Uniforms::Init(); } +void Scene::GenerateGrid(int divisions, std::vector& verts, std::vector& inds) { + float step = 1.0f / static_cast(divisions); + float halfSize = 0.5f; + + // Create vertices for patches + for (int i = 0; i <= divisions; i++) { + for (int j = 0; j <= divisions; j++) { + float x = -halfSize + j * step; + float y = -halfSize + i * step; + + Vertex vertex; + vertex.position = glm::vec3(x, y, 0.0f); + vertex.texCoord = glm::vec2(static_cast(j) / divisions, static_cast(i) / divisions); + + verts.push_back(vertex); + } + } + + // Create indices for patches + for (int i = 0; i < divisions; i++) { + for (int j = 0; j < divisions; j++) { + int bottomLeft = i * (divisions + 1) + j; + int bottomRight = bottomLeft + 1; + int topLeft = bottomLeft + (divisions + 1); + int topRight = topLeft + 1; + + inds.push_back(topLeft); + inds.push_back(topRight); + inds.push_back(bottomRight); + inds.push_back(bottomLeft); + } + } +} + // Currently creates a test triangle and initializes its buffers void Scene::InitBuffers() { - GLuint patch_vbo; - - float patchVertices[] = { - // Positions // Texture Coords - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // Bottom-left - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Bottom-right - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // Top-right - -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // Top-left - }; + int divisions = 2; // Number of divisions along one axis of the grid + GenerateGrid(divisions, vertices, indices); + // Create and bind VAO, VBO, and EBO, and pass the data to OpenGL + GLuint vao, vbo, ebo; glGenVertexArrays(1, &vao_); - glGenBuffers(1, &patch_vbo); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + glBindVertexArray(vao_); - glBindBuffer(GL_ARRAY_BUFFER, patch_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(patchVertices), &patchVertices, GL_STATIC_DRAW); + // Bind and fill the vertex buffer + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); - // Position attribute + // Bind and fill the element buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); + + // Define vertex position attribute + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position)); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - // Texture coordinate attribute + // Define texture coordinate attribute + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoord)); glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + // Unbind VAO glBindVertexArray(0); } @@ -184,7 +224,7 @@ void Scene::Display(GLFWwindow* window) { glBindVertexArray(vao_); glPatchParameteri(GL_PATCH_VERTICES, 4); - glDrawArrays(GL_PATCHES, 0, 4); + glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, 0); //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);