diff options
author | ccolin | 2020-12-22 13:15:23 +0100 |
---|---|---|
committer | ccolin | 2020-12-22 13:15:23 +0100 |
commit | 7fbe0814d52ba861a02b0560d4e6872845ef241e (patch) | |
tree | 1a8f6fd67b5d1606a58c0df00fbab285f1206d36 /src/opengl_widget.cc |
initial commit
Diffstat (limited to 'src/opengl_widget.cc')
-rw-r--r-- | src/opengl_widget.cc | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/opengl_widget.cc b/src/opengl_widget.cc new file mode 100644 index 0000000..0251491 --- /dev/null +++ b/src/opengl_widget.cc @@ -0,0 +1,143 @@ +#include "opengl_widget.hh" + + +static const GLchar *vertex_shader_source = R"glsl( +#version 330 core + +layout(location = 0) in vec3 pos; + +uniform mat4 proj; +uniform mat4 view; +uniform mat4 model; + +void main() { + gl_Position = proj * view * model * vec4(pos, 1.0); +} +)glsl"; + +static const GLchar *fragment_shader_source = R"glsl( +#version 330 core + +out vec4 final_col; + +void main() { + final_col = vec4(0, 0, 0, 1); +} +)glsl"; + + +static void GLAPIENTRY opengl_debug_cb(GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, + const GLchar* message, + const void* userParam) { + (void) source; (void) type; (void) id; (void) severity; (void) length; + (void) userParam; + qDebug() << "OpenGL debug output:" << message; +} + + +OpenGLWidget *OpenGLWidget::instance = nullptr; + + +OpenGLWidget::OpenGLWidget(QWidget *parent) + :QOpenGLWidget(parent) { + OpenGLWidget::instance = this; +} + + +OpenGLWidget::~OpenGLWidget() { + OpenGLWidget::instance = nullptr; +} + + +void OpenGLWidget::initializeGL() { + initializeOpenGLFunctions(); + GLint major, minor; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + qDebug("OpenGL version %d.%d", major, minor); + + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(opengl_debug_cb, 0); + + /* Compile the vertex shader. */ + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); + glCompileShader(vertex_shader); + GLint status; + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetShaderInfoLog(vertex_shader, sizeof log, NULL, log); + fprintf(stderr, "Failed to compile the vertex shader: %s\n", log); + exit(1); + } + + /* Compile the fragment shader. */ + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); + glCompileShader(fragment_shader); + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetShaderInfoLog(fragment_shader, sizeof log, NULL, log); + fprintf(stderr, "Failed to compile the fragment shader: %s\n", log); + exit(1); + } + + /* Link the shader program. */ + GLuint shader_program = glCreateProgram(); + glAttachShader(shader_program, vertex_shader); + glAttachShader(shader_program, fragment_shader); + glBindFragDataLocation(shader_program, 0, "out_color"); + glLinkProgram(shader_program); + glGetProgramiv(shader_program, GL_LINK_STATUS, &status); + if (status != GL_TRUE) { + char log[1024]; + glGetProgramInfoLog(shader_program, sizeof log, NULL, log); + fprintf(stderr, "Failed to link the shader program: %s\n", log); + exit(1); + } + + /* Use it. */ + glUseProgram(shader_program); + + /* Get the position attribute. */ + pos_attr = glGetAttribLocation(shader_program, "pos"); + + proj_attr = glGetUniformLocation(shader_program, "proj"); + view_attr = glGetUniformLocation(shader_program, "view"); + model_attr = glGetUniformLocation(shader_program, "model"); + + QMatrix4x4 view; + view.translate(0, 0, 5); + glUniformMatrix4fv(view_attr, 1, GL_FALSE, view.data()); + + QMatrix4x4 trans; + trans.translate(0, 0, -5); + glUniformMatrix4fv(view_attr, 1, GL_FALSE, trans.data()); + + glClearColor(1, 1, 1, 0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + emit initialized(); +} + + +void OpenGLWidget::resizeGL(int w, int h) { + QMatrix4x4 projection; + projection.perspective(FOV, (float) w/h, .1, 100); + glUniformMatrix4fv(proj_attr, 1, GL_FALSE, projection.data()); +} + + +void OpenGLWidget::paintGL() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + for (const OpenGLMesh &mesh : meshes) { + glUniformMatrix4fv(model_attr, 1, GL_FALSE, mesh.mat.data()); + glBindVertexArray(mesh.vao); + glDrawArrays(GL_TRIANGLES, 0, mesh.nverts); + } +} |