Add small example

This commit is contained in:
Mario Hüttel 2020-03-18 22:42:04 +01:00
parent d15fb54804
commit b50cb62ac3
16 changed files with 386 additions and 23 deletions

View File

@ -11,10 +11,20 @@ pkg_check_modules(SDL2 REQUIRED sdl2)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" ${EPOXY_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
configure_file("shaders/2d-passthrough-vertex.glsl" "shaders/2d-passthrough-vertex.glsl" COPYONLY)
configure_file("shaders/fixed-red-fragment.glsl" "shaders/fixed-red-fragment.glsl" COPYONLY)
configure_file("shaders/triangle-gen-geometry.glsl" "shaders/triangle-gen-geometry.glsl" COPYONLY)
configure_file("shaders/triangle-gen-zoomed-geometry.glsl" "shaders/triangle-gen-zoomed-geometry.glsl" COPYONLY)
configure_file("shaders/textured-rectangle-vertex.glsl" "shaders/textured-rectangle-vertex.glsl" COPYONLY)
configure_file("shaders/textured-rectangle-fragment.glsl" "shaders/textured-rectangle-fragment.glsl" COPYONLY)
configure_file("shaders/2d-zoom-translate-vertex.glsl" "shaders/2d-zoom-translate-vertex.glsl" COPYONLY)
aux_source_directory("src" SOURCES)
add_compile_options(-Wall)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} m pthread ${EPOXY_LIBRARIES} ${SDL2_LIBRARIES})
install (TARGETS ${PROJECT_NAME} DESTINATION bin)

View File

@ -0,0 +1,19 @@
#ifndef OPENGLGRAPHICS_H
#define OPENGLGRAPHICS_H
#include <string>
#include <epoxy/gl.h>
#include <opengl-playground/openglshader.hpp>
class OpenGlGraphics
{
public:
OpenGlGraphics(OpenGlShaderProgram &prog);
~OpenGlGraphics();
virtual void realize() = 0;
virtual void render() = 0;
protected:
OpenGlShaderProgram shaderprog;
};
#endif // OPENGLGRAPHICS_H

View File

@ -12,6 +12,9 @@ class OpenGlShaderProgram
int compile();
void unload();
int use();
int getUniformLoc(const std::string &uniform);
void setUniformFloat(const std::string &uniform, float value);
void setUniformVec2(const std::string &uniform, float *vector);
private:
bool compiled;
GLuint shader_program;

View File

@ -0,0 +1,27 @@
#ifndef TEXTURED_RECTANGLE_H
#define TEXTURED_RECTANGLE_H
#include <opengl-playground/openglgraphics.hpp>
#include <epoxy/gl.h>
class TexturedRectangle : OpenGlGraphics
{
public:
TexturedRectangle(float x0, float y0, float x1, float y1, OpenGlShaderProgram &shaderprog);
void realize();
void render();
void setZoom(float zoom);
float getZoom();
void setOffset(float x_off, float y_off);
float getOffsetX();
float getOffsetY();
private:
float pos1[2];
float pos2[2];
float x_offset;
float y_offset;
float zoom;
GLuint vao;
};
#endif // TEXTURED_RECTANGLE_H

View File

@ -0,0 +1,8 @@
#version 330 core
layout (location = 0) in vec2 inputVertex;
void main()
{
gl_Position = vec4(inputVertex.x, inputVertex.y, 0.0, 1.0);
}

View File

@ -0,0 +1,11 @@
#version 330 core
layout (location = 0) in vec2 inputVertex;
uniform float zoom;
uniform vec2 center_pos;
void main()
{
vec4 translated = (vec4(inputVertex.x, inputVertex.y, 0.0, 1.0) - vec4(center_pos.x, center_pos.y, 0.0, 0.0));
gl_Position = vec4(translated.x, translated.y, translated.z, translated.w) * vec4(zoom, zoom, 1, 1);
}

View File

@ -0,0 +1,8 @@
#version 330 core
out vec4 fragmentColor;
void main()
{
fragmentColor = vec4(1.0, 0.0, 0.0, 0.0);
}

View File

@ -0,0 +1,8 @@
#version 330 core
out vec4 fragmentColor;
void main()
{
fragmentColor = vec4(1.0, 0.0, 0.0, 0.0);
}

View File

@ -0,0 +1,11 @@
#version 330 core
layout (location = 0) in vec2 inputVertex;
uniform float zoom;
uniform vec2 pos_offset;
void main()
{
vec2 pos2d = (inputVertex - pos_offset) * zoom;
gl_Position = vec4(pos2d.x , pos2d.y, 0.0, 1.0);
}

View File

@ -0,0 +1,15 @@
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices=3) out;
void main()
{
gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0);
EmitVertex();
EndPrimitive();
}

