updates
This commit is contained in:
parent
fc862a279f
commit
ede68286df
1 changed files with 184 additions and 26 deletions
188
skr/skr.h
188
skr/skr.h
|
|
@ -197,9 +197,8 @@ typedef struct SkrShader {
|
||||||
const char* Path;
|
const char* Path;
|
||||||
} SkrShader;
|
} SkrShader;
|
||||||
|
|
||||||
static SkrShader skr_fps_camera_vert = {
|
static char* skr_camera_3d_vert =
|
||||||
GL_VERTEX_SHADER,
|
"#version 330 core\n"
|
||||||
(char*){"#version 330 core\n"
|
|
||||||
"layout (location = 0) in vec3 aPos;\n"
|
"layout (location = 0) in vec3 aPos;\n"
|
||||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||||
"out vec2 TexCoord;\n"
|
"out vec2 TexCoord;\n"
|
||||||
|
|
@ -210,8 +209,7 @@ static SkrShader skr_fps_camera_vert = {
|
||||||
"gl_Position = projection * view * model * vec4(aPos, "
|
"gl_Position = projection * view * model * vec4(aPos, "
|
||||||
"1.0f);\n"
|
"1.0f);\n"
|
||||||
"TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
"TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
||||||
"}\n"},
|
"}\n";
|
||||||
NULL};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Vertex structure used by the rendering engine.
|
* @brief Vertex structure used by the rendering engine.
|
||||||
|
|
@ -421,9 +419,6 @@ typedef struct SkrModel {
|
||||||
SkrMesh* Meshes; /*!< Array of meshes that compose the model. */
|
SkrMesh* Meshes; /*!< Array of meshes that compose the model. */
|
||||||
unsigned int MeshCount;
|
unsigned int MeshCount;
|
||||||
|
|
||||||
SkrTexture* Textures; /*!< Array of textures used by model's meshes. */
|
|
||||||
unsigned int TextureCount;
|
|
||||||
|
|
||||||
char* Path; /*!< Filesystem path of the model file. */
|
char* Path; /*!< Filesystem path of the model file. */
|
||||||
} SkrModel;
|
} SkrModel;
|
||||||
|
|
||||||
|
|
@ -482,6 +477,10 @@ typedef struct SkrState {
|
||||||
unsigned int ProgramCount;
|
unsigned int ProgramCount;
|
||||||
} SkrState;
|
} SkrState;
|
||||||
|
|
||||||
|
typedef enum SkrCameraType {
|
||||||
|
SKR_CAMERA_3D,
|
||||||
|
} SkrCameraType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief First-person camera structure.
|
* @brief First-person camera structure.
|
||||||
*
|
*
|
||||||
|
|
@ -504,6 +503,9 @@ typedef struct SkrCamera {
|
||||||
float LastY; /*!< Last cursor Y position. */
|
float LastY; /*!< Last cursor Y position. */
|
||||||
bool FirstMouse; /*!< Whether the first mouse movement has been
|
bool FirstMouse; /*!< Whether the first mouse movement has been
|
||||||
captured. */
|
captured. */
|
||||||
|
|
||||||
|
SkrCameraType Type;
|
||||||
|
|
||||||
bool Initialized;
|
bool Initialized;
|
||||||
} SkrCamera;
|
} SkrCamera;
|
||||||
|
|
||||||
|
|
@ -512,13 +514,19 @@ typedef struct SkrCamera {
|
||||||
.Position = {0.0f, 0.0f, 3.0f}, \
|
.Position = {0.0f, 0.0f, 3.0f}, \
|
||||||
.Front = {0.0f, 0.0f, -1.0f}, \
|
.Front = {0.0f, 0.0f, -1.0f}, \
|
||||||
.Up = {0.0f, 1.0f, 0.0f}, \
|
.Up = {0.0f, 1.0f, 0.0f}, \
|
||||||
|
\
|
||||||
.Yaw = -90.0f, \
|
.Yaw = -90.0f, \
|
||||||
.Pitch = 0.0f, \
|
.Pitch = 0.0f, \
|
||||||
.FOV = 70.0f, \
|
.FOV = 70.0f, \
|
||||||
|
\
|
||||||
.Sensitivity = 0.1f, \
|
.Sensitivity = 0.1f, \
|
||||||
.LastX = 400.0f, \
|
.LastX = 400.0f, \
|
||||||
.LastY = 300.0f, \
|
.LastY = 300.0f, \
|
||||||
.FirstMouse = true, \
|
.FirstMouse = true, \
|
||||||
|
\
|
||||||
|
.Type = SKR_CAMERA_3D, \
|
||||||
|
\
|
||||||
|
.Initialized = true, \
|
||||||
})
|
})
|
||||||
|
|
||||||
extern SkrCamera* g_skr_camera;
|
extern SkrCamera* g_skr_camera;
|
||||||
|
|
@ -916,13 +924,15 @@ static inline GLuint m_skr_gl_create_program(const GLuint* shaders,
|
||||||
* @return Program ID, or 0 on failure.
|
* @return Program ID, or 0 on failure.
|
||||||
*/
|
*/
|
||||||
static inline GLuint
|
static inline GLuint
|
||||||
m_skr_gl_create_program_from_shaders(const SkrShader* shaders_input,
|
m_skr_gl_create_program_from_shaders(const SkrShader* shader_array,
|
||||||
const size_t count) {
|
const size_t size) {
|
||||||
if (!shaders_input || count == 0) {
|
if (!shader_array || size == 0) {
|
||||||
m_skr_last_error_set("either shaders_input != 1 or count == 0");
|
m_skr_last_error_set("either shaders_input != 1 or count == 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t count = size / sizeof(SkrShader);
|
||||||
|
|
||||||
GLuint* shaders = (GLuint*)malloc(sizeof(GLuint) * count);
|
GLuint* shaders = (GLuint*)malloc(sizeof(GLuint) * count);
|
||||||
if (!shaders) {
|
if (!shaders) {
|
||||||
m_skr_last_error_set("shaders_input == NULL");
|
m_skr_last_error_set("shaders_input == NULL");
|
||||||
|
|
@ -930,7 +940,7 @@ m_skr_gl_create_program_from_shaders(const SkrShader* shaders_input,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
const SkrShader* s = &shaders_input[i];
|
const SkrShader* s = &shader_array[i];
|
||||||
GLuint shader = 0;
|
GLuint shader = 0;
|
||||||
|
|
||||||
if (s->Source) {
|
if (s->Source) {
|
||||||
|
|
@ -1077,6 +1087,27 @@ static inline void m_skr_gl_renderer_render(SkrState* s) {
|
||||||
if (mesh->VAO == 0 || mesh->VertexCount == 0)
|
if (mesh->VAO == 0 || mesh->VertexCount == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (g_skr_camera) {
|
||||||
|
mat4 projection;
|
||||||
|
glm_perspective(
|
||||||
|
glm_rad(g_skr_camera->FOV),
|
||||||
|
(float)s->Window->Width /
|
||||||
|
(float)s->Window->Height,
|
||||||
|
0.1f, 100.0f, projection);
|
||||||
|
m_skr_gl_shader_set_mat4(
|
||||||
|
mesh->Backend.GL.Program, "projection",
|
||||||
|
projection);
|
||||||
|
|
||||||
|
vec3 center;
|
||||||
|
glm_vec3_add(g_skr_camera->Position,
|
||||||
|
g_skr_camera->Front, center);
|
||||||
|
mat4 view;
|
||||||
|
glm_lookat(g_skr_camera->Position, center,
|
||||||
|
g_skr_camera->Up, view);
|
||||||
|
m_skr_gl_shader_set_mat4(
|
||||||
|
mesh->Backend.GL.Program, "view", view);
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(mesh->Backend.GL.Program);
|
glUseProgram(mesh->Backend.GL.Program);
|
||||||
glBindVertexArray(mesh->VAO);
|
glBindVertexArray(mesh->VAO);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, mesh->VertexCount);
|
glDrawArrays(GL_TRIANGLES, 0, mesh->VertexCount);
|
||||||
|
|
@ -1265,6 +1296,54 @@ static inline int SkrWindowShouldClose(SkrWindow* w) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void SkrRendererInit(SkrState* s) {
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < s->ModelCount; ++i) {
|
||||||
|
SkrModel* model = &s->Models[i];
|
||||||
|
for (unsigned int j = 0; j < model->MeshCount; ++j) {
|
||||||
|
SkrMesh* mesh = &model->Meshes[j];
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &mesh->VAO);
|
||||||
|
glGenBuffers(1, &mesh->VBO);
|
||||||
|
glBindVertexArray(mesh->VAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
mesh->VertexCount * sizeof(SkrVertex),
|
||||||
|
mesh->Vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
0, 3, GL_FLOAT, GL_FALSE, sizeof(SkrVertex),
|
||||||
|
(void*)offsetof(SkrVertex, Position));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||||
|
sizeof(SkrVertex),
|
||||||
|
(void*)offsetof(SkrVertex, UV));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
for (unsigned int t = 0; t < mesh->TextureCount; ++t) {
|
||||||
|
SkrTexture* tex = &mesh->Textures[t];
|
||||||
|
if (tex->Path && !tex->ID) {
|
||||||
|
unsigned int tex_id;
|
||||||
|
if (m_skr_gl_load_texture_2d_from_path(
|
||||||
|
tex->Path, &tex_id)) {
|
||||||
|
tex->ID = tex_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(mesh->Backend.GL.Program);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void SkrRendererRender(SkrState* s) {
|
static inline void SkrRendererRender(SkrState* s) {
|
||||||
if (!s || !s->Window)
|
if (!s || !s->Window)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1316,7 +1395,7 @@ static inline GLuint m_skr_gl_triangle(SkrState* s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
mesh.Backend.GL.Program =
|
mesh.Backend.GL.Program =
|
||||||
m_skr_gl_create_program_from_shaders(shaders, 2);
|
m_skr_gl_create_program_from_shaders(shaders, sizeof(shaders));
|
||||||
glUseProgram(mesh.Backend.GL.Program);
|
glUseProgram(mesh.Backend.GL.Program);
|
||||||
|
|
||||||
glGenVertexArrays(1, &mesh.VAO);
|
glGenVertexArrays(1, &mesh.VAO);
|
||||||
|
|
@ -1355,8 +1434,6 @@ static inline void SkrTriangle(SkrState* s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SkrInitCamera(SkrState* s, SkrShader vert) {}
|
|
||||||
|
|
||||||
static inline void SkrCaptureCursor(SkrState* s) {
|
static inline void SkrCaptureCursor(SkrState* s) {
|
||||||
if (s->Window->Backend.Type == SKR_BACKEND_WINDOW_GLFW) {
|
if (s->Window->Backend.Type == SKR_BACKEND_WINDOW_GLFW) {
|
||||||
glfwSetInputMode(s->Window->Backend.Handler.GLFW, GLFW_CURSOR,
|
glfwSetInputMode(s->Window->Backend.Handler.GLFW, GLFW_CURSOR,
|
||||||
|
|
@ -1364,6 +1441,87 @@ static inline void SkrCaptureCursor(SkrState* s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void m_skr_gl_mesh_init(SkrMesh* m) {
|
||||||
|
if (!m || !m->Vertices || m->VertexCount == 0) {
|
||||||
|
m_skr_last_error_set("Invalid mesh: missing vertices or count");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &m->VAO);
|
||||||
|
|
||||||
|
glGenBuffers(1, &m->VBO);
|
||||||
|
|
||||||
|
glBindVertexArray(m->VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m->VBO);
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(SkrVertex) * m->VertexCount,
|
||||||
|
m->Vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// vertex positions
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(SkrVertex),
|
||||||
|
(void*)0);
|
||||||
|
// vertex normals
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(SkrVertex),
|
||||||
|
(void*)offsetof(SkrVertex, Normal));
|
||||||
|
// vertex texture coords
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(SkrVertex),
|
||||||
|
(void*)offsetof(SkrVertex, UV));
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
if (m->Textures && m->TextureCount > 0) {
|
||||||
|
for (unsigned int i = 0; i < m->TextureCount; ++i) {
|
||||||
|
SkrTexture* tex = &m->Textures[i];
|
||||||
|
|
||||||
|
if (!tex->Path) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int id = 0;
|
||||||
|
if (!m_skr_gl_load_texture_2d_from_path(tex->Path,
|
||||||
|
&id)) {
|
||||||
|
fprintf(stderr, "Failed to load texture: %s\n",
|
||||||
|
tex->Path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex->ID = id;
|
||||||
|
tex->Type = (i == 0) ? SKR_TEXTURE_DIFFUSE
|
||||||
|
: SKR_TEXTURE_SPECULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_skr_last_error_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bind all textures of a mesh to consecutive texture units.
|
||||||
|
* Starts at GL_TEXTURE0 and binds each SkrTexture.ID in order.
|
||||||
|
*
|
||||||
|
* @param mesh The mesh whose textures to bind.
|
||||||
|
*/
|
||||||
|
static inline void m_skr_gl_mesh_bind_textures(const SkrMesh* mesh) {
|
||||||
|
if (!mesh || !mesh->Textures || mesh->TextureCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mesh->TextureCount; ++i) {
|
||||||
|
const SkrTexture* tex = &mesh->Textures[i];
|
||||||
|
|
||||||
|
if (tex->ID == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i); // activate unit N
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex->ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue