sent from android
This commit is contained in:
parent
15aa9d54ea
commit
a03c7c85b8
BIN
assets/crate.jpg
Normal file
BIN
assets/crate.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
38
assets/cube.obj
Normal file
38
assets/cube.obj
Normal file
@ -0,0 +1,38 @@
|
||||
# Blender 4.5.0
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.125000 0.750000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.875000 0.750000
|
||||
s 0
|
||||
f 2/1 3/2 1/3
|
||||
f 4/4 7/5 3/2
|
||||
f 8/6 5/7 7/5
|
||||
f 6/8 1/9 5/7
|
||||
f 7/5 1/10 3/11
|
||||
f 4/12 6/8 8/6
|
||||
f 2/1 4/4 3/2
|
||||
f 4/4 8/6 7/5
|
||||
f 8/6 6/8 5/7
|
||||
f 6/8 2/13 1/9
|
||||
f 7/5 5/7 1/10
|
||||
f 4/12 2/14 6/8
|
BIN
assets/meow.png
Normal file
BIN
assets/meow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 169 KiB |
1479
assets/monkey.obj
Normal file
1479
assets/monkey.obj
Normal file
File diff suppressed because it is too large
Load Diff
45
include/geometry.hpp
Normal file
45
include/geometry.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef GEOMETRY_HPP
|
||||
#define GEOMETRY_HPP
|
||||
|
||||
// Includes
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "graphics.hpp"
|
||||
|
||||
// Object class
|
||||
class Object {
|
||||
public:
|
||||
Object(
|
||||
float *vertices, unsigned int vertex_size,
|
||||
unsigned int *indices, unsigned int index_size,
|
||||
float *normals = nullptr, unsigned int normal_size = 0,
|
||||
float *texcoords = nullptr, unsigned int texcoord_size = 0
|
||||
);
|
||||
~Object();
|
||||
void draw();
|
||||
|
||||
private:
|
||||
unsigned int VAO, VBO, EBO, NBO, TBO; // Vertex Array Object, Vertex Buffer Object, Element Buffer Object, Normal Buffer Object, Texture Buffer Object
|
||||
unsigned int vertex_count;
|
||||
unsigned int index_count;
|
||||
};
|
||||
|
||||
class UntexturedObject {
|
||||
public:
|
||||
UntexturedObject(
|
||||
float *vertices, unsigned int vertex_size,
|
||||
unsigned int *indices, unsigned int index_size,
|
||||
float *normals = nullptr, unsigned int normal_size = 0,
|
||||
float *texcoords = nullptr, unsigned int texcoord_size = 0
|
||||
);
|
||||
~UntexturedObject();
|
||||
void draw();
|
||||
|
||||
private:
|
||||
unsigned int VAO, VBO, EBO, NBO, TBO; // Vertex Array Object, Vertex Buffer Object, Element Buffer Object, Normal Buffer Object, Texture Buffer Object
|
||||
unsigned int vertex_count;
|
||||
unsigned int index_count;
|
||||
};
|
||||
|
||||
#endif
|
@ -3,11 +3,11 @@
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
// Includes
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
#include "window.hpp"
|
||||
#include "shader.hpp"
|
||||
#include "texture.hpp"
|
||||
#include <iostream>
|
||||
|
||||
// Constants
|
||||
const int open_gl_major_version = 3;
|
||||
@ -21,25 +21,13 @@ extern float frame_time;
|
||||
extern float fps;
|
||||
extern float frame_time_graph[100];
|
||||
extern SDL_GLContext gl_context;
|
||||
|
||||
extern ImGuiIO& io;
|
||||
extern ImGuiStyle& style;
|
||||
#define delta_time frame_time
|
||||
|
||||
// Functions
|
||||
int initialize_opengl();
|
||||
void cleanup_opengl();
|
||||
|
||||
// ImGui
|
||||
int initialize_imgui();
|
||||
void cleanup_imgui();
|
||||
void new_frame_imgui();
|
||||
void frame_time_ui();
|
||||
|
||||
// Frame time calculation
|
||||
void calc_frame_time();
|
||||
|
||||
// Shader management
|
||||
unsigned int compile_shader(const char* shader_source, GLenum shader_type);
|
||||
unsigned int create_program(unsigned int vertex_shader, unsigned int fragment_shader);
|
||||
|
||||
#endif
|
23
include/gui.hpp
Normal file
23
include/gui.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef GUI_HPP
|
||||
#define GUI_HPP
|
||||
|
||||
// Includes
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "window.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include <iostream>
|
||||
|
||||
// Variables
|
||||
extern ImGuiIO& io;
|
||||
extern ImGuiStyle& style;
|
||||
extern
|
||||
|
||||
// Functions
|
||||
int initialize_imgui();
|
||||
void cleanup_imgui();
|
||||
void new_frame_imgui();
|
||||
void frame_time_ui();
|
||||
|
||||
#endif
|
23
include/loader.hpp
Normal file
23
include/loader.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef LOADER_HPP
|
||||
#define LOADER_HPP
|
||||
|
||||
// Includes
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
// Obj struct
|
||||
struct Obj {
|
||||
float* vertices; // Pointer to vertex data
|
||||
size_t vertex_count; // Number of vertices
|
||||
float* normals; // Pointer to normal data
|
||||
size_t normal_count; // Number of normals
|
||||
float* texcoords; // Pointer to texture coordinate data
|
||||
size_t texcoord_count; // Number of texture coordinates
|
||||
unsigned int* indices; // Pointer to index data
|
||||
size_t index_count; // Number of indices
|
||||
};
|
||||
|
||||
// Function to load an OBJ file
|
||||
Obj load_obj(const std::string& filename);
|
||||
|
||||
#endif // LOADER_HPP
|
@ -6,11 +6,17 @@
|
||||
#include "window.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "loader.hpp"
|
||||
|
||||
// Variables
|
||||
extern bool running;
|
||||
|
||||
// Functions
|
||||
int main(int argc, char* argv[]);
|
||||
void init(); // Initialize SDL, OpenGL, and ImGui
|
||||
void handle_events(); // Handle SDL events
|
||||
void handle_keyboard_input(); // Handle keyboard input for camera movement
|
||||
|
||||
#endif
|
24
include/shader.hpp
Normal file
24
include/shader.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef SHADER_HPP
|
||||
#define SHADER_HPP
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
// Includes
|
||||
#include "utils.hpp"
|
||||
#include <iostream>
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
#include "geometry.hpp"
|
||||
|
||||
// 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();
|
||||
};
|
||||
|
||||
#endif
|
24
include/texture.hpp
Normal file
24
include/texture.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef TEXTURE_HPP
|
||||
#define TEXTURE_HPP
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
// Includes
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
#include <iostream>
|
||||
|
||||
// Functions
|
||||
void flip_surface(SDL_Surface* surface);
|
||||
|
||||
// Classes
|
||||
class Texture {
|
||||
public:
|
||||
unsigned int ID;
|
||||
Texture(const char* file_path);
|
||||
~Texture();
|
||||
void bind() const;
|
||||
void bind(unsigned int unit) const;
|
||||
void unbind() const;
|
||||
};
|
||||
|
||||
#endif
|
@ -2,18 +2,16 @@
|
||||
#define WINDOW_HPP
|
||||
|
||||
// Includes
|
||||
#include "iostream"
|
||||
#include <iostream>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// Constants
|
||||
const int window_width = 800;
|
||||
const int window_height = 600;
|
||||
|
||||
// Variables
|
||||
const SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
extern float main_scale;
|
||||
extern SDL_Window* window;
|
||||
extern SDL_Event event;
|
||||
extern int window_width;
|
||||
extern int window_height;
|
||||
|
||||
// Functions
|
||||
int initialize_sdl();
|
||||
|
10
makefile
10
makefile
@ -10,10 +10,10 @@ IMGUI_DIR = imgui
|
||||
CXX = g++
|
||||
|
||||
# Libs
|
||||
LIBS = -lGL `pkg-config --libs sdl3`
|
||||
LIBS = -lGL -lglm `pkg-config --libs sdl3 sdl3-image`
|
||||
|
||||
# Compiler and linker settings
|
||||
CXXFLAGS = `pkg-config --cflags sdl3` -std=c++17 -I $(INCLUDE_DIR)
|
||||
CXXFLAGS = -std=c++17 -I $(INCLUDE_DIR)
|
||||
|
||||
# If ImGui directory is set, include its source files
|
||||
ifdef IMGUI_DIR
|
||||
@ -51,6 +51,10 @@ dirs:
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
@mkdir -p $(OBJ_DIR)
|
||||
|
||||
# Clear build directory
|
||||
clear:
|
||||
@find $(OBJ_DIR) -type f -name '*.o' ! -name 'imgui*.o' -exec rm -f {} +
|
||||
|
||||
# Pattern rule for source files in src directory
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
@ -64,7 +68,7 @@ $(OBJ_DIR)/%.o: $(IMGUI_DIR)/backends/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
endif
|
||||
|
||||
all: dirs $(BIN)
|
||||
all: dirs clear $(BIN)
|
||||
@echo Build complete
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
|
@ -2,7 +2,11 @@
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec3 color; // Input color from the vertex shader
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform sampler2D texture1; // Texture sampler
|
||||
uniform sampler2D texture2; // Second texture sampler
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(color, 1.0); // Set the fragment color to the input color
|
||||
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.3) * vec4(color, 1.0); // Mix the two textures and apply the color
|
||||
}
|
@ -1,9 +1,16 @@
|
||||
#version 330 core
|
||||
|
||||
layout(location = 0) in vec3 position; // Vertex position
|
||||
layout(location = 1) in vec2 texCoords; // Texture coordinates
|
||||
out vec3 color; // Output color to the fragment shader
|
||||
out vec2 TexCoord;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position, 1.0); // Set the position of the vertex
|
||||
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
|
||||
TexCoord = texCoords; // Pass texture coordinates to the fragment shader
|
||||
}
|
8
shaders/triangle_untextured.frag
Normal file
8
shaders/triangle_untextured.frag
Normal 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
|
||||
}
|
13
shaders/triangle_untextured.vert
Normal file
13
shaders/triangle_untextured.vert
Normal 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
|
||||
}
|
120
src/geometry.cpp
Normal file
120
src/geometry.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include "geometry.hpp"
|
||||
|
||||
Object::Object(
|
||||
float *vertices, unsigned int vertex_size,
|
||||
unsigned int *indices, unsigned int index_size,
|
||||
float *normals, unsigned int normal_size,
|
||||
float *texcoords, unsigned int texcoord_size
|
||||
) {
|
||||
glGenVertexArrays(1, &VAO); // Generate a vertex array object
|
||||
glGenBuffers(1, &VBO); // Generate a vertex buffer object
|
||||
glGenBuffers(1, &EBO); // Generate an element buffer object
|
||||
glGenBuffers(1, &NBO); // Generate a normal buffer object
|
||||
glGenBuffers(1, &TBO); // Generate a texture buffer object
|
||||
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Bind the vertex buffer object
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Bind the element buffer object
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_size, vertices, GL_STATIC_DRAW); // Upload vertex data to the buffer
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, indices, GL_STATIC_DRAW); // Upload index data to the buffer
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); // Set up vertex attributes
|
||||
glEnableVertexAttribArray(0); // Enable vertex attribute 0
|
||||
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // Set up texture coordinates
|
||||
glEnableVertexAttribArray(1); // Enable vertex attribute 1
|
||||
|
||||
if (normals && normal_size > 0) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, NBO); // Bind the normal buffer object
|
||||
glBufferData(GL_ARRAY_BUFFER, normal_size, normals, GL_STATIC_DRAW); // Upload normal data to the buffer
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // Set up normal attributes
|
||||
glEnableVertexAttribArray(2); // Enable vertex attribute 2
|
||||
}
|
||||
|
||||
if (texcoords && texcoord_size > 0) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, TBO); // Bind the texture buffer object
|
||||
glBufferData(GL_ARRAY_BUFFER, texcoord_size, texcoords, GL_STATIC_DRAW); // Upload texture coordinate data to the buffer
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); // Set up texture coordinate attributes
|
||||
glEnableVertexAttribArray(3); // Enable vertex attribute 3
|
||||
}
|
||||
|
||||
glBindVertexArray(0); // Unbind the vertex array object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind the vertex buffer object
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Unbind the element buffer object
|
||||
|
||||
this->vertex_count = vertex_size / (5 * sizeof(float)); // Calculate vertex count based on size
|
||||
this->index_count = index_size / sizeof(unsigned int); // Calculate index count based on size
|
||||
}
|
||||
|
||||
Object::~Object() {
|
||||
glDeleteVertexArrays(1, &VAO); // Delete the vertex array object
|
||||
glDeleteBuffers(1, &VBO); // Delete the vertex buffer object
|
||||
glDeleteBuffers(1, &EBO); // Delete the element buffer object
|
||||
glDeleteBuffers(1, &NBO); // Delete the normal buffer object
|
||||
glDeleteBuffers(1, &TBO); // Delete the texture buffer object
|
||||
}
|
||||
|
||||
void Object::draw() {
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0); // Draw the object using the element buffer
|
||||
glBindVertexArray(0); // Unbind the vertex array object
|
||||
}
|
||||
|
||||
UntexturedObject::UntexturedObject(
|
||||
float *vertices, unsigned int vertex_size,
|
||||
unsigned int *indices, unsigned int index_size,
|
||||
float *normals, unsigned int normal_size,
|
||||
float *texcoords, unsigned int texcoord_size
|
||||
) {
|
||||
glGenVertexArrays(1, &VAO); // Generate a vertex array object
|
||||
glGenBuffers(1, &VBO); // Generate a vertex buffer object
|
||||
glGenBuffers(1, &EBO); // Generate an element buffer object
|
||||
glGenBuffers(1, &NBO); // Generate a normal buffer object
|
||||
glGenBuffers(1, &TBO); // Generate a texture buffer object
|
||||
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Bind the vertex buffer object
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Bind the element buffer object
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_size, vertices, GL_STATIC_DRAW); // Upload vertex data to the buffer
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, indices, GL_STATIC_DRAW); // Upload index data to the buffer
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // Set up vertex attributes
|
||||
glEnableVertexAttribArray(0); // Enable vertex attribute 0
|
||||
|
||||
if (normals && normal_size > 0) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, NBO); // Bind the normal buffer object
|
||||
glBufferData(GL_ARRAY_BUFFER, normal_size, normals, GL_STATIC_DRAW); // Upload normal data to the buffer
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // Set up normal attributes
|
||||
glEnableVertexAttribArray(1); // Enable vertex attribute 1
|
||||
}
|
||||
|
||||
if (texcoords && texcoord_size > 0) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, TBO); // Bind the texture buffer object
|
||||
glBufferData(GL_ARRAY_BUFFER, texcoord_size, texcoords, GL_STATIC_DRAW); // Upload texture coordinate data to the buffer
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); // Set up texture coordinate attributes
|
||||
glEnableVertexAttribArray(2); // Enable vertex attribute 2
|
||||
}
|
||||
|
||||
glBindVertexArray(0); // Unbind the vertex array object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind the vertex buffer object
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Unbind the element buffer object
|
||||
|
||||
this->vertex_count = vertex_size / (5 * sizeof(float)); // Calculate vertex count based on size
|
||||
this->index_count = index_size / sizeof(unsigned int); // Calculate index count based on
|
||||
}
|
||||
|
||||
UntexturedObject::~UntexturedObject() {
|
||||
glDeleteVertexArrays(1, &VAO); // Delete the vertex array object
|
||||
glDeleteBuffers(1, &VBO); // Delete the vertex buffer object
|
||||
glDeleteBuffers(1, &EBO); // Delete the element buffer object
|
||||
glDeleteBuffers(1, &NBO); // Delete the normal buffer object
|
||||
glDeleteBuffers(1, &TBO); // Delete the texture buffer object
|
||||
}
|
||||
|
||||
void UntexturedObject::draw() {
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0); // Draw the object using the element buffer
|
||||
glBindVertexArray(0); // Unbind the vertex array object
|
||||
}
|
100
src/graphics.cpp
100
src/graphics.cpp
@ -6,7 +6,6 @@ Uint32 current_time;
|
||||
float frame_time;
|
||||
float fps;
|
||||
float frame_time_graph[100];
|
||||
|
||||
SDL_GLContext gl_context;
|
||||
|
||||
// Functions
|
||||
@ -44,91 +43,6 @@ void cleanup_opengl() {
|
||||
std::cout << "OpenGL cleanup successful." << std::endl;
|
||||
}
|
||||
|
||||
unsigned int compile_shader(const char* shader_source, GLenum shader_type) {
|
||||
unsigned int shader = glCreateShader(shader_type);
|
||||
if (shader == 0) {
|
||||
std::cerr << "Failed to create shader." << std::endl;
|
||||
return 0; // Shader creation failed
|
||||
}
|
||||
|
||||
glShaderSource(shader, 1, &shader_source, nullptr);
|
||||
glCompileShader(shader);
|
||||
|
||||
// Check for compilation errors
|
||||
int success;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char info_log[512];
|
||||
glGetShaderInfoLog(shader, sizeof(info_log), nullptr, info_log);
|
||||
std::cerr << "Shader compilation error: " << info_log << std::endl;
|
||||
glDeleteShader(shader);
|
||||
return 0; // Shader compilation failed
|
||||
}
|
||||
|
||||
return shader; // Shader compiled successfully
|
||||
}
|
||||
|
||||
unsigned int create_program(unsigned int vertex_shader, unsigned int fragment_shader) {
|
||||
unsigned int program = glCreateProgram();
|
||||
if (program == 0) {
|
||||
std::cerr << "Failed to create shader program." << std::endl;
|
||||
return 0; // Program creation failed
|
||||
}
|
||||
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
|
||||
// Check for linking errors
|
||||
int success;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char info_log[512];
|
||||
glGetProgramInfoLog(program, sizeof(info_log), nullptr, info_log);
|
||||
std::cerr << "Shader program linking error: " << info_log << std::endl;
|
||||
glDeleteProgram(program);
|
||||
return 0; // Program linking failed
|
||||
}
|
||||
|
||||
return program; // Program created successfully
|
||||
}
|
||||
|
||||
int initialize_imgui() {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale);
|
||||
style.FontScaleDpi = main_scale;
|
||||
|
||||
if (!ImGui_ImplSDL3_InitForOpenGL(window, gl_context)) {
|
||||
std::cerr << "ImGui_ImplSDL3_InitForOpenGL failed!" << std::endl;
|
||||
return 1; // Initialization failed
|
||||
}
|
||||
|
||||
char glsl_version[32];
|
||||
snprintf(glsl_version, sizeof(glsl_version), "#version %d%d0", open_gl_major_version, open_gl_minor_version);
|
||||
if (!ImGui_ImplOpenGL3_Init(glsl_version)) {
|
||||
std::cerr << "ImGui_ImplOpenGL3_Init failed!" << std::endl;
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
return 1; // Initialization failed
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_imgui() {
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
std::cout << "ImGui cleanup successful." << std::endl;
|
||||
}
|
||||
|
||||
void calc_frame_time() {
|
||||
// Calculate frame time
|
||||
current_time = SDL_GetTicks();
|
||||
@ -142,17 +56,3 @@ void calc_frame_time() {
|
||||
}
|
||||
frame_time_graph[0] = frame_time; // Add new frame time
|
||||
}
|
||||
|
||||
void new_frame_imgui() {
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void frame_time_ui() {
|
||||
ImGui::Begin("Frame Time");
|
||||
ImGui::Text("Current FPS: %.2f", fps);
|
||||
ImGui::Text("Current Frame Time: %.3f ms", frame_time * 1000.0f);
|
||||
ImGui::PlotLines("##Frame Time Graph", frame_time_graph, 100, 0, "Frame Time (ms)", 0.0f, 0.1f, ImVec2(200, 80));
|
||||
ImGui::End();
|
||||
}
|
51
src/gui.cpp
Normal file
51
src/gui.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "gui.hpp"
|
||||
|
||||
int initialize_imgui() {
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale);
|
||||
style.FontScaleDpi = main_scale;
|
||||
|
||||
if (!ImGui_ImplSDL3_InitForOpenGL(window, gl_context)) {
|
||||
std::cerr << "ImGui_ImplSDL3_InitForOpenGL failed!" << std::endl;
|
||||
return 1; // Initialization failed
|
||||
}
|
||||
|
||||
char glsl_version[32];
|
||||
snprintf(glsl_version, sizeof(glsl_version), "#version %d%d0", open_gl_major_version, open_gl_minor_version);
|
||||
if (!ImGui_ImplOpenGL3_Init(glsl_version)) {
|
||||
std::cerr << "ImGui_ImplOpenGL3_Init failed!" << std::endl;
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
return 1; // Initialization failed
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_imgui() {
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
std::cout << "ImGui cleanup successful." << std::endl;
|
||||
}
|
||||
|
||||
void new_frame_imgui() {
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void frame_time_ui() {
|
||||
ImGui::Begin("Frame Time");
|
||||
ImGui::Text("Current FPS: %.2f", fps);
|
||||
ImGui::Text("Current Frame Time: %.3f ms", frame_time * 1000.0f);
|
||||
ImGui::PlotLines("##Frame Time Graph", frame_time_graph, 100, 0, "Frame Time (ms)", 0.0f, 0.1f, ImVec2(200, 80));
|
||||
ImGui::End();
|
||||
}
|
48
src/loader.cpp
Normal file
48
src/loader.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "loader.hpp"
|
||||
|
||||
Obj load_obj(const std::string& filename) {
|
||||
Obj obj;
|
||||
obj.vertices = nullptr;
|
||||
obj.vertex_count = 0;
|
||||
obj.indices = nullptr;
|
||||
obj.index_count = 0;
|
||||
obj.normals = nullptr;
|
||||
obj.normal_count = 0;
|
||||
obj.texcoords = nullptr;
|
||||
obj.texcoord_count = 0;
|
||||
|
||||
std::ifstream file(filename);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Failed to open OBJ file: " << filename << std::endl;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Read the file and populate the obj structure
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
// Parse the line and extract vertex, normal, and index data
|
||||
if (line.substr(0, 2) == "v ") {
|
||||
// Vertex position
|
||||
obj.vertex_count++;
|
||||
obj.vertices = (float*)realloc(obj.vertices, obj.vertex_count * 3 * sizeof(float));
|
||||
sscanf(line.c_str() + 2, "%f %f %f", &obj.vertices[(obj.vertex_count - 1) * 3], &obj.vertices[(obj.vertex_count - 1) * 3 + 1], &obj.vertices[(obj.vertex_count - 1) * 3 + 2]);
|
||||
} else if (line.substr(0, 2) == "f ") {
|
||||
// Face indices
|
||||
unsigned int index1,
|
||||
} else if (line.substr(0, 2) == "vn") {
|
||||
// Vertex normal
|
||||
obj.normal_count++;
|
||||
obj.normals = (float*)realloc(obj.normals, obj.normal_count * 3 * sizeof(float));
|
||||
sscanf(line.c_str() + 3, "%f %f %f", &obj.normals[(obj.normal_count - 1) * 3], &obj.normals[(obj.normal_count - 1) * 3 + 1], &obj.normals[(obj.normal_count - 1) * 3 + 2]);
|
||||
|
||||
} else if (line.substr(0, 2) == "vt") {
|
||||
// Vertex texture coordinate
|
||||
obj.texcoord_count++;
|
||||
obj.texcoords = (float*)realloc(obj.texcoords, obj.texcoord_count * 2 * sizeof(float));
|
||||
sscanf(line.c_str() + 3, "%f %f", &obj.texcoords[(obj.texcoord_count - 1) * 2], &obj.texcoords[(obj.texcoord_count - 1) * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
return obj;
|
||||
}
|
224
src/main.cpp
224
src/main.cpp
@ -1,22 +1,33 @@
|
||||
#include "main.hpp"
|
||||
#include <GL/glu.h>
|
||||
|
||||
// Variables
|
||||
bool running = true;
|
||||
float fov = 45.0f; // Field of view
|
||||
float camera_move_speed = 10.0f; // Camera movement speed
|
||||
bool wireframe_mode = false; // Wireframe mode toggle
|
||||
glm::mat4 viewMatrix = glm::mat4(1.0f); // View matrix
|
||||
glm::mat4 projectionMatrix = glm::perspective(glm::radians(fov), (float)window_width / (float)window_height, 0.1f, 100.0f); // Perspective projection matrix
|
||||
|
||||
// Main
|
||||
int main(int argc, char* argv[]) {
|
||||
glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 3.0f); // Initial camera position
|
||||
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f); // Camera front vector
|
||||
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); // Camera up vector
|
||||
float camera_pitch = 0.0f; // Pitch angle
|
||||
float camera_yaw = -90.0f; // Yaw angle
|
||||
float camera_turn_speed = 1.0f; // Camera turn speed
|
||||
|
||||
// Init
|
||||
void init() {
|
||||
// Initialize SDL
|
||||
if (initialize_sdl() != 0) {
|
||||
std::cerr << "SDL initialization failed." << std::endl;
|
||||
return 1; // SDL initialization failed
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize OpenGL
|
||||
if (initialize_opengl() != 0) {
|
||||
std::cerr << "OpenGL initialization failed." << std::endl;
|
||||
cleanup_sdl();
|
||||
return 1; // OpenGL initialization failed
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize ImGui
|
||||
@ -24,92 +35,159 @@ int main(int argc, char* argv[]) {
|
||||
std::cerr << "ImGui initialization failed." << std::endl;
|
||||
cleanup_opengl();
|
||||
cleanup_sdl();
|
||||
return 1; // ImGui initialization failed
|
||||
return;
|
||||
}
|
||||
|
||||
// Triangle vertices
|
||||
float vertices[] = {
|
||||
0.5f, 0.5f, 0.0f, // top right
|
||||
0.5f, -0.5f, 0.0f, // bottom right
|
||||
-0.5f, -0.5f, 0.0f, // bottom left
|
||||
-0.5f, 0.5f, 0.0f // top left
|
||||
};
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
unsigned int indices[] = {
|
||||
0, 1, 3, // first triangle
|
||||
1, 2, 3 // second triangle
|
||||
};
|
||||
|
||||
// Vertex buffer object (VBO) and vertex array object (VAO) and element buffer object (EBO)
|
||||
unsigned int VBO, VAO, EBO;
|
||||
|
||||
glGenVertexArrays(1, &VAO); // Generate a vertex array object
|
||||
glGenBuffers(1, &VBO); // Generate a vertex buffer object
|
||||
glGenBuffers(1, &EBO); // Generate an element buffer object
|
||||
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Bind the vertex buffer object
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Bind the element buffer object
|
||||
|
||||
// Upload vertex data to the buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||
|
||||
// Set up vertex attributes
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindVertexArray(0); // Unbind the vertex array object
|
||||
|
||||
// Load shaders
|
||||
const char* vertex_shader_source = read_file("shaders/triangle.vert");
|
||||
const char* fragment_shader_source = read_file("shaders/triangle.frag");
|
||||
|
||||
unsigned int vertex_shader = compile_shader(vertex_shader_source, GL_VERTEX_SHADER);
|
||||
unsigned int fragment_shader = compile_shader(fragment_shader_source, GL_FRAGMENT_SHADER);
|
||||
unsigned int shader_program = create_program(vertex_shader, fragment_shader);
|
||||
|
||||
// Set the shader program
|
||||
glUseProgram(shader_program);
|
||||
|
||||
// Wireframe toggle
|
||||
bool wireframe_mode = false;
|
||||
|
||||
// Main loop
|
||||
while (running) {
|
||||
|
||||
// Handle events
|
||||
// Event handling
|
||||
void handle_events() {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
ImGui_ImplSDL3_ProcessEvent(&event); // Process ImGui events
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
running = false; // Exit loop on quit event
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
// Handle window resize
|
||||
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||
glViewport(0, 0, window_width, window_height); // Update OpenGL
|
||||
break;
|
||||
|
||||
// Start the ImGui frame
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle keyboard input
|
||||
void handle_keyboard_input() {
|
||||
const bool *keyboard_state = SDL_GetKeyboardState(NULL);
|
||||
|
||||
// Handle keyboard input for camera movement
|
||||
if (keyboard_state[SDL_SCANCODE_W]) {
|
||||
camera_position += camera_move_speed * delta_time * camera_front; // Move forward
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_S]) {
|
||||
camera_position -= camera_move_speed * delta_time * camera_front; // Move backward
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_A]) {
|
||||
camera_position -= glm::normalize(glm::cross(camera_front, camera_up)) * camera_move_speed * delta_time; // Move left
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_D]) {
|
||||
camera_position += glm::normalize(glm::cross(camera_front, camera_up)) * camera_move_speed * delta_time; // Move right
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_SPACE]) {
|
||||
camera_position += camera_up * camera_move_speed * delta_time; // Move up
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_LCTRL]) {
|
||||
camera_position -= camera_up * camera_move_speed * delta_time; // Move down
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_LEFT]) {
|
||||
camera_yaw -= camera_turn_speed; // Turn left
|
||||
if (camera_yaw < -180.0f) camera_yaw += 360.0f; // Wrap yaw
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_RIGHT]) {
|
||||
camera_yaw += camera_turn_speed; // Turn right
|
||||
if (camera_yaw > 180.0f) camera_yaw -= 360.0f; // Wrap yaw
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_UP]) {
|
||||
camera_pitch += camera_turn_speed; // Look up
|
||||
if (camera_pitch > 89.0f) camera_pitch = 89.0f; // Clamp pitch
|
||||
}
|
||||
if (keyboard_state[SDL_SCANCODE_DOWN]) {
|
||||
camera_pitch -= camera_turn_speed; // Look down
|
||||
if (camera_pitch < -89.0f) camera_pitch = -89.0f; // Clamp pitch
|
||||
}
|
||||
}
|
||||
|
||||
// ImGui frame
|
||||
void imgui_frame() {
|
||||
new_frame_imgui();
|
||||
|
||||
// Frame time UI
|
||||
frame_time_ui();
|
||||
|
||||
// Toggle wireframe mode ui
|
||||
ImGui::Begin("Wireframe Mode");
|
||||
if (ImGui::Checkbox("Enable Wireframe Mode", &wireframe_mode)) {
|
||||
ImGui::Begin("Control Panel");
|
||||
ImGui::Text("Camera Position: (%.2f, %.2f, %.2f)", camera_position.x, camera_position.y, camera_position.z);
|
||||
ImGui::Text("Camera Front: (%.2f, %.2f, %.2f)", camera_front.x, camera_front.y, camera_front.z);
|
||||
ImGui::Text("Camera Up: (%.2f, %.2f, %.2f)", camera_up.x, camera_up.y, camera_up.z);
|
||||
ImGui::Text("Camera Pitch: %.2f degrees", camera_pitch);
|
||||
ImGui::Text("Camera Yaw: %.2f degrees", camera_yaw);
|
||||
ImGui::SliderFloat("Field of View", &fov, 1.0f, 120.0f, "%.1f degrees");
|
||||
ImGui::SliderFloat("Camera Speed", &camera_move_speed, 0.1f, 10.0f, "%.1f units/s");
|
||||
ImGui::SliderFloat("Camera Turn Speed", &camera_turn_speed, 1.0f, 5.0f, "%.2f units/s");
|
||||
ImGui::Checkbox("Wireframe Mode", &wireframe_mode);
|
||||
if (wireframe_mode) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Enable wireframe mode
|
||||
} else {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Disable wireframe mode
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Main
|
||||
int main(int argc, char* argv[]) {
|
||||
// Initialize SDL, OpenGL, and ImGui
|
||||
init();
|
||||
|
||||
// Load shader program
|
||||
Shader shader_program("shaders/triangle_untextured.vert", "shaders/triangle_untextured.frag");
|
||||
|
||||
// Generate and set up textures
|
||||
Texture texture1("assets/crate.jpg");
|
||||
Texture texture2("assets/meow.png");
|
||||
shader_program.use();
|
||||
shader_program.setInt("texture1", 0);
|
||||
shader_program.setInt("texture2", 1);
|
||||
|
||||
// Load an OBJ file
|
||||
Obj obj = load_obj("assets/cube.obj");
|
||||
|
||||
// print vertex and index counts
|
||||
std::cout << "Loaded OBJ file: " << obj.vertex_count << " vertices, " << obj.index_count << " indices." << std::endl;
|
||||
|
||||
// Create the object and set up its geometry
|
||||
UntexturedObject object(
|
||||
obj.vertices, obj.vertex_count * 3 * sizeof(float),
|
||||
obj.indices, obj.index_count * sizeof(unsigned int)
|
||||
);
|
||||
|
||||
glm::mat4 modelMatrix = glm::mat4(1.0f);
|
||||
|
||||
// Main loop
|
||||
while (running) {
|
||||
// Handle events
|
||||
handle_events();
|
||||
handle_keyboard_input();
|
||||
|
||||
// ImGui frame
|
||||
imgui_frame();
|
||||
|
||||
// Update the projection and view matrices
|
||||
projectionMatrix = glm::perspective(glm::radians(fov), (float)window_width / (float)window_height, 0.1f, 100.0f);
|
||||
camera_front = glm::vec3(
|
||||
cos(glm::radians(camera_yaw)) * cos(glm::radians(camera_pitch)),
|
||||
sin(glm::radians(camera_pitch)),
|
||||
sin(glm::radians(camera_yaw)) * cos(glm::radians(camera_pitch))
|
||||
);
|
||||
viewMatrix = glm::lookAt(camera_position, camera_position + camera_front, camera_up);
|
||||
|
||||
// Render
|
||||
ImGui::Render();
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBindVertexArray(VAO); // Bind the vertex array object
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // Draw the triangles
|
||||
// Use the shader program
|
||||
shader_program.use();
|
||||
shader_program.setMat4("view", viewMatrix); // Set the view matrix
|
||||
shader_program.setMat4("projection", projectionMatrix); // Set the projection matrix
|
||||
shader_program.setMat4("model", modelMatrix); // Set the model matrix
|
||||
|
||||
texture1.bind(0); // Bind texture 1 to unit 0
|
||||
texture2.bind(1); // Bind texture 2 to unit 1
|
||||
|
||||
object.draw(); // Draw the object
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_GL_SwapWindow(window);
|
||||
@ -119,14 +197,6 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
glDeleteProgram(shader_program);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
free((void*)vertex_shader_source);
|
||||
free((void*)fragment_shader_source);
|
||||
cleanup_imgui();
|
||||
cleanup_opengl();
|
||||
cleanup_sdl();
|
||||
|
97
src/shader.cpp
Normal file
97
src/shader.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "shader.hpp"
|
||||
|
||||
Shader::Shader(const char* vertexPath, const char* fragmentPath) {
|
||||
// Load and compile vertex shader
|
||||
unsigned int shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
if (shader == 0) {
|
||||
std::cerr << "Failed to create shader." << std::endl;
|
||||
}
|
||||
|
||||
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);
|
||||
std::cerr << "Vertex shader compilation error: " << info_log << std::endl;
|
||||
glDeleteShader(shader);
|
||||
}
|
||||
|
||||
// Load and compile fragment shader
|
||||
unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if (fragment_shader == 0) {
|
||||
std::cerr << "Failed to create shader." << std::endl;
|
||||
}
|
||||
|
||||
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);
|
||||
std::cerr << "Fragment shader compilation error: " << info_log << std::endl;
|
||||
glDeleteShader(fragment_shader);
|
||||
}
|
||||
|
||||
// Create shader program
|
||||
ID = glCreateProgram();
|
||||
if (ID == 0) {
|
||||
std::cerr << "Failed to create shader program." << std::endl;
|
||||
}
|
||||
|
||||
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);
|
||||
std::cerr << "Shader program linking error: " << info_log << std::endl;
|
||||
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 {
|
||||
std::cerr << "Shader program not initialized." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
68
src/texture.cpp
Normal file
68
src/texture.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "texture.hpp"
|
||||
|
||||
void flip_surface(SDL_Surface* surface) {
|
||||
if (!surface) {
|
||||
std::cerr << "Surface is null, cannot flip" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int pitch = surface->pitch;
|
||||
Uint8* pixels = static_cast<Uint8*>(surface->pixels);
|
||||
int height = surface->h;
|
||||
|
||||
for (int y = 0; y < height / 2; ++y) {
|
||||
Uint8* top_row = pixels + y * pitch;
|
||||
Uint8* bottom_row = pixels + (height - y - 1) * pitch;
|
||||
|
||||
for (int x = 0; x < pitch; ++x) {
|
||||
std::swap(top_row[x], bottom_row[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(const char* file_path) {
|
||||
ID = 0;
|
||||
SDL_Surface* surface = IMG_Load(file_path);
|
||||
if (!surface) {
|
||||
std::cerr << "Failed to load texture: " << SDL_GetError() << std::endl;
|
||||
return; // Texture loading failed
|
||||
}
|
||||
|
||||
GLenum format = (surface->format == SDL_PIXELFORMAT_RGBA32) ? GL_RGBA : GL_RGB;
|
||||
flip_surface(surface); // Flip the surface vertically
|
||||
|
||||
glGenTextures(1, &ID);
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
SDL_DestroySurface(surface); // Free the surface after uploading texture data
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (ID != 0) {
|
||||
glDeleteTextures(1, &ID);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::bind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
}
|
||||
|
||||
void Texture::bind(unsigned int unit) const {
|
||||
if (unit >= GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
|
||||
std::cerr << "Texture unit out of range: " << unit << std::endl;
|
||||
return; // Invalid texture unit
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
}
|
||||
|
||||
void Texture::unbind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
float main_scale;
|
||||
SDL_Window* window;
|
||||
SDL_Event event;
|
||||
int window_width = 850; // Default window width
|
||||
int window_height = 850; // Default window height
|
||||
|
||||
// Functions
|
||||
int initialize_sdl() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user