Draw a triangle to the screen

This commit is contained in:
Nathan Chapman 2025-07-01 09:25:56 -06:00
parent cc15bbab1f
commit 27452c30a5

View File

@ -1,12 +1,116 @@
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
// Window dimensions
const GLint WIDTH = 800, HEIGHT = 600;
// Vertex Shader
static const char *vertex_shader = " \n\
#version 330 \n\
\n\
layout (location = 0) in vec3 pos; \n\
\n\
void main() { \n\
gl_Position = vec4(pos.x, pos.y, pos.z, 1.0); \n\
}";
// Fragment shader
static const char *fragment_shader = " \n\
#version 330 \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
color = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
bool add_shader(GLuint *program, const char *shader_code, GLenum shader_type) {
GLuint shader = glCreateShader(shader_type);
const GLchar *code[1];
code[0] = shader_code;
GLint code_length[1];
code_length[0] = strlen(shader_code);
glShaderSource(shader, 1, code, code_length);
glCompileShader(shader);
GLint result = 0;
GLchar errors[1024] = { 0 };
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (!result) {
glGetShaderInfoLog(shader, sizeof(errors), NULL, errors);
printf("Error compiling the %d shader: '%s'\n", shader_type, errors);
return false;
}
glAttachShader(*program, shader);
return true;
}
bool compile_shaders(GLuint *shader_program) {
*shader_program = glCreateProgram();
if (!shader_program) {
printf("Error creating shader program!\n");
return false;
}
add_shader(shader_program, vertex_shader, GL_VERTEX_SHADER);
add_shader(shader_program, fragment_shader, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar errors[1024] = { 0 };
glLinkProgram(*shader_program);
glGetProgramiv(*shader_program, GL_LINK_STATUS, &result);
if (!result) {
glGetProgramInfoLog(*shader_program, sizeof(errors), NULL, errors);
printf("Error linking program: '%s'\n", errors);
return false;
}
glValidateProgram(*shader_program);
glGetProgramiv(*shader_program, GL_VALIDATE_STATUS, &result);
if (!result) {
glGetProgramInfoLog(*shader_program, sizeof(errors), NULL, errors);
printf("Error validating program: '%s'\n", errors);
return false;
}
return true;
}
void create_triangle(GLuint *VAO, GLuint *VBO) {
GLfloat vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, VAO);
glBindVertexArray(*VAO);
glGenBuffers(1, VBO);
glBindBuffer(GL_ARRAY_BUFFER, *VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int main() {
GLuint VAO, VBO, shader_program;
// Initialize GLFW
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
@ -19,7 +123,6 @@ int main() {
// Setup GLFW window properties
// OpenGL version
// @Reminder Look into making it work on Wayland
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
// Core profile means it will not be backwards compatible
@ -63,21 +166,33 @@ int main() {
// Setup viewport size
glViewport(0, 0, buffer_width, buffer_height);
// Create our triangle
create_triangle(&VAO, &VBO);
compile_shaders(&shader_program);
// Loop until window is closed
while (!glfwWindowShouldClose(window)) {
// Get and handle user input events
glfwPollEvents();
// Clear window
glClearColor(1.0f, 0.9f, 0.4f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// We usually have two buffers, the first is hidden and that's the one
// we draw to. The second is the one we display, so when we're done drawing
// we call this glfwSwapBuffers() to swap the buffers to show the one we've
// been drawing to so that it now shows. We then can start drawing on the
// other buffer.
glBindVertexArray(0);
glUseProgram(0);
// We usually have two buffers, the first is hidden and that's
// the one we draw to. The second is the one we display, so
// when we're done drawing we call this glfwSwapBuffers() to
// swap the buffers to show the one we've been drawing to so
// that it now shows. We then can start drawing on the other
// buffer.
glfwSwapBuffers(window);
}