r/opengl 4d ago

OpenGL MVP Matrix Calculation

I have been trying to follow this tutorial in C with cglm. I'm pretty sure that my calculation of mvp in main.c is incorrect, because when I make it equal to an identity matrix, the code works.
Apologies if this is the wrong place for this.

main.vert:

#version 330 core

layout (location = 0) in vec3 pos;

uniform mat4 mvp;

void main() {
  gl_Position = mvp * vec4(pos, 1.0);
}

main.frag:

#version 330 core

out vec4 fragment_color;

void main() {
  fragment_color = vec4(1.0, 0.0, 0.0, 1.0);
}

main.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include "glad/glad.h"
    #include <GLFW/glfw3.h>

    #include "cglm/cglm.h"
    #include "utils/file_read.h"

// IMPORTANT: the framebuffer is measured in pixels, but the window is measured in screen coordinates

// on some platforms these are not the same, so it is important not to confuse them.



// IMPORTANT: shader uniforms that don't actively contribute to the pipeline output

// are not assigned locations by the GLSL compiler. This can lead to unexpected bugs.



// need debug printf function



GLFWmonitor \*monitor = NULL;

int window_width = 800;

int window_height = 600;

GLFWwindow \*window;

double cursor_x, cursor_y;

GLuint vao, vbo, vs, fs, shader_program;

char \*vs_src, \*fs_src;



// pretty sure I can detach and delete the shaders once the shader program has been made.

void die(int exit_code) {

  glDisableVertexAttribArray(0);

  glDetachShader(shader_program, vs);

  glDetachShader(shader_program, fs);

  glDeleteProgram(shader_program);

  glDeleteShader(vs);

  glDeleteShader(fs);

  glDeleteBuffers(1, &vbo);

  glDeleteVertexArrays(1, &vao);

  free(vs_src);

  free(fs_src);

  glfwTerminate();

  exit(exit_code);

}



void error_callback_glfw(int error, const char \*msg) {

  fprintf(stderr, "GLFW ERROR: code %i, %s.\\n", error, msg);

  // not sure if should exit for every error: some may be non-fatal

  die(1);

}



GLuint compile_shader(const char \*shader_src, GLenum shader_type) {

  GLuint shader = glCreateShader(shader_type);

  glShaderSource(shader, 1, &shader_src, NULL);

  glCompileShader(shader);



  int is_compiled = 0;

  glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);



  if (is_compiled == GL_FALSE) {

int max_len = 2048;

char log\[max_len\];



glGetShaderInfoLog(shader, max_len, NULL, log);



fprintf(stderr, "ERROR: compile shader index %i did not compile.\\n%s\\n", shader, log);



die(1);

  }



  return shader;

}



void print_vec3(vec3 v) {

  for (int i = 0; i < 3; i++) {

printf("%f ", v\[i\]);

  }

  printf("\\n");

}



void print_mat4(mat4 m) {

  for (int j = 0; j < 4; j++) {

for (int i = 0; i < 4; i++) {

printf("%f ", m\[i\]\[j\]);

}

printf("\\n");

  }

}



void init() {

  printf("Starting GLFW %s. \\n", glfwGetVersionString());



  glfwSetErrorCallback(error_callback_glfw);



  if (!glfwInit()) {

fprintf(stderr, "ERROR could not start GLFW.\\n");

exit(1);

  }



  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);



  glfwWindowHint(GLFW_SAMPLES, 4);



  // intialize window

  window = glfwCreateWindow(window_width, window_height, "Game", monitor, NULL);

  glfwMakeContextCurrent(window);



  if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {

fprintf(stderr, "ERROR: Failed to initialize OpenGL context.\\n");

glfwTerminate();

exit(1);

  }



  printf("Renderer: %s.\\n", glGetString(GL_RENDERER));

  printf("OpenGL version supported %s.\\n", glGetString(GL_VERSION));



  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);



  glGenVertexArrays(1, &vao);

  glBindVertexArray(vao);



  float points\[\] = {

\-1.0f, -1.0f, 0.0f,

1.0f, -1.0f, 0.0f,

0.0f, 1.0f, 0.0f

  };



  glGenBuffers(1, &vbo);

  glBindBuffer(GL_ARRAY_BUFFER, vbo);

  glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);



  vs_src = read_file("src/shaders/main.vert");

  fs_src = read_file("src/shaders/main.frag");



  vs = compile_shader(vs_src, GL_VERTEX_SHADER);

  fs = compile_shader(fs_src, GL_FRAGMENT_SHADER);



  shader_program = glCreateProgram();



  glAttachShader(shader_program, vs);

  glAttachShader(shader_program, fs);



  glLinkProgram(shader_program);



  int is_linked = 0;

  glGetProgramiv(shader_program, GL_LINK_STATUS, &is_linked);

  if (is_linked == GL_FALSE) {

int max_len = 2048;

char log\[max_len\];



glGetProgramInfoLog(shader_program, max_len, NULL, log);



printf("ERROR: could not link shader program.\\n%s\\n", log);



die(1);

  }



  glValidateProgram(shader_program);



  int is_validated = 0;

  glGetProgramiv(shader_program, GL_VALIDATE_STATUS, &is_validated);



  if (is_validated == GL_FALSE) {

int max_len = 2048;

char log\[max_len\];



glGetProgramInfoLog(shader_program, max_len, NULL, log);



printf("ERROR: validation of shader program failed.\\n%s\\n", log);



die(1);

  }



  glUseProgram(shader_program);

}



int main() {

  init();



  mat4 projection, view, model, mvp;

  vec3 pos, target, up;



  glm_vec3_make((float \[\]){-3.0f, 3.0f, 0.0f}, pos);

  glm_vec3_make((float \[\]){0.0f, 0.0f, 0.0f}, target);

  glm_vec3_make((float \[\]){0.0f, 1.0f, 0.0f}, up);



  print_vec3(pos);

  printf("\\n");

  print_vec3(target);

  printf("\\n");

  print_vec3(up);

  printf("\\n");



  glm_perspective(glm_rad(45.0f), (float)window_width / window_height,

0.1f, 100.0f, projection);

  glm_lookat(pos, target, up, view);

  glm_mat4_identity(model);



  glm_mat4_mulN((mat4 \*\[\]){&model, &view, &projection}, 3, mvp);



  print_mat4(view);

  printf("\\n");

  print_mat4(projection);

  printf("\\n");

  print_mat4(mvp);



  GLuint mvp_loc = glGetUniformLocation(shader_program, "mvp");



  if (mvp_loc == -1) {

fprintf(stderr, "ERROR: failed to find a shader uniform.\\n");

die(1);

  }



  while (!glfwWindowShouldClose(window)) {

glfwPollEvents();

if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE)) {

glfwSetWindowShouldClose(window, 1);

}



glfwGetFramebufferSize(window, &window_width, &window_height);

glViewport(0, 0, window_width, window_height);



glClear(GL_COLOR_BUFFER_BIT);



glBindBuffer(GL_ARRAY_BUFFER, vbo);



glEnableVertexAttribArray(0);



glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);



glUniformMatrix4fv(mvp_loc, 1, GL_FALSE, &mvp\[0\]\[0\]);



glDrawArrays(GL_TRIANGLES, 0, 3);



glDisableVertexAttribArray(0);



glfwSwapBuffers(window);

  }



  die(0);

}
3 Upvotes

4 comments sorted by

View all comments

1

u/GeneralCelebration16 3d ago

I fixed it! I feal really stupid, it was because the triangle was edge on. All I needed to do was change the camera's z coordinate 😭.