View File

@ -0,0 +1,17 @@
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices=3) out;
uniform float zoom;
void main()
{
gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0) * zoom;
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.1, 0.0, 0.0) * zoom;
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.0, 0.0, 0.0) * zoom;
EmitVertex();
EndPrimitive();
}

View File

@ -1,6 +1,7 @@
#include <iostream>
#include <iostream>
#include <opengl-playground/sdlmainwindow.hpp>
#include <epoxy/gl.h>
#include <opengl-playground/openglshader.hpp>
#include <opengl-playground/textured-rectangle.hpp>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 640
@ -10,8 +11,26 @@ int main(int argc, char **argv)
(void)argc;
(void)argv;
MainWindow *window;
GLuint triangle_vao;
GLuint triangle_vbo;
SDL_Event event;
bool run = true;
bool got_event = false;
window = new SdlMainWindow(WINDOW_WIDTH, WINDOW_HEIGHT);
float nav_point[2] = {0.0f, 0.0f};
float zoom = 1.0;
float triangle_vertices[] = { -0.5f, 0.0f,
0.0f, 0.5f,
0.0f, 0.0f,
0.8f, 0.0f,
0.8f, 0.5f,
0.5f, 0.2f,
};
window = new SdlMainWindow(WINDOW_HEIGHT, WINDOW_WIDTH);
window->show();
window->activateGlContext();
@ -21,9 +40,73 @@ int main(int argc, char **argv)
glClearColor(0.1f, 0.1f, 0.1f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
glGenVertexArrays(1, &triangle_vao);
glBindVertexArray(triangle_vao);
glGenBuffers(1, &triangle_vbo);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
OpenGlShaderProgram prog = OpenGlShaderProgram("shaders/2d-zoom-translate-vertex.glsl", "shaders/triangle-gen-zoomed-geometry.glsl", "shaders/fixed-red-fragment.glsl");
prog.compile();
OpenGlShaderProgram textured_rect_prog = OpenGlShaderProgram("shaders/textured-rectangle-vertex.glsl", "", "shaders/textured-rectangle-fragment.glsl");
textured_rect_prog.compile();
TexturedRectangle rect = TexturedRectangle(-0.1, -0.1, 0.1, 0.1, textured_rect_prog);
rect.realize();
while (run) {
glClear(GL_COLOR_BUFFER_BIT);
// Draw the triangles
prog.use();
prog.setUniformFloat("zoom", zoom);
prog.setUniformVec2("center_pos", nav_point);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindVertexArray(triangle_vao);
glDrawArrays(GL_POINTS, 0, sizeof(triangle_vertices)/2);
rect.setZoom(zoom);
rect.setOffset(nav_point[0], nav_point[1]);
rect.render();
window->swapBuffer();
got_event = false;
SDL_Delay(5000);
while (!got_event) {
if (SDL_WaitEvent(&event)) {
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_w) {
nav_point[1] += 0.05;
} else if (event.key.keysym.sym == SDLK_s) {
nav_point[1] -= 0.05;
} else if (event.key.keysym.sym == SDLK_a) {
nav_point[0] -= 0.05;
} else if (event.key.keysym.sym == SDLK_d) {
nav_point[0] += 0.05;
} else if (event.key.keysym.sym == SDLK_ESCAPE) {
std::cout << "Bye!" << std::endl;
run = false;
} else if (event.key.keysym.sym == SDLK_PLUS) {
zoom += 0.01f;
} else if (event.key.keysym.sym == SDLK_MINUS) {
zoom -= 0.01f;
if (zoom < 0.0f)
zoom = 0.0f;
}
got_event = true;
}
}
}
}
textured_rect_prog.unload();
prog.unload();
delete window;
}

13
src/openglgraphics.cpp Normal file
View File

@ -0,0 +1,13 @@
#include <opengl-playground/openglgraphics.hpp>
OpenGlGraphics::OpenGlGraphics(OpenGlShaderProgram &prog) : shaderprog(prog)
{
}
OpenGlGraphics::~OpenGlGraphics()
{
}

View File

