rectangle render

This commit is contained in:
2025-11-24 09:22:10 +00:00
parent a17b76f366
commit a786d26dde
5 changed files with 223 additions and 1 deletions

25
inc/engine/shader.hpp Normal file
View File

@@ -0,0 +1,25 @@
#ifndef SHADER_HPP
#define SHADER_HPP
#define GL_GLEXT_PROTOTYPES
// Includes
#include <SDL3/SDL_opengl.h>
#include <glm/glm.hpp>
#include <string>
// Shader class
class Shader {
public:
unsigned int ID;
Shader(const char* vertexPath, const char* fragmentPath);
void use() const;
void setBool(const std::string &name, bool value) const;
void setInt(const std::string &name, int value) const;
void setFloat(const std::string &name, float value) const;
void setMat4(const std::string &name, const glm::mat4 &mat) const;
~Shader();
private:
const char* read_file(const char* filePath);
};
#endif

8
shaders/triangle.frag Normal file
View File

@@ -0,0 +1,8 @@
#version 330 core
out vec4 FragColor;
in vec3 color; // Input color from the vertex shader
void main() {
FragColor = vec4(color, 1.0); // Apply the color directly
}

13
shaders/triangle.vert Normal file
View File

@@ -0,0 +1,13 @@
#version 330 core
layout(location = 0) in vec3 position; // Vertex position
out vec3 color; // Output color to the fragment shader
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices
color = position + vec3(0.5); // Set the color based on the vertex position
}

114
src/engine/shader.cpp Normal file
View File

@@ -0,0 +1,114 @@
#include "engine/shader.hpp"
#include <iostream>
#include <fstream>
#include <SDL3/SDL_log.h>
Shader::Shader(const char* vertexPath, const char* fragmentPath) {
// Load and compile vertex shader
unsigned int shader = glCreateShader(GL_VERTEX_SHADER);
if (shader == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create shader.");
}
const char* vertex_shader_source = read_file(vertexPath);
glShaderSource(shader, 1, &vertex_shader_source, nullptr);
glCompileShader(shader);
// Check for vertex shader compilation errors
int success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char info_log[512];
glGetShaderInfoLog(shader, sizeof(info_log), nullptr, info_log);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vertex shader compilation error: %s", info_log);
glDeleteShader(shader);
}
// Load and compile fragment shader
unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
if (fragment_shader == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create shader.");
}
const char* fragment_shader_source = read_file(fragmentPath);
glShaderSource(fragment_shader, 1, &fragment_shader_source, nullptr);
glCompileShader(fragment_shader);
// Check for fragment shader compilation errors
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
char info_log[512];
glGetShaderInfoLog(fragment_shader, sizeof(info_log), nullptr, info_log);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Fragment shader compilation error: %s", info_log);
glDeleteShader(fragment_shader);
}
// Create shader program
ID = glCreateProgram();
if (ID == 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create shader program.");
}
glAttachShader(ID, shader);
glAttachShader(ID, fragment_shader);
glLinkProgram(ID);
// Check for linking errors
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success) {
char info_log[512];
glGetProgramInfoLog(ID, sizeof(info_log), nullptr, info_log);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Shader program linking error: %s", info_log);
glDeleteProgram(ID);
ID = 0; // Reset ID to indicate failure
}
// Clean up shaders as they are no longer needed
glDeleteShader(shader);
glDeleteShader(fragment_shader);
}
void Shader::use() const {
if (ID != 0) {
glUseProgram(ID);
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Shader program not initialized.");
}
}
void Shader::setBool(const std::string &name, bool value) const {
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
void Shader::setInt(const std::string &name, int value) const {
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const std::string &name, float value) const {
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setMat4(const std::string &name, const glm::mat4 &mat) const {
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
Shader::~Shader() {
if (ID != 0) {
glDeleteProgram(ID);
ID = 0; // Reset ID to indicate the shader program has been deleted
}
}
const char* Shader::read_file(const char* filePath) {
std::ifstream file(filePath);
if (!file.is_open()) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open shader file: %s", filePath);
return "";
}
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
char* buffer = new char[content.size() + 1];
std::copy(content.begin(), content.end(), buffer);
buffer[content.size()] = '\0';
return buffer;
}

View File

@@ -1,5 +1,10 @@
#define GL_GLEXT_PROTOTYPES
#include "engine/sdl.hpp"
#include "engine/opengl.hpp"
#include "engine/shader.hpp"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
int main(int argc, char* argv[]) {
SDLWindow window("My SDL Application", 800, 600);
@@ -7,11 +12,68 @@ int main(int argc, char* argv[]) {
OpenGLContext glContext(window);
if (!glContext.isInitialized()) { return -1; }
glm::mat4 viewMatrix = glm::lookAt(
glm::vec3(0.0f, 0.0f, 3.0f), // Camera position
glm::vec3(0.0f, 0.0f, 0.0f), // Look at point
glm::vec3(0.0f, 1.0f, 0.0f) // Up vector
); // View matrix
glm::mat4 projectionMatrix = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f); // Projection matrix
glm::mat4 modelMatrix = glm::mat4(1.0f); // Model matrix
Shader shader_program("shaders/triangle.vert", "shaders/triangle.frag");
// test setup
float vertexData[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
};
unsigned int indexData[] = {
0, 1, 2, // first triangle
1, 3, 2 // second triangle
};
unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
window.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
window.showWindow();
while (window.isRunning()) {
window.pollEvents();
// Application logic and rendering would go here
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader_program.use();
shader_program.setMat4("view", viewMatrix);
shader_program.setMat4("projection", projectionMatrix);
shader_program.setMat4("model", modelMatrix);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glContext.swapBuffers();
}