Add perspective view

This commit is contained in:
Mario Hüttel 2020-03-23 17:26:32 +01:00
parent 4a7e0ac82a
commit 8238e94eea
12 changed files with 203 additions and 61 deletions

View File

@ -0,0 +1,21 @@
#ifndef GLOBALCANVASSETTINGS_H
#define GLOBALCANVASSETTINGS_H
#include <glm/glm.hpp>
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

View File

@ -9,21 +9,19 @@ class OpenGlShaderProgram
{ {
public: public:
OpenGlShaderProgram(std::string vertex_file, std::string geometry_file, std::string fragment_file); OpenGlShaderProgram(std::string vertex_file, std::string geometry_file, std::string fragment_file);
OpenGlShaderProgram(const OpenGlShaderProgram &) = delete;
OpenGlShaderProgram(const OpenGlShaderProgram &&) = delete;
~OpenGlShaderProgram(); ~OpenGlShaderProgram();
void setProjectionView(const glm::mat4 &projection, const glm::mat4 &view);
glm::mat4 getProjection();
glm::mat4 getView();
int compile(); int compile();
void unload(); void unload();
int use(); int use();
int getUniformLoc(const std::string &uniform); int getUniformLoc(const std::string &uniform);
void setUniformFloat(const std::string &uniform, float value); 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 setUniformVec2(const std::string &uniform, float *vector);
void setUniformMat4(const std::string &uniform, const glm::mat4 &matrix); void setUniformMat4(const std::string &uniform, const glm::mat4 &matrix);
void setUniformVec4(const std::string &uniform, const glm::vec4 &vector);
private: private:
glm::mat4 proj;
glm::mat4 view;
glm::mat4 proj_view;
bool compiled; bool compiled;
GLuint shader_program; GLuint shader_program;
std::string vertex_file; std::string vertex_file;

View File

@ -7,9 +7,12 @@ class OpenGlTexture
{ {
public: public:
OpenGlTexture(); OpenGlTexture();
OpenGlTexture(const OpenGlTexture &tex); OpenGlTexture(const OpenGlTexture &tex) = delete;
OpenGlTexture(const OpenGlTexture &&tex); OpenGlTexture(const OpenGlTexture &&tex) = delete;
~OpenGlTexture(); ~OpenGlTexture();
void setRGBDataFromBytes(unsigned int width, unsigned int height, char *buffer);
void use(unsigned int slot);
void use();
protected: protected:
GLuint texture; GLuint texture;

View File

@ -2,13 +2,15 @@
#define TEXTURED_RECTANGLE_H #define TEXTURED_RECTANGLE_H
#include <opengl-playground/openglgraphics.hpp> #include <opengl-playground/openglgraphics.hpp>
#include <opengl-playground/opengltexture.hpp>
#include <epoxy/gl.h> #include <epoxy/gl.h>
#include <memory> #include <memory>
class TexturedRectangle : OpenGlGraphics class TexturedRectangle : public OpenGlGraphics
{ {
public: public:
TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr<OpenGlShaderProgram> shaderprog); TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr<OpenGlShaderProgram> &shaderprog,
std::shared_ptr<OpenGlTexture> &texture);
void realize(); void realize();
void render(); void render();
void setZoom(float zoom); void setZoom(float zoom);
@ -16,8 +18,11 @@ class TexturedRectangle : OpenGlGraphics
void setOffset(float x_off, float y_off); void setOffset(float x_off, float y_off);
float getOffsetX(); float getOffsetX();
float getOffsetY(); float getOffsetY();
void setBaseColor(const glm::vec4 &color);
private: private:
std::shared_ptr<OpenGlTexture> m_texture;
void calculateModelMatrix(); void calculateModelMatrix();
glm::vec4 base_color;
float pos1[2]; float pos1[2];
float pos2[2]; float pos2[2];
float x_offset; float x_offset;

View File

@ -1,8 +1,13 @@
#version 330 core #version 330 core
out vec4 fragmentColor; out vec4 fragmentColor;
in vec2 textureCoord;
uniform vec4 base_color;
uniform sampler2D uni_texture;
void main() 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);
} }

View File

@ -1,10 +1,15 @@
#version 330 core #version 330 core
layout (location = 0) in vec2 inputVertex; layout (location = 0) in vec2 inputVertex;
layout (location = 1) in vec2 textureInputVertex;
out vec2 textureCoord;
uniform mat4 model_matrix; uniform mat4 model_matrix;
uniform mat4 projection_view_matrix; uniform mat4 projection_view_matrix;
void main() void main()
{ {
textureCoord = textureInputVertex;
gl_Position = projection_view_matrix * model_matrix * vec4(inputVertex.x , inputVertex.y, 0.0, 1.0); gl_Position = projection_view_matrix * model_matrix * vec4(inputVertex.x , inputVertex.y, 0.0, 1.0);
} }

View File

@ -0,0 +1,37 @@
#include <opengl-playground/globalcanvassettings.hpp>
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;
}

