diff --git a/FinalProject/FinalProject.vcxproj b/FinalProject/FinalProject.vcxproj index d73cb8a..0b92cd2 100644 --- a/FinalProject/FinalProject.vcxproj +++ b/FinalProject/FinalProject.vcxproj @@ -115,6 +115,7 @@ + @@ -134,6 +135,7 @@ + diff --git a/FinalProject/FinalProject.vcxproj.filters b/FinalProject/FinalProject.vcxproj.filters index cda208c..2ccb5d7 100644 --- a/FinalProject/FinalProject.vcxproj.filters +++ b/FinalProject/FinalProject.vcxproj.filters @@ -103,6 +103,9 @@ Source Files\OpenGL Abstractions + + Source Files\OpenGL Abstractions + @@ -153,6 +156,9 @@ Header Files\OpenGL Abstractions + + Header Files\OpenGL Abstractions + diff --git a/FinalProject/sceneviewer.cpp b/FinalProject/sceneviewer.cpp index 2896afe..1111d49 100644 --- a/FinalProject/sceneviewer.cpp +++ b/FinalProject/sceneviewer.cpp @@ -75,6 +75,13 @@ void SceneViewer::initializeGL() { vertexShader_sky.dispose(); fragmentShader_sky.dispose(); + VertexShader vertexShader_ter("./temp/shaders/terrainShader.vs"); + FragmentShader fragmentShader_ter("./temp/shaders/terrainShader.fs"); + terrainShader.attachShader(vertexShader_ter); + terrainShader.attachShader(fragmentShader_ter); + vertexShader_ter.dispose(); + fragmentShader_ter.dispose(); + Model* backpackModel = new Model("D:\\ProgrammingFile\\SceneEditor\\Models\\backpack\\backpack.obj"); Logger::info("Model loaded"); @@ -82,6 +89,8 @@ void SceneViewer::initializeGL() { _objects.push_back(backpack); sky = new skybox("D:/ProgrammingFile/SceneEditor/skybox"); + + ter = new Terrain(); _camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f)); } @@ -98,21 +107,36 @@ void SceneViewer::paintGL() { // Set view and projection matrices glm::mat4 view = _camera.viewMatrix(); glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f); - _shaderProgram.setUniform("view", view); + /*_shaderProgram.setUniform("view", view); _shaderProgram.setUniform("projection", projection); for (auto object : _objects) { object.render(_shaderProgram); - } + }*/ _shaderProgram.unbind(); - skyShader.bind(); + terrainShader.bind(); + glm::mat4 Model = glm::mat4(1.0f); + Model = glm::translate(Model, glm::vec3(0.0f, 0.0f, -2.0f)); + terrainShader.setUniform("view", view); + terrainShader.setUniform("projection", projection); + terrainShader.setUniform("model", Model); + terrainShader.setUniform("dep", 0); + terrainShader.setUniform("tex1", 1); + terrainShader.setUniform("tex2", 2); + ter->render(); + terrainShader.unbind(); + + + /*skyShader.bind(); view = glm::mat4(glm::mat3(view)); skyShader.setUniform("view", view); skyShader.setUniform("projection", projection); sky->render(); - skyShader.unbind(); + skyShader.unbind();*/ + + } void SceneViewer::mousePressEvent(QMouseEvent* event) { diff --git a/FinalProject/sceneviewer.h b/FinalProject/sceneviewer.h index 6ad5eb6..c3cba71 100644 --- a/FinalProject/sceneviewer.h +++ b/FinalProject/sceneviewer.h @@ -13,6 +13,7 @@ #include "vao.h" #include "utils.h" #include "skybox.h" +#include "terrain.h" class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions { @@ -25,7 +26,10 @@ private: // Shader program for objects ShaderProgram _shaderProgram = ShaderProgram::empty(); ShaderProgram skyShader = ShaderProgram::empty(); + ShaderProgram terrainShader = ShaderProgram::empty(); skybox* sky; + Terrain* ter; + // Main camera Camera _camera; float _cameraMovementSpeed = 0.02f; diff --git a/FinalProject/terrain.cpp b/FinalProject/terrain.cpp new file mode 100644 index 0000000..68084b6 --- /dev/null +++ b/FinalProject/terrain.cpp @@ -0,0 +1,97 @@ +#include "terrain.h" +#include "utils.h" + +#include +#include + +Terrain::Terrain(int rows, int cols):row_num(rows),col_num(cols) { + Vertex.clear(); + Indicess.clear(); + float x = -50, z = -50; + + for (int i = 0; i < rows; i++) { + x = -5; + for (int j = 0; j < cols; j++) { + Vertex.push_back(x); + Vertex.push_back(0); + Vertex.push_back(z); + Vertex.push_back(1.0f / cols * j); + Vertex.push_back(1 - i * 1.0f / rows); + x += 0.1; + } + z += 0.1; + } + + for (int i = 1; i < rows; i++) { + for (int j = 1; j < cols; j++) { + Indicess.push_back((i - 1) * cols + j - 1); + Indicess.push_back((i - 1) * cols + j); + Indicess.push_back(i * cols + j - 1); + + Indicess.push_back(i * cols + j - 1); + Indicess.push_back((i - 1) * cols + j); + Indicess.push_back(i * cols + j); + } + } + + tex1 = loadTexture("D:/ProgrammingFile/SceneEditor/terrain/rock.jpg"); + tex2 = loadTexture("D:/ProgrammingFile/SceneEditor/terrain/water.jpg"); + dep = loadTexture("D:/ProgrammingFile/SceneEditor/terrain/heightmap.png"); + + OPENGL_EXTRA_FUNCTIONS->glGenVertexArrays(1, &TerrainVAO); + OPENGL_EXTRA_FUNCTIONS->glGenBuffers(1, &TerrainVBO); + OPENGL_EXTRA_FUNCTIONS->glBindVertexArray(TerrainVAO); + OPENGL_EXTRA_FUNCTIONS->glBindBuffer(GL_ARRAY_BUFFER, TerrainVBO); + OPENGL_EXTRA_FUNCTIONS->glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex), &Vertex, GL_STATIC_DRAW); + OPENGL_EXTRA_FUNCTIONS->glEnableVertexAttribArray(0); + OPENGL_EXTRA_FUNCTIONS->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); +} + +unsigned int Terrain::loadTexture(std::string path) { + unsigned int textureID; + OPENGL_FUNCTIONS->glGenTextures(1, &textureID); + OPENGL_FUNCTIONS->glBindTexture(GL_TEXTURE_2D, textureID); + stbi_set_flip_vertically_on_load(true); + + int width, height, nrChannels; + + unsigned char* data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0); + if (data) { + GLenum format; + if (nrChannels == 1) { + format = GL_RED; + } + else if (nrChannels == 3) { + format = GL_RGB; + } + else if (nrChannels == 4) { + format = GL_RGBA; + } + else { + return 0; + } + + OPENGL_FUNCTIONS->glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + OPENGL_FUNCTIONS->glGenerateMipmap(GL_TEXTURE_2D); + } + + stbi_image_free(data); + + return textureID; +} + +void Terrain::render() { + OPENGL_EXTRA_FUNCTIONS->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + OPENGL_EXTRA_FUNCTIONS->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0); + OPENGL_EXTRA_FUNCTIONS->glBindTexture(GL_TEXTURE_2D, dep); + OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE1); + OPENGL_EXTRA_FUNCTIONS->glBindTexture(GL_TEXTURE_2D, tex1); + OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE2); + OPENGL_EXTRA_FUNCTIONS->glBindTexture(GL_TEXTURE_2D, tex2); + + OPENGL_EXTRA_FUNCTIONS->glBindVertexArray(TerrainVAO); + OPENGL_EXTRA_FUNCTIONS->glDrawElements(GL_TRIANGLES, Indicess.size(), GL_UNSIGNED_SHORT, &Indicess.front()); + +} \ No newline at end of file diff --git a/FinalProject/terrain.h b/FinalProject/terrain.h new file mode 100644 index 0000000..39e6fab --- /dev/null +++ b/FinalProject/terrain.h @@ -0,0 +1,19 @@ +#pragma once + +#include "utils.h" + +#include +#include + +class Terrain { +private: + std::vector Vertex; + std::vector Indicess; + unsigned int TerrainVAO, TerrainVBO; + int row_num, col_num; +public: + unsigned int dep, tex1, tex2; + Terrain(int rows = 200, int cols = 200); + void render(); + unsigned int loadTexture(std::string path); +}; \ No newline at end of file diff --git a/terrain/heightmap.png b/terrain/heightmap.png new file mode 100644 index 0000000..89abd09 Binary files /dev/null and b/terrain/heightmap.png differ diff --git a/terrain/rock.jpg b/terrain/rock.jpg new file mode 100644 index 0000000..ec4cdf8 Binary files /dev/null and b/terrain/rock.jpg differ diff --git a/terrain/water.jpg b/terrain/water.jpg new file mode 100644 index 0000000..b1ec2da Binary files /dev/null and b/terrain/water.jpg differ