@ -1,4 +1,7 @@
#include <opengl-playground/openglshader.hpp>
#include <string.h>
#include <fstream>
#include <iostream>
OpenGlShaderProgram::OpenGlShaderProgram(std::string vertex_file, std::string geometry_file, std::string fragment_file)
{
@ -10,12 +13,16 @@ OpenGlShaderProgram::OpenGlShaderProgram(std::string vertex_file, std::string ge
OpenGlShaderProgram::~OpenGlShaderProgram()
{
this->unload();
}
char *load_shader_program_from_file(std::string file_name)
std::string load_shader_program_from_file(std::string &file_name)
{
return NULL;
std::ifstream ifs(file_name);
std::string file_content((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
return file_content;
}
int OpenGlShaderProgram::compile()
@ -25,7 +32,8 @@ int OpenGlShaderProgram::compile()
char info_log[512];
unsigned int vertex_shader, geometry_shader, fragment_shader;
bool vertex_b = false, geo_b = false, frag_b = false;
char *src_code;
std::string src_code;
const char *c_string;
if (this->compiled) {
glDeleteProgram(shader_program);
@ -37,32 +45,37 @@ int OpenGlShaderProgram::compile()
if (!vertex_file.empty()) {
vertex_b = true;
src_code = load_shader_program_from_file(this->vertex_file);
c_string = src_code.c_str();
/* Compile the vertex shader */
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &src_code, NULL);
glShaderSource(vertex_shader, 1, &c_string, NULL);
glCompileShader(vertex_shader);
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
free(src_code);
if (!success) {
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
fprintf(stderr, "%s\n", info_log);
printf("Error in vertex shader: %s\n", info_log);
ret_code = -1;
goto delete_vertex;
}
glAttachShader(this->shader_program, vertex_shader);
}
} else
printf("Empty\n");
if (!this->geometry_file.empty()) {
geo_b = true;
/* Compile the vertex shader */
geometry_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(geometry_shader, 1, &src_code, NULL);
src_code = load_shader_program_from_file(this->geometry_file);
c_string = src_code.c_str();
/* Compile the vertex shader */
geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geometry_shader, 1, &c_string, NULL);
glCompileShader(geometry_shader);
glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &success);
free(src_code);
if (!success) {
glGetShaderInfoLog(geometry_shader, 512, NULL, info_log);
@ -78,12 +91,14 @@ int OpenGlShaderProgram::compile()
if (!this->fragment_file.empty()) {
frag_b = true;
/* Compile the vertex shader */
fragment_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(fragment_shader, 1, &src_code, NULL);
src_code = load_shader_program_from_file(this->fragment_file);
c_string = src_code.c_str();
/* Compile the vertex shader */
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &c_string, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
free(src_code);
if (!success) {
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
@ -141,3 +156,27 @@ int OpenGlShaderProgram::use()
glUseProgram(this->shader_program);
return 0;
}
void OpenGlShaderProgram::setUniformFloat(const std::string &uniform, float value)
{
int loc = this->getUniformLoc(uniform);
if (loc >= 0) {
glUniform1f(loc, value);
}
}
void OpenGlShaderProgram::setUniformVec2(const std::string &uniform, float *vector)
{
int loc = this->getUniformLoc(uniform);
if (loc >= 0) {
glUniform2fv(loc, 1, vector);
}
}
int OpenGlShaderProgram::getUniformLoc(const std::string &uniform)
{
if (!this->compiled)
return -1;
return glGetUniformLocation(this->shader_program, uniform.c_str());
}

View File

@ -29,6 +29,11 @@ void SdlMainWindow::swapBuffer()
void SdlMainWindow::activateGlContext()
{
// OPENGL VERSION
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
if (this->context == NULL)
this->context = SDL_GL_CreateContext(this->window);
else

View File

@ -0,0 +1,86 @@
#include <opengl-playground/textured-rectangle.hpp>
TexturedRectangle::TexturedRectangle(float x0, float y0, float x1, float y1, OpenGlShaderProgram &shaderprog) :
OpenGlGraphics(shaderprog)
{
this->pos1[0] = x0;
this->pos1[1] = y0;
this->pos2[0] = x1;
this->pos2[1] = y1;
this->setZoom(1.0f);
this->setOffset(0.0f, 0.0f);
this->vao = 0;
}
void TexturedRectangle::realize()
{
GLuint vbo;
GLuint elem_buff;
const unsigned int indices[] = {
0, 1, 2,
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],
};
glGenVertexArrays(1, &this->vao);
glBindVertexArray(this->vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &elem_buff);
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);
glEnableVertexAttribArray(0);
}
void TexturedRectangle::render()
{
float offset[2];
this->shaderprog.use();
offset[0] = this->getOffsetX();
offset[1] = this->getOffsetY();
this->shaderprog.setUniformVec2("pos_offset", offset);
this->shaderprog.setUniformFloat("zoom", this->zoom);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindVertexArray(this->vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
void TexturedRectangle::setZoom(float zoom)
{
this->zoom = zoom;
}
float TexturedRectangle::getZoom()
{
return this->zoom;
}
void TexturedRectangle::setOffset(float x_off, float y_off)
{
this->x_offset = x_off;
this->y_offset = y_off;
}
float TexturedRectangle::getOffsetX()
{
return this->x_offset;
}
float TexturedRectangle::getOffsetY()
{
return this->y_offset;
}