View File

@ -2,6 +2,7 @@
#include <opengl-playground/sdlmainwindow.hpp> #include <opengl-playground/sdlmainwindow.hpp>
#include <opengl-playground/openglshader.hpp> #include <opengl-playground/openglshader.hpp>
#include <opengl-playground/textured-rectangle.hpp> #include <opengl-playground/textured-rectangle.hpp>
#include <opengl-playground/globalcanvassettings.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@ -13,21 +14,31 @@
#define WINDOW_WIDTH 1200 #define WINDOW_WIDTH 1200
#define WINDOW_HEIGHT 800 #define WINDOW_HEIGHT 800
unsigned char tex[4*10000] = {255};
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
(void)argc; (void)argc;
(void)argv; (void)argv;
SdlMainWindow *window; SdlMainWindow *window;
SDL_Event event;
bool run = true; bool run = true;
bool got_event = false;
glm::mat4 view_matrix; glm::mat4 view_matrix;
glm::mat4 projection_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 nav_point[2] = {0.0f, 0.0f};
float zoom = 1.0; 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 = new SdlMainWindow(WINDOW_HEIGHT, WINDOW_WIDTH);
window->show(); window->show();
@ -43,10 +54,14 @@ int main(int argc, char **argv)
"shaders/textured-rectangle-fragment.glsl"); "shaders/textured-rectangle-fragment.glsl");
projection_matrix = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 1.0f); 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(); textured_rect_prog->compile();
TexturedRectangle rect = TexturedRectangle(-1, -1, 1, 1, textured_rect_prog); std::shared_ptr<OpenGlTexture> texture = std::make_shared<OpenGlTexture>();
texture->setRGBDataFromBytes(100,100, (char*)tex);
TexturedRectangle rect = TexturedRectangle(-3, -3, 3, 3, textured_rect_prog, texture);
rect.realize(); rect.realize();
// Setup Dear ImGui context // Setup Dear ImGui context
@ -70,6 +85,15 @@ int main(int argc, char **argv)
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&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); ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
run = false; run = false;
@ -86,14 +110,37 @@ int main(int argc, char **argv)
ImGui::NewFrame(); ImGui::NewFrame();
view_matrix = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, zoom)); 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], 0.0f)); 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(); 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::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

View File

