Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Light set up:
- ```c
- void smLight3D_MakePointLight(smLight3D* light)
- {
- if (light->shadowTransforms == NULL)
- {
- light->shadowTransforms = smVector_Create(sizeof(mat4), 6);
- }
- vec3 lightPos;
- glm_vec3_copy(light->position, lightPos);
- mat4 shadowProj;
- glm_perspective(glm_rad(90.0f),
- (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, 0.1f,
- 150.0f, shadowProj);
- smVector_Clear(light->shadowTransforms);
- // For each face of the cube
- // +X direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, -1.0f, 0.0f};
- glm_vec3_add(lightPos, (vec3) {1.0f, 0.0f, 0.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // -X direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, -1.0f, 0.0f};
- glm_vec3_add(lightPos, (vec3) {-1.0f, 0.0f, 0.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // +Y direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, 0.0f, 1.0f};
- glm_vec3_add(lightPos, (vec3) {0.0f, 1.0f, 0.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // -Y direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, 0.0f, -1.0f};
- glm_vec3_add(lightPos, (vec3) {0.0f, -1.0f, 0.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // +Z direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, -1.0f, 0.0f};
- glm_vec3_add(lightPos, (vec3) {0.0f, 0.0f, 1.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // -Z direction
- {
- mat4 view, result;
- vec3 center, up = {0.0f, -1.0f, 0.0f};
- glm_vec3_add(lightPos, (vec3) {0.0f, 0.0f, -1.0f}, center);
- glm_lookat(lightPos, center, up, view);
- glm_mat4_mul(shadowProj, view, result);
- smVector_PushBack(light->shadowTransforms, &result);
- }
- // The OpenGL code remains the same
- glGenFramebuffers(1, &light->depthMapFBO);
- // Create depth cubemap texture
- glGenTextures(1, &light->depthCubemap);
- glBindTexture(GL_TEXTURE_CUBE_MAP, light->depthCubemap);
- for (unsigned int i = 0; i < 6; ++i)
- {
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
- GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT,
- 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
- }
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R,
- GL_CLAMP_TO_EDGE);
- // Attach depth cubemap as the FBO's depth buffer
- glBindFramebuffer(GL_FRAMEBUFFER, light->depthMapFBO);
- glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- light->depthCubemap, 0);
- glDrawBuffer(GL_NONE); // No color buffer is drawn
- glReadBuffer(GL_NONE); // No need to read from a buffer
- // Ensure framebuffer is complete
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
- GL_FRAMEBUFFER_COMPLETE)
- printf("Framebuffer not complete!\n");
- // Unbind framebuffer
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- ```
- Model rendering:
- ```c
- // This function is only a helper function that gets called later.
- void smModel_Draw(smModel* mesh, smTransform* trans, smShader shader)
- {
- if (mesh->meshes == NULL)
- {
- smModel_Create(mesh);
- }
- smShader_Use(shader);
- for (int i = 0; i < mesh->meshes->size; ++i)
- {
- smMesh* actualMesh = (smMesh*)smVector_Get(mesh->meshes, i);
- if (mesh->extractTexture)
- {
- // bind appropriate textures
- unsigned int diffuseNr = 1;
- unsigned int specularNr = 1;
- unsigned int normalNr = 1;
- unsigned int heightNr = 1;
- for (unsigned int j = 0; j < actualMesh->textures->size;
- j++)
- {
- glActiveTexture(GL_TEXTURE0 + j);
- char number[128];
- smTexture* texture =
- (smTexture*)smVector_Get(actualMesh->textures, j);
- if (strcmp(texture->type, "texture_diffuse") == 0)
- {
- strcpy(number, "");
- sprintf(number, "%d", diffuseNr++);
- }
- else if (strcmp(texture->type, "texture_specular") ==
- 0)
- {
- strcpy(number, "");
- sprintf(number, "%d", specularNr++);
- }
- else if (strcmp(texture->type, "texture_normal") == 0)
- {
- strcpy(number, "");
- sprintf(number, "%d", normalNr++);
- }
- else if (strcmp(texture->type, "texture_height") == 0)
- {
- strcpy(number, "");
- sprintf(number, "%d", heightNr++);
- }
- char name[128];
- sprintf(name, "%s", texture->type);
- // now set the sampler to the correct texture unit
- glUniform1i(glGetUniformLocation(shader.ID, name), j);
- unsigned int id = ((smTexture*)smVector_Get(
- actualMesh->textures, j))
- ->ID;
- // and finally bind the texture
- glBindTexture(GL_TEXTURE_2D, id);
- }
- }
- else
- {
- smShader_SetTexture2D(shader, "texture_diffuse",
- mesh->texture, 0);
- smShader_SetTexture2D(shader, "texture_normal",
- mesh->normalTexture, 1);
- smShader_SetTexture2D(shader, "texture_specular",
- mesh->specularTexture, 2);
- }
- smShader_SetMat4(shader, "projection", smState.persProj);
- mat4 view;
- smCamera_GetViewMatrix(&smState.camera, view);
- smShader_SetMat4(shader, "view", view);
- mat4 transform;
- glm_mat4_identity(transform);
- glm_translate(transform,
- (vec3) {trans->position[0], trans->position[1],
- trans->position[2]});
- glm_rotate(transform, trans->rotation[0],
- (vec3) {1.0f, 0.0f, 0.0f});
- glm_rotate(transform, trans->rotation[1],
- (vec3) {0.0f, 1.0f, 0.0f});
- glm_rotate(transform, trans->rotation[2],
- (vec3) {0.0f, 0.0f, 1.0f});
- glm_scale(transform, (vec3) {trans->scale[0], trans->scale[1],
- trans->scale[2]});
- smShader_SetMat4(shader, "model", transform);
- glActiveTexture(GL_TEXTURE0);
- // draw mesh
- glBindVertexArray(actualMesh->VAO);
- glDrawElements(GL_TRIANGLES,
- (unsigned int)actualMesh->indices->size,
- GL_UNSIGNED_INT, 0);
- glBindVertexArray(0);
- }
- }
- // Anytime you see the SM_ECS_ITER nonsense, just think of it as a for loop that loops over lights and models
- void smMeshRenderer_Sys()
- {
- SM_ECS_ITER_START(smState.scene, SM_ECS_COMPONENT_TYPE(smLight3D))
- {
- smLight3D* light =
- SM_ECS_GET(smState.scene, _entity, smLight3D);
- glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
- glBindFramebuffer(GL_FRAMEBUFFER, light->depthMapFBO);
- glClear(GL_DEPTH_BUFFER_BIT);
- smShader_Use(sm_shadowShader3d);
- #ifdef SM_DEBUG_LEVEL_1
- if (light->shadowTransforms == NULL)
- {
- smLight3D_MakePointLight(light);
- }
- #endif
- for (unsigned int i = 0; i < 6; ++i)
- {
- char uniform[64];
- sprintf(uniform, "shadowMatrices[%d]", i);
- mat4* shadowTransform =
- (mat4*)smVector_Get(light->shadowTransforms, i);
- smShader_SetMat4(sm_shadowShader3d, uniform,
- (*shadowTransform));
- }
- smShader_SetFloat(sm_shadowShader3d, "farPlane", 1000.0f);
- smShader_SetVec3(sm_shadowShader3d, "lightPos",
- light->position);
- SM_ECS_ITER_START(smState.scene,
- SM_ECS_COMPONENT_TYPE(smMeshRenderer))
- {
- smMeshRenderer* mesh =
- SM_ECS_GET(smState.scene, _entity, smMeshRenderer);
- smTransform* trans =
- SM_ECS_GET(smState.scene, _entity, smTransform);
- mat4 transform;
- glm_mat4_identity(transform);
- glm_translate(transform, (vec3) {trans->position[0],
- trans->position[1],
- trans->position[2]});
- glm_rotate(transform, trans->rotation[0],
- (vec3) {1.0f, 0.0f, 0.0f});
- glm_rotate(transform, trans->rotation[1],
- (vec3) {0.0f, 1.0f, 0.0f});
- glm_rotate(transform, trans->rotation[2],
- (vec3) {0.0f, 0.0f, 1.0f});
- glm_scale(transform,
- (vec3) {trans->scale[0], trans->scale[1],
- trans->scale[2]});
- smShader_SetMat4(sm_shadowShader3d, "model", transform);
- smModel_Draw(mesh, trans, sm_shadowShader3d);
- }
- SM_ECS_ITER_END();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- SM_ECS_ITER_END();
- glViewport(0, 0, smState.window->width, smState.window->height);
- // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- smShader_Use(sm_shader3d);
- SM_ECS_ITER_START(smState.scene,
- SM_ECS_COMPONENT_TYPE(smMeshRenderer))
- {
- smMeshRenderer* mesh =
- SM_ECS_GET(smState.scene, _entity, smMeshRenderer);
- smTransform* trans =
- SM_ECS_GET(smState.scene, _entity, smTransform);
- int lightCount = 0;
- SM_ECS_ITER_START(smState.scene,
- SM_ECS_COMPONENT_TYPE(smLight3D))
- {
- smLight3D* light =
- SM_ECS_GET(smState.scene, _entity, smLight3D);
- glActiveTexture(GL_TEXTURE0 + lightCount);
- glBindTexture(GL_TEXTURE_CUBE_MAP, light->depthCubemap);
- char uniformName[64];
- sprintf(uniformName, "depthMaps[%d]", lightCount);
- smShader_SetInt(sm_shader3d, uniformName, lightCount);
- sprintf(uniformName, "lights[%d].pos", lightCount);
- smShader_SetVec3(sm_shader3d, uniformName,
- light->position);
- sprintf(uniformName, "lights[%d].radius", lightCount);
- smShader_SetFloat(sm_shader3d, uniformName,
- light->radius);
- sprintf(uniformName, "lights[%d].color", lightCount);
- smShader_SetVec4(sm_shader3d, uniformName, light->color);
- sprintf(uniformName, "lights[%d].intensity", lightCount);
- smShader_SetFloat(sm_shader3d, uniformName,
- light->intensity);
- sprintf(uniformName, "lights[%d].castShadows",
- lightCount);
- smShader_SetBool(sm_shader3d, uniformName,
- light->castsShadows);
- lightCount++;
- }
- SM_ECS_ITER_END();
- smModel_Draw(mesh, trans, sm_shader3d);
- }
- SM_ECS_ITER_END();
- }
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement