#include "render/skybox.h" #include "render/shader.h" #include static const float CUBE_VERTICES[] = { -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, }; bool Skybox_init(Skybox *sky) { memset(sky, 0, sizeof(*sky)); sky->program = Shader_load("shaders/skybox.vert", "shaders/skybox.frag"); if (!sky->program) return false; sky->u_view = glGetUniformLocation(sky->program, "view"); sky->u_projection = glGetUniformLocation(sky->program, "projection"); sky->u_sky_time = glGetUniformLocation(sky->program, "skyTime"); sky->u_sun_dir = glGetUniformLocation(sky->program, "sunDirection"); sky->u_light_color = glGetUniformLocation(sky->program, "lightColor"); sky->u_sky_top = glGetUniformLocation(sky->program, "skyTop"); sky->u_sky_horizon = glGetUniformLocation(sky->program, "skyHorizon"); sky->u_day_factor = glGetUniformLocation(sky->program, "dayFactor"); sky->u_overcast = glGetUniformLocation(sky->program, "overcast"); glGenVertexArrays(1, &sky->vao); glGenBuffers(1, &sky->vbo); glBindVertexArray(sky->vao); glBindBuffer(GL_ARRAY_BUFFER, sky->vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VERTICES), CUBE_VERTICES, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); glEnableVertexAttribArray(0); glBindVertexArray(0); return true; } static void setVec3(GLint loc, Vec3 v) { glUniform3f(loc, v.x, v.y, v.z); } void Skybox_draw(const Skybox *sky, const Renderer *renderer, const Camera *camera, const Lighting *light) { Mat4 view = camera->view; view.m[12] = view.m[13] = view.m[14] = 0.0f; /* sky follows the camera */ glDisable(GL_CULL_FACE); /* seen from inside */ glDepthFunc(GL_LEQUAL); glUseProgram(sky->program); glUniformMatrix4fv(sky->u_view, 1, GL_FALSE, view.m); glUniformMatrix4fv(sky->u_projection, 1, GL_FALSE, camera->projection.m); glUniform1f(sky->u_sky_time, renderer->time); glUniform1f(sky->u_day_factor, light->day_factor); glUniform1f(sky->u_overcast, light->overcast); setVec3(sky->u_sun_dir, light->sun_direction); setVec3(sky->u_light_color, light->light_color); setVec3(sky->u_sky_top, light->sky_top); setVec3(sky->u_sky_horizon, light->sky_horizon); glBindVertexArray(sky->vao); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glDepthFunc(GL_LESS); } void Skybox_shutdown(Skybox *sky) { if (sky->vbo) glDeleteBuffers(1, &sky->vbo); if (sky->vao) glDeleteVertexArrays(1, &sky->vao); Shader_destroy(&sky->program); memset(sky, 0, sizeof(*sky)); }