@ -1,4 +1,5 @@
#include <opengl-playground/openglshader.hpp> #include <opengl-playground/openglshader.hpp>
#include <opengl-playground/globalcanvassettings.hpp>
#include <string.h> #include <string.h>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -9,7 +10,6 @@ OpenGlShaderProgram::OpenGlShaderProgram(std::string vertex_file, std::string ge
this->geometry_file = geometry_file; this->geometry_file = geometry_file;
this->fragment_file = fragment_file; this->fragment_file = fragment_file;
this->compiled = false; this->compiled = false;
this->setProjectionView(glm::mat4(1.0f), glm::mat4(1.0f));
} }
OpenGlShaderProgram::~OpenGlShaderProgram() OpenGlShaderProgram::~OpenGlShaderProgram()
@ -17,23 +17,6 @@ OpenGlShaderProgram::~OpenGlShaderProgram()
this->unload(); 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::string load_shader_program_from_file(std::string &file_name)
{ {
std::ifstream ifs(file_name); std::ifstream ifs(file_name);
@ -172,7 +155,7 @@ int OpenGlShaderProgram::use()
return -1; return -1;
glUseProgram(this->shader_program); glUseProgram(this->shader_program);
this->setUniformMat4("projection_view_matrix", this->proj_view); this->setUniformMat4("projection_view_matrix", GlobalCanvasSettings::getPVMatrix());
return 0; 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) void OpenGlShaderProgram::setUniformVec2(const std::string &uniform, float *vector)
{ {
int loc = this->getUniformLoc(uniform); 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) int OpenGlShaderProgram::getUniformLoc(const std::string &uniform)
{ {
if (!this->compiled) if (!this->compiled)

View File

@ -10,19 +10,25 @@ OpenGlTexture::OpenGlTexture()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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() 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);
} }

View File

@ -1,4 +1,5 @@
#include <opengl-playground/sdlmainwindow.hpp> #include <opengl-playground/sdlmainwindow.hpp>
#include <epoxy/gl.h>
SdlMainWindow::SdlMainWindow(int height, int width) : MainWindow() SdlMainWindow::SdlMainWindow(int height, int width) : MainWindow()
{ {
@ -16,6 +17,7 @@ SdlMainWindow::~SdlMainWindow()
void SdlMainWindow::show() void SdlMainWindow::show()
{ {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16);
this->window = SDL_CreateWindow("OpenGL Playground", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, this->window = SDL_CreateWindow("OpenGL Playground", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
this->width, this->height, SDL_WINDOW_OPENGL); this->width, this->height, SDL_WINDOW_OPENGL);
return; return;
@ -38,6 +40,8 @@ void SdlMainWindow::activateGlContext()
this->context = SDL_GL_CreateContext(this->window); this->context = SDL_GL_CreateContext(this->window);
else else
SDL_GL_MakeCurrent(this->window, this->context); SDL_GL_MakeCurrent(this->window, this->context);
glEnable(GL_MULTISAMPLE);
} }
SDL_Window *SdlMainWindow::getWindow() SDL_Window *SdlMainWindow::getWindow()

View File

@ -2,7 +2,8 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr<OpenGlShaderProgram> shaderprog) : TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std::shared_ptr<OpenGlShaderProgram> &shaderprog,
std::shared_ptr<OpenGlTexture> &texture) :
OpenGlGraphics(shaderprog) OpenGlGraphics(shaderprog)
{ {
this->pos1[0] = x0; this->pos1[0] = x0;
@ -12,6 +13,8 @@ TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, std
this->setZoom(1.0f); this->setZoom(1.0f);
this->setOffset(0.0f, 0.0f); this->setOffset(0.0f, 0.0f);
this->vao = 0; this->vao = 0;
this->base_color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
this->m_texture = texture;
} }
void TexturedRectangle::realize() void TexturedRectangle::realize()
@ -23,11 +26,11 @@ void TexturedRectangle::realize()
2, 0, 3 2, 0, 3
}; };
float vertices[8] = { float vertices[16] = {
this->pos1[0], this->pos1[1], this->pos1[0], this->pos1[1], 0.0f, 0.0f,
this->pos1[0], this->pos2[1], this->pos1[0], this->pos2[1], 0.0f, 1.0f,
this->pos2[0], this->pos2[1], this->pos2[0], this->pos2[1], 1.0f, 1.0f,
this->pos2[0], this->pos1[1], this->pos2[0], this->pos1[1], 1.0f, 0.0f,
}; };
glGenVertexArrays(1, &this->vao); glGenVertexArrays(1, &this->vao);
@ -39,19 +42,23 @@ void TexturedRectangle::realize()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem_buff); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem_buff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 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); glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2*sizeof(float)));
glEnableVertexAttribArray(1);
} }
void TexturedRectangle::render() void TexturedRectangle::render()
{ {
this->shaderprog->use(); this->shaderprog->use();
this->shaderprog->setUniformVec4("base_color", this->base_color);
this->shaderprog->setUniformMat4("model_matrix", this->model_matrix); this->shaderprog->setUniformMat4("model_matrix", this->model_matrix);
this->shaderprog->setUniformInt("uni_texture", 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
this->m_texture->use(0UL);
glBindVertexArray(this->vao); glBindVertexArray(this->vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
} }
void TexturedRectangle::setZoom(float zoom) void TexturedRectangle::setZoom(float zoom)
@ -82,6 +89,11 @@ float TexturedRectangle::getOffsetY()
return this->y_offset; return this->y_offset;
} }
void TexturedRectangle::setBaseColor(const glm::vec4 &color)
{
this->base_color = color;
}
void TexturedRectangle::calculateModelMatrix() void TexturedRectangle::calculateModelMatrix()
{ {
glm::mat4 moved_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(-this->x_offset, -this->y_offset, 0.0f)); glm::mat4 moved_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(-this->x_offset, -this->y_offset, 0.0f));