From a0be00407fc920ffc0cad5b3378237790bfde908 Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 17 Sep 2024 21:37:13 +0200 Subject: [PATCH] feat: implemented default shader --- resources/default_shader.fs | 20 ++++++++++++ resources/default_shader.vs | 25 +++++++++++++++ resources/spacefighter.glb | Bin 19368 -> 32488 bytes resources/wabbit_alpha.png | Bin 496 -> 0 bytes src/core/mesh_render_entity.c | 12 ++++++- src/core/mesh_render_entity.h | 1 + src/core/resources.c | 57 +++++++++++++++++++++++++++++----- src/core/resources.h | 3 ++ src/main.c | 28 +++++++++++------ src/utils | 2 +- 10 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 resources/default_shader.fs create mode 100644 resources/default_shader.vs delete mode 100644 resources/wabbit_alpha.png diff --git a/resources/default_shader.fs b/resources/default_shader.fs new file mode 100644 index 0000000..86eb57c --- /dev/null +++ b/resources/default_shader.fs @@ -0,0 +1,20 @@ +#version 330 + +in vec2 fragTexCoord; // texture coordinate +in vec3 fragNormal; // normal direction + +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +out vec4 finalColor; + +uniform vec3 lightDirection; // direction of light +uniform vec4 ambient; + +void main() { + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 light_dot = vec3(pow(dot(fragNormal, lightDirection)-0.2, 3.0)); + finalColor = texelColor * colDiffuse * vec4(light_dot, 1.0); + finalColor += texelColor * (ambient/10.0) * colDiffuse; + finalColor = pow(finalColor, vec4(vec3(0.6), 1.0)); +} diff --git a/resources/default_shader.vs b/resources/default_shader.vs new file mode 100644 index 0000000..93dac26 --- /dev/null +++ b/resources/default_shader.vs @@ -0,0 +1,25 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec3 fragNormal; + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragNormal = normalize(vec3(matModel * vec4(vertexNormal, 1.0))); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/resources/spacefighter.glb b/resources/spacefighter.glb index ea4aea37d45b8cb6acce19ad9183313cd7feb565..7178bcdc9dfe1d3904100265a1611deb47220a88 100644 GIT binary patch literal 32488 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 LwLsQ_9q0c5P|=i4 literal 19368 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 OVJR`D6MuoJM*a_!+ch)* diff --git a/resources/wabbit_alpha.png b/resources/wabbit_alpha.png deleted file mode 100644 index db4081fec5a801d4b6f2beeafca4a0dffbe5d333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 496 zcmVkdg0005ENklL3}oV1UkKwj zR!p+}SzGQ1Lo9AdRLcO<$^;0*lnoX=&J$YA5LPS!VBaua0r+$qJpH~0V9wxJFD(PA z&1m1B(Y*nPt}2}R`nVc48-pGk+oY0f~#SXp#a2JUX%FH!|NU~u>Ux$NYShaVV# zxM9^@%P2RMzigf8kd2c+5PIidYcGl)n+CSN2R)N`?X1;_lBc?+5VD(*r^hK+fbnP$;y&koBO>l}`piuGtifTyxd7z=IjkKWV z<|mKp*eBaXAq@k&-1Y5Kafh=3yHrmDg>;#_$(i-TN-@4D-e)DRsn`coS6h^eTRRO$T00ld@}3ZH m<2RER$xNr(&-FgA{~G{&g0wAMhB_|*0000model); + GetShaderResource("default_shader", &self->shader); return CreateSceneNode(MeshRenderEntity_as_SceneNodeEntity(self)); } @@ -36,15 +37,24 @@ void MeshRenderEntityEnterTree(MeshRenderEntity *self) { SceneNodeEntity parent_entity = self->node->parent->entity; self->transform = TC_CAST(parent_entity, Transformable); LoadResource(self->model.handle); + LoadResource(self->shader.handle); + Vector3 light_direction = Vector3Normalize((Vector3){1.f, 1.f, 0.f}); + SetShaderValue(*self->shader.resource, GetShaderLocation(*self->shader.resource, "lightDirection"), &light_direction, SHADER_UNIFORM_VEC3); + SetShaderValue(*self->shader.resource, GetShaderLocation(*self->shader.resource, "ambient"), &BLACK, SHADER_UNIFORM_VEC4); + for(size_t i = 0; i < self->model.resource->materialCount; ++i) + self->model.resource->materials[i].shader = *self->shader.resource; AddRenderable(MeshRenderEntity_as_Renderable(self)); } void MeshRenderEntityExitTree(MeshRenderEntity *self) { ReleaseResource(self->model.handle); + ReleaseResource(self->shader.handle); RemoveRenderable(MeshRenderEntity_as_Renderable(self)); } void MeshRenderEntityDraw(MeshRenderEntity *self) { self->model.resource->transform = TransformGetMatrix(self->transform.tc->get_global_transform(self->transform.data)); - DrawModel(*self->model.resource, (Vector3){0.f, 0.f, 0.f}, 1.f, WHITE); + BeginShaderMode(*self->shader.resource); + DrawModel(*self->model.resource, Vector3Zero(), 1.0f, WHITE); + EndShaderMode(); } diff --git a/src/core/mesh_render_entity.h b/src/core/mesh_render_entity.h index ca726cb..3e185cc 100644 --- a/src/core/mesh_render_entity.h +++ b/src/core/mesh_render_entity.h @@ -12,6 +12,7 @@ typedef struct MeshRenderEntity { SceneNode *node; Transformable transform; ModelResource model; + ShaderResource shader; } MeshRenderEntity; extern SceneNode *CreateMeshRenderEntity(char const *resource_path); diff --git a/src/core/resources.c b/src/core/resources.c index 3160d36..fc53900 100644 --- a/src/core/resources.c +++ b/src/core/resources.c @@ -8,7 +8,7 @@ char const *RESOURCE_DIRECTORY = "resources"; typedef enum ResourceType { - RESOURCE_MODEL, RESOURCE_TEXTURE, + RESOURCE_MODEL, RESOURCE_TEXTURE, RESOURCE_SHADER, RESOURCE_MAX } ResourceType; @@ -21,6 +21,7 @@ typedef struct ResourceContainer { union { Model model; Texture texture; + Shader shader; }; } ResourceContainer; @@ -31,9 +32,11 @@ static void Internal_LoadModelResource(ResourceContainer *resource); static void Internal_UnloadModelResource(ResourceContainer *resource); static void Internal_LoadTextureResource(ResourceContainer *resource); static void Internal_UnloadTextureResource(ResourceContainer *resource); +static void Internal_LoadShaderResource(ResourceContainer *resource); +static void Internal_UnloadShaderResource(ResourceContainer *resource); -LoadResourceFn g_load_functions[] = {Internal_LoadModelResource, Internal_LoadTextureResource}; -UnloadResourceFn g_unload_functions[] = {Internal_UnloadModelResource, Internal_UnloadTextureResource}; +LoadResourceFn g_load_functions[] = {Internal_LoadModelResource, Internal_LoadTextureResource, Internal_LoadShaderResource}; +UnloadResourceFn g_unload_functions[] = {Internal_UnloadModelResource, Internal_UnloadTextureResource, Internal_UnloadShaderResource}; static HashMap g_resource_map; static FilePathList g_resource_files; @@ -52,6 +55,9 @@ static ResourceType ResourceGetTypeFromPath(char const *path) { // Model files if(IsFileExtension(path, ".glb")) return RESOURCE_MODEL; if(IsFileExtension(path, ".gltf")) return RESOURCE_MODEL; + // Shader files + if(IsFileExtension(path, ".fg")) return RESOURCE_SHADER; + if(IsFileExtension(path, ".vs")) return RESOURCE_SHADER; return RESOURCE_MAX; } @@ -85,13 +91,23 @@ void Internal_IndexResourceDirectory() { .is_loaded = false, .use_counter = 0, .path = g_resource_files.paths[i], - .name = GetFileName(g_resource_files.paths[i]), + .name = GetFileNameWithoutExt(g_resource_files.paths[i]), .type = ResourceGetTypeFromPath(g_resource_files.paths[i]) }; // only index resources that the engine knows how to load - if(placeholder.type != RESOURCE_MAX) { + if(placeholder.type == RESOURCE_SHADER) { // shaders are made up of two files, so their paths are treated differently + // if the shader has already been added, don't accidentally add it twice. + ResourceContainer *found_container = hash_map_get_as(ResourceContainer, &g_resource_map, &placeholder.name); + if(found_container == NULL) { + placeholder.path = GetDirectoryPath(placeholder.path); + LOG_INFO("Internal_IndexResourceDirectory: Indexing %s as %s", placeholder.path, placeholder.name); + hash_map_insert(&g_resource_map, &placeholder.name, &placeholder); + LOG_INFO("hash: %zu", strhash(placeholder.name)); + } + } else if(placeholder.type != RESOURCE_MAX) { // regular resources LOG_INFO("Internal_IndexResourceDirectory: Indexing %s as %s", placeholder.path, placeholder.name); hash_map_insert(&g_resource_map, &placeholder.name, &placeholder); + LOG_INFO("hash: %zu", strhash(placeholder.name)); } } } @@ -104,7 +120,8 @@ void InitializeResourceSubsystem() { void CleanResourceSubsystem() { List resources = hash_map_values(&g_resource_map); list_foreach(ResourceContainer *,resource, &resources) - g_unload_functions[resource->type](resource); + if(resource->is_loaded) + g_unload_functions[resource->type](resource); hash_map_empty(&g_resource_map); UnloadDirectoryFiles(g_resource_files); } @@ -128,7 +145,7 @@ bool GetTextureResource(char const *path, TextureResource *out) { *out = ResourceEmpty(Texture); // assert some assumptions about the found resource ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path); - ASSERT_RETURN(container->type != RESOURCE_TEXTURE, false, "GetTextureResource: Resource %s is not a Texture.", path); + ASSERT_RETURN(container->type == RESOURCE_TEXTURE, false, "GetTextureResource: Resource %s is not a Texture.", path); *out = (TextureResource) { .handle = container, .resource = &container->texture @@ -136,6 +153,18 @@ bool GetTextureResource(char const *path, TextureResource *out) { return true; } +bool GetShaderResource(char const *path, ShaderResource *out) { + ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path); + *out = ResourceEmpty(Shader); + ASSERT_RETURN(container != NULL, false, "GetShaderResource: Resource %s not in index.", path); + ASSERT_RETURN(container->type == RESOURCE_SHADER, false, "GetShaderResource: Resource %s is not a Shader.", path); + *out = (ShaderResource) { + .handle = container, + .resource = &container->shader + }; + return true; +} + bool IsResourceLoaded(ResourceHandle handle) { return handle->is_loaded; } @@ -157,6 +186,7 @@ void ReleaseResource(ResourceHandle handle) { static void Internal_LoadModelResource(ResourceContainer *resource) { + LOG_INFO("Loading model from: %s", resource->path); resource->model = LoadModel(resource->path); } @@ -176,3 +206,16 @@ void Internal_UnloadTextureResource(ResourceContainer *resource) { UnloadTexture(resource->texture); resource->texture = (Texture){0}; } + +static +void Internal_LoadShaderResource(ResourceContainer *resource) { + resource->shader = LoadShader(TextFormat("%s/%s.vs", resource->path, resource->name), TextFormat("%s/%s.fs", resource->path, resource->name)); + ASSERT_RETURN(IsShaderReady(resource->shader),, "Internal_LoadShaderResource: Shader failed to load."); +} + +static +void Internal_UnloadShaderResource(ResourceContainer *resource) { + UnloadShader(resource->shader); + resource->shader = (Shader){0}; +} + diff --git a/src/core/resources.h b/src/core/resources.h index 1b1c5ca..2fd43c1 100644 --- a/src/core/resources.h +++ b/src/core/resources.h @@ -11,6 +11,7 @@ typedef struct ResourceContainer* ResourceHandle; ResourceType(Model); ResourceType(Texture); +ResourceType(Shader); //! Allocate and initialize memory required to operate resource subsystem extern void InitializeResourceSubsystem(); @@ -20,6 +21,8 @@ extern void CleanResourceSubsystem(); extern bool GetModelResource(char const *path, ModelResource *out); //! Get indexed texture from resources. extern bool GetTextureResource(char const *path, TextureResource *out); +//! Get indexed shader from resources. +extern bool GetShaderResource(char const *path, ShaderResource *out); //! Check if a resource is loaded or not. extern bool IsResourceLoaded(ResourceHandle handle); diff --git a/src/main.c b/src/main.c index fa079c6..9de5740 100644 --- a/src/main.c +++ b/src/main.c @@ -9,22 +9,30 @@ #include "utils/debug.h" Scene *CreateInitialScene() { + Transformable transformable; + Transform transform; SceneNode *root = CreateTransformNode(); + // create a model with a camera attached as a child of the root of the scene SceneNode *model_parent = CreateTransformNode(); SceneNodeAddChild(root, model_parent); - - SceneNode *camera_parent = CreateTransformNode(); - SceneNodeAddChild(model_parent, camera_parent); - // set camera parent location - Transformable transformable = TC_CAST(camera_parent->entity, Transformable); - Transform transform = transformable.tc->get_transform(transformable.data); - transform.translation = (Vector3){0.f, 3.f, -10.f}; + // create the rest of the scene with a mesh and a functionality node + SceneNodeAddChild(model_parent, CreateMeshRenderEntity("spacefighter")); + SceneNodeAddChild(model_parent, CreateTestObject()); + transformable = TC_CAST(model_parent->entity, Transformable); + transform = transformable.tc->get_global_transform(transformable.data); + transform.translation.y += 10; + transformable.tc->set_global_transform(transformable.data, transform); + // create a camera attached to it's own transform node + SceneNode *camera_parent = CreateTransformNode(); // the parent + SceneNodeAddChild(model_parent, camera_parent); // attached to the model parent + // set camera parent offset + transformable = TC_CAST(camera_parent->entity, Transformable); + transform = transformable.tc->get_transform(transformable.data); + transform.translation = (Vector3){-3.f, 3.f, -10.f}; transform.rotation = QuaternionFromEuler(7.5f * DEG2RAD, 0.f, 0.f); transformable.tc->set_transform(transformable.data, transform); - + // create the camera and attach it to the dedicated transform node SceneNodeAddChild(camera_parent, CreateCameraNode()); - SceneNodeAddChild(model_parent, CreateMeshRenderEntity("spacefighter.glb")); - SceneNodeAddChild(model_parent, CreateTestObject()); return CreateScene(root); } diff --git a/src/utils b/src/utils index c4ec92f..af50174 160000 --- a/src/utils +++ b/src/utils @@ -1 +1 @@ -Subproject commit c4ec92fa82ab0bbee24f5c60ce36455a37d3696d +Subproject commit af50174b71853f3ca887fc0e064e88258c412f2c