From 8238e94eea58d3dad7c0f6ed37b8019584f25728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 23 Mar 2020 17:26:32 +0100 Subject: [PATCH] Add perspective view --- .../globalcanvassettings.hpp | 21 ++++++ include/opengl-playground/openglshader.hpp | 10 ++- include/opengl-playground/opengltexture.hpp | 7 +- .../opengl-playground/textured-rectangle.hpp | 9 ++- shaders/textured-rectangle-fragment.glsl | 7 +- shaders/textured-rectangle-vertex.glsl | 5 ++ src/globalcanvassettings.cpp | 37 +++++++++++ src/main.cpp | 65 ++++++++++++++++--- src/openglshader.cpp | 37 +++++------ src/opengltexture.cpp | 32 +++++---- src/sdlmainwindow.cpp | 4 ++ src/textured-rectangle.cpp | 30 ++++++--- 12 files changed, 203 insertions(+), 61 deletions(-) create mode 100644 include/opengl-playground/globalcanvassettings.hpp create mode 100644 src/globalcanvassettings.cpp diff --git a/include/opengl-playground/globalcanvassettings.hpp b/include/opengl-playground/globalcanvassettings.hpp new file mode 100644 index 0000000..47996d3 --- /dev/null +++ b/include/opengl-playground/globalcanvassettings.hpp @@ -0,0 +1,21 @@ +#ifndef GLOBALCANVASSETTINGS_H +#define GLOBALCANVASSETTINGS_H + +#include + +class GlobalCanvasSettings +{ + public: + static void setProjectionMatrix(const glm::mat4 &proj); + static void setViewMatrix(const glm::mat4 &view); + static const glm::mat4 &getViewMatrix(); + static const glm::mat4 &getProjectionMatrix(); + static const glm::mat4 &getPVMatrix(); + private: + static void calculatePVMatrix(); + static glm::mat4 m_proj; + static glm::mat4 m_view; + static glm::mat4 m_proj_view; +}; + +#endif // GLOBALCANVASSETTINGS_H diff --git a/include/opengl-playground/openglshader.hpp b/include/opengl-playground/openglshader.hpp index ed01de8..c6dff72 100644 --- a/include/opengl-playground/openglshader.hpp +++ b/include/opengl-playground/openglshader.hpp @@ -9,21 +9,19 @@ class OpenGlShaderProgram { public: OpenGlShaderProgram(std::string vertex_file, std::string geometry_file, std::string fragment_file); + OpenGlShaderProgram(const OpenGlShaderProgram &) = delete; + OpenGlShaderProgram(const OpenGlShaderProgram &&) = delete; ~OpenGlShaderProgram(); - void setProjectionView(const glm::mat4 &projection, const glm::mat4 &view); - glm::mat4 getProjection(); - glm::mat4 getView(); int compile(); void unload(); int use(); int getUniformLoc(const std::string &uniform); void setUniformFloat(const std::string &uniform, float value); + void setUniformInt(const std::string &uniform, int value); void setUniformVec2(const std::string &uniform, float *vector); void setUniformMat4(const std::string &uniform, const glm::mat4 &matrix); + void setUniformVec4(const std::string &uniform, const glm::vec4 &vector); private: - glm::mat4 proj; - glm::mat4 view; - glm::mat4 proj_view; bool compiled; GLuint shader_program; std::string vertex_file; diff --git a/include/opengl-playground/opengltexture.hpp b/include/opengl-playground/opengltexture.hpp index 7057bcc..f6892ba 100644 --- a/include/opengl-playground/opengltexture.hpp +++ b/include/opengl-playground/opengltexture.hpp @@ -7,9 +7,12 @@ class OpenGlTexture { public: OpenGlTexture(); - OpenGlTexture(const OpenGlTexture &tex); - OpenGlTexture(const OpenGlTexture &&tex); + OpenGlTexture(const OpenGlTexture &tex) = delete; + OpenGlTexture(const OpenGlTexture &&tex) = delete; ~OpenGlTexture(); + void setRGBDataFromBytes(unsigned int width, unsigned int height, char *buffer); + void use(unsigned int slot); + void use(); protected: GLuint texture; diff --git a/include/opengl-playground/textured-rectangle.hpp b/include/opengl-playground/textured-rectangle.hpp index 6a2ce7a..1e20c64 100644 --- a/include/opengl-playground/textured-rectangle.hpp +++ b/include/opengl-playground/textured-rectangle.hpp @@ -2,13 +2,15 @@ #define TEXTURED_RECTANGLE_H #include +#include #include #include -class TexturedRectangle : OpenGlGraphics +class TexturedRectangle : public OpenGlGraphics { public: - TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr shaderprog); + TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr &shaderprog, + std::shared_ptr &texture); void realize(); void render(); void setZoom(float zoom); @@ -16,8 +18,11 @@ class TexturedRectangle : OpenGlGraphics void setOffset(float x_off, float y_off); float getOffsetX(); float getOffsetY(); + void setBaseColor(const glm::vec4 &color); private: + std::shared_ptr m_texture; void calculateModelMatrix(); + glm::vec4 base_color; float pos1[2]; float pos2[2]; float x_offset; diff --git a/shaders/textured-rectangle-fragment.glsl b/shaders/textured-rectangle-fragment.glsl index 10de971..a12990b 100644 --- a/shaders/textured-rectangle-fragment.glsl +++ b/shaders/textured-rectangle-fragment.glsl @@ -1,8 +1,13 @@ #version 330 core out vec4 fragmentColor; +in vec2 textureCoord; +uniform vec4 base_color; +uniform sampler2D uni_texture; void main() { - fragmentColor = vec4(1.0, 0.0, 0.0, 0.0); + vec4 temp_color = texture(uni_texture, textureCoord); + fragmentColor = temp_color * (1 - base_color.a) + base_color * base_color.a; + //fragmentColor = vec4(1.0, 0.0, 0.0, 0.0); } diff --git a/shaders/textured-rectangle-vertex.glsl b/shaders/textured-rectangle-vertex.glsl index ea3180b..a131e12 100644 --- a/shaders/textured-rectangle-vertex.glsl +++ b/shaders/textured-rectangle-vertex.glsl @@ -1,10 +1,15 @@ #version 330 core layout (location = 0) in vec2 inputVertex; +layout (location = 1) in vec2 textureInputVertex; + +out vec2 textureCoord; + uniform mat4 model_matrix; uniform mat4 projection_view_matrix; void main() { + textureCoord = textureInputVertex; gl_Position = projection_view_matrix * model_matrix * vec4(inputVertex.x , inputVertex.y, 0.0, 1.0); } diff --git a/src/globalcanvassettings.cpp b/src/globalcanvassettings.cpp new file mode 100644 index 0000000..4b4361e --- /dev/null +++ b/src/globalcanvassettings.cpp @@ -0,0 +1,37 @@ +#include + +glm::mat4 GlobalCanvasSettings::m_proj = glm::mat4(1.0f); +glm::mat4 GlobalCanvasSettings::m_view = glm::mat4(1.0f); +glm::mat4 GlobalCanvasSettings::m_proj_view = glm::mat4(1.0f); + +void GlobalCanvasSettings::setProjectionMatrix(const glm::mat4 &proj) +{ + GlobalCanvasSettings::m_proj = proj; + GlobalCanvasSettings::calculatePVMatrix(); +} + +void GlobalCanvasSettings::setViewMatrix(const glm::mat4 &view) +{ + GlobalCanvasSettings::m_view = view; + GlobalCanvasSettings::calculatePVMatrix(); +} + +const glm::mat4 &GlobalCanvasSettings::getViewMatrix() +{ + return GlobalCanvasSettings::m_view; +} + +const glm::mat4 &GlobalCanvasSettings::getProjectionMatrix() +{ + return GlobalCanvasSettings::m_proj; +} + +const glm::mat4 &GlobalCanvasSettings::getPVMatrix() +{ + return GlobalCanvasSettings::m_proj_view; +} + +void GlobalCanvasSettings::calculatePVMatrix() +{ + GlobalCanvasSettings::m_proj_view = GlobalCanvasSettings::m_proj * GlobalCanvasSettings::m_view; +} diff --git a/src/main.cpp b/src/main.cpp index d09d878..af18aab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -13,21 +14,31 @@ #define WINDOW_WIDTH 1200 #define WINDOW_HEIGHT 800 +unsigned char tex[4*10000] = {255}; + int main(int argc, char **argv) { (void)argc; (void)argv; SdlMainWindow *window; - SDL_Event event; bool run = true; - bool got_event = false; glm::mat4 view_matrix; glm::mat4 projection_matrix; - bool show_demo_window = true; + glm::vec4 color = glm::vec4(1.0f); + float y_rotation = 0.0f; + bool proj_ortho = true; float nav_point[2] = {0.0f, 0.0f}; float zoom = 1.0; + for (int i = 0; i < 10000; i++) { + tex[i*4] = 0xff; + tex[i*4+1] = 0x00; + tex[i*4+2] = 0x00; + tex[i*4+3] = 0xFF; + } + + window = new SdlMainWindow(WINDOW_HEIGHT, WINDOW_WIDTH); window->show(); @@ -43,10 +54,14 @@ int main(int argc, char **argv) "shaders/textured-rectangle-fragment.glsl"); projection_matrix = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 1.0f); - textured_rect_prog->setProjectionView(projection_matrix, glm::mat4(1.0f)); + GlobalCanvasSettings::setProjectionMatrix(projection_matrix); + GlobalCanvasSettings::setViewMatrix(glm::mat4(1.0f)); textured_rect_prog->compile(); - TexturedRectangle rect = TexturedRectangle(-1, -1, 1, 1, textured_rect_prog); + std::shared_ptr texture = std::make_shared(); + texture->setRGBDataFromBytes(100,100, (char*)tex); + + TexturedRectangle rect = TexturedRectangle(-3, -3, 3, 3, textured_rect_prog, texture); rect.realize(); // Setup Dear ImGui context @@ -70,6 +85,15 @@ int main(int argc, char **argv) SDL_Event event; while (SDL_PollEvent(&event)) { + if (event.type == SDL_MOUSEWHEEL) { + if (event.wheel.y > 0) { + zoom += 0.1; + } else { + zoom -= 0.1; + } + } + + ImGui_ImplSDL2_ProcessEvent(&event); if (event.type == SDL_QUIT) run = false; @@ -86,14 +110,37 @@ int main(int argc, char **argv) ImGui::NewFrame(); - view_matrix = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, zoom)); - view_matrix = glm::translate(view_matrix, glm::vec3(-nav_point[0], -nav_point[1], 0.0f)); + view_matrix = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, 1.0)); + view_matrix = glm::translate(view_matrix, glm::vec3(-nav_point[0], -nav_point[1], -10.0f)); + + GlobalCanvasSettings::setViewMatrix(view_matrix); - textured_rect_prog->setProjectionView(projection_matrix, view_matrix); rect.render(); + ImGui::Begin("Rectangle"); + ImGui::Text("Change the color of the rectangle below"); + ImGui::NewLine(); + ImGui::SliderFloat4("Rectangle Color", &color.r, 0.0f, 1.0f, "%.3f", 1.0f); + ImGui::Text("Rectangle Rotation:"); + ImGui::NewLine(); + ImGui::SliderAngle("Y Rotation", &y_rotation, -180.0f, +180.0f); + static int e = 0; + ImGui::RadioButton("Orthographic", &e, 0); ImGui::SameLine(); + ImGui::RadioButton("Perspective", &e, 1); - ImGui::ShowDemoWindow(&show_demo_window); + if(!e) { + GlobalCanvasSettings::setProjectionMatrix(glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 20.0f)); + } else { + + GlobalCanvasSettings::setProjectionMatrix(glm::perspective(glm::radians(120.0f), (float)1200/(float)800, 1.0f, 30.0f)); + } + + ImGui::End(); + + + glm::mat4 model_matrix = glm::rotate(glm::mat4(1.0f), y_rotation, glm::vec3(0.0f, 1.0f, 0.0f)); + rect.setModelMatrix(model_matrix); + rect.setBaseColor(color); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); diff --git a/src/openglshader.cpp b/src/openglshader.cpp index 6719bb3..0de026a 100644 --- a/src/openglshader.cpp +++ b/src/openglshader.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,7 +10,6 @@ OpenGlShaderProgram::OpenGlShaderProgram(std::string vertex_file, std::string ge this->geometry_file = geometry_file; this->fragment_file = fragment_file; this->compiled = false; - this->setProjectionView(glm::mat4(1.0f), glm::mat4(1.0f)); } OpenGlShaderProgram::~OpenGlShaderProgram() @@ -17,23 +17,6 @@ OpenGlShaderProgram::~OpenGlShaderProgram() this->unload(); } -void OpenGlShaderProgram::setProjectionView(const glm::mat4 &projection, const glm::mat4 &view) -{ - this->proj = projection; - this->view = view; - this->proj_view = projection * view; -} - -glm::mat4 OpenGlShaderProgram::getProjection() -{ - return this->proj; -} - -glm::mat4 OpenGlShaderProgram::getView() -{ - return this->view; -} - std::string load_shader_program_from_file(std::string &file_name) { std::ifstream ifs(file_name); @@ -172,7 +155,7 @@ int OpenGlShaderProgram::use() return -1; glUseProgram(this->shader_program); - this->setUniformMat4("projection_view_matrix", this->proj_view); + this->setUniformMat4("projection_view_matrix", GlobalCanvasSettings::getPVMatrix()); return 0; } @@ -185,6 +168,14 @@ void OpenGlShaderProgram::setUniformFloat(const std::string &uniform, float valu } } +void OpenGlShaderProgram::setUniformInt(const std::string &uniform, int value) +{ + int loc = this->getUniformLoc(uniform); + if (loc >= 0) { + glUniform1i(loc, value); + } +} + void OpenGlShaderProgram::setUniformVec2(const std::string &uniform, float *vector) { int loc = this->getUniformLoc(uniform); @@ -201,6 +192,14 @@ void OpenGlShaderProgram::setUniformMat4(const std::string &uniform, const glm:: } } +void OpenGlShaderProgram::setUniformVec4(const std::string &uniform, const glm::vec4 &vector) +{ + int loc = this->getUniformLoc(uniform); + if (loc >= 0) { + glUniform4fv(loc, 1, &vector.x); + } +} + int OpenGlShaderProgram::getUniformLoc(const std::string &uniform) { if (!this->compiled) diff --git a/src/opengltexture.cpp b/src/opengltexture.cpp index 69d6700..7645f46 100644 --- a/src/opengltexture.cpp +++ b/src/opengltexture.cpp @@ -10,19 +10,25 @@ OpenGlTexture::OpenGlTexture() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } -OpenGlTexture::OpenGlTexture(const OpenGlTexture &tex) -{ - this->texture = tex.texture; -} - -OpenGlTexture::OpenGlTexture(const OpenGlTexture &&tex) -{ - this->texture = tex.texture; -} - - - OpenGlTexture::~OpenGlTexture() { - + glDeleteTextures(1, &this->texture); +} + +void OpenGlTexture::setRGBDataFromBytes(unsigned int width, unsigned int height, char *buffer) +{ + this->use(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + glGenerateMipmap(GL_TEXTURE_2D); +} + +void OpenGlTexture::use(unsigned int slot) +{ + glActiveTexture(GL_TEXTURE0 + slot); + this->use(); +} + +void OpenGlTexture::use() +{ + glBindTexture(GL_TEXTURE_2D, this->texture); } diff --git a/src/sdlmainwindow.cpp b/src/sdlmainwindow.cpp index ae3587e..2f74503 100644 --- a/src/sdlmainwindow.cpp +++ b/src/sdlmainwindow.cpp @@ -1,4 +1,5 @@ #include +#include SdlMainWindow::SdlMainWindow(int height, int width) : MainWindow() { @@ -16,6 +17,7 @@ SdlMainWindow::~SdlMainWindow() void SdlMainWindow::show() { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16); this->window = SDL_CreateWindow("OpenGL Playground", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, this->width, this->height, SDL_WINDOW_OPENGL); return; @@ -38,6 +40,8 @@ void SdlMainWindow::activateGlContext() this->context = SDL_GL_CreateContext(this->window); else SDL_GL_MakeCurrent(this->window, this->context); + + glEnable(GL_MULTISAMPLE); } SDL_Window *SdlMainWindow::getWindow() diff --git a/src/textured-rectangle.cpp b/src/textured-rectangle.cpp index dce6464..bd57d98 100644 --- a/src/textured-rectangle.cpp +++ b/src/textured-rectangle.cpp @@ -2,7 +2,8 @@ #include #include -TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr shaderprog) : +TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr &shaderprog, + std::shared_ptr &texture) : OpenGlGraphics(shaderprog) { this->pos1[0] = x0; @@ -12,6 +13,8 @@ TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std this->setZoom(1.0f); this->setOffset(0.0f, 0.0f); this->vao = 0; + this->base_color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); + this->m_texture = texture; } void TexturedRectangle::realize() @@ -23,11 +26,11 @@ void TexturedRectangle::realize() 2, 0, 3 }; - float vertices[8] = { - this->pos1[0], this->pos1[1], - this->pos1[0], this->pos2[1], - this->pos2[0], this->pos2[1], - this->pos2[0], this->pos1[1], + float vertices[16] = { + this->pos1[0], this->pos1[1], 0.0f, 0.0f, + this->pos1[0], this->pos2[1], 0.0f, 1.0f, + this->pos2[0], this->pos2[1], 1.0f, 1.0f, + this->pos2[0], this->pos1[1], 1.0f, 0.0f, }; glGenVertexArrays(1, &this->vao); @@ -39,19 +42,23 @@ void TexturedRectangle::realize() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem_buff); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); + + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2*sizeof(float))); + glEnableVertexAttribArray(1); } void TexturedRectangle::render() { this->shaderprog->use(); - + this->shaderprog->setUniformVec4("base_color", this->base_color); this->shaderprog->setUniformMat4("model_matrix", this->model_matrix); + this->shaderprog->setUniformInt("uni_texture", 0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + this->m_texture->use(0UL); glBindVertexArray(this->vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - } void TexturedRectangle::setZoom(float zoom) @@ -82,6 +89,11 @@ float TexturedRectangle::getOffsetY() return this->y_offset; } +void TexturedRectangle::setBaseColor(const glm::vec4 &color) +{ + this->base_color = color; +} + void TexturedRectangle::calculateModelMatrix() { glm::mat4 moved_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(-this->x_offset, -this->y_offset, 0.0f));