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