#pragma once #include #include #include // 3 axis lines: X=red, Y=green, Z=blue // Each line: 2 vertices, each vertex has pos(3) + color(3) static const float AXIS_VERTICES[] = { // X axis - red 0.0f, 0.0f, 0.0f, 1.0f, 0.2f, 0.2f, 1.0f, 0.0f, 0.0f, 1.0f, 0.2f, 0.2f, // Y axis - green 0.0f, 0.0f, 0.0f, 0.2f, 1.0f, 0.2f, 0.0f, 1.0f, 0.0f, 0.2f, 1.0f, 0.2f, // Z axis - blue 0.0f, 0.0f, 0.0f, 0.2f, 0.4f, 1.0f, 0.0f, 0.0f, 1.0f, 0.2f, 0.4f, 1.0f, }; struct AxisRenderer { unsigned int VAO, VBO; unsigned int shader; }; static const char *AXIS_VERT_SRC = R"( #version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec3 aColor; out vec3 vColor; uniform mat4 uMVP; void main() { vColor = aColor; gl_Position = uMVP * vec4(aPos, 1.0); } )"; static const char *AXIS_FRAG_SRC = R"( #version 330 core in vec3 vColor; out vec4 FragColor; void main() { FragColor = vec4(vColor, 1.0); } )"; inline AxisRenderer axis_init() { AxisRenderer r; // Compile inline shaders int success; char log[512]; unsigned int vert = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vert, 1, &AXIS_VERT_SRC, NULL); glCompileShader(vert); glGetShaderiv(vert, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vert, 512, NULL, log); fprintf(stderr, "Axis vert: %s\n", log); } unsigned int frag = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(frag, 1, &AXIS_FRAG_SRC, NULL); glCompileShader(frag); glGetShaderiv(frag, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(frag, 512, NULL, log); fprintf(stderr, "Axis frag: %s\n", log); } r.shader = glCreateProgram(); glAttachShader(r.shader, vert); glAttachShader(r.shader, frag); glLinkProgram(r.shader); glDeleteShader(vert); glDeleteShader(frag); glGenVertexArrays(1, &r.VAO); glGenBuffers(1, &r.VBO); glBindVertexArray(r.VAO); glBindBuffer(GL_ARRAY_BUFFER, r.VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(AXIS_VERTICES), AXIS_VERTICES, GL_STATIC_DRAW); // pos glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); // color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(0); return r; } inline void axis_draw(const AxisRenderer &r, const glm::mat4 &mvp) { glUseProgram(r.shader); glUniformMatrix4fv(glGetUniformLocation(r.shader, "uMVP"), 1, GL_FALSE, glm::value_ptr(mvp)); glBindVertexArray(r.VAO); glLineWidth(2.0f); glDrawArrays(GL_LINES, 0, 6); glBindVertexArray(0); } inline void axis_destroy(AxisRenderer &r) { glDeleteVertexArrays(1, &r.VAO); glDeleteBuffers(1, &r.VBO); glDeleteProgram(r.shader); }