aboutsummaryrefslogtreecommitdiff
path: root/src/opengl_widget.cc
diff options
context:
space:
mode:
authorccolin2020-12-22 13:15:23 +0100
committerccolin2020-12-22 13:15:23 +0100
commit7fbe0814d52ba861a02b0560d4e6872845ef241e (patch)
tree1a8f6fd67b5d1606a58c0df00fbab285f1206d36 /src/opengl_widget.cc
initial commit
Diffstat (limited to 'src/opengl_widget.cc')
-rw-r--r--src/opengl_widget.cc143
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);
+ }
+}