twn_skybox.c
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
#include "twn_rendering_c.h"
|
||||
#include "twn_util.h"
|
||||
#include "twn_util_c.h"
|
||||
#include "twn_config.h"
|
||||
#include "twn_engine_context_c.h"
|
||||
#include "twn_text_c.h"
|
||||
@ -464,3 +465,152 @@ void finally_draw_text(FontData const *font_data,
|
||||
size_t get_text_payload_size(void) {
|
||||
return sizeof (ElementIndexedQuadWithoutColor);
|
||||
}
|
||||
|
||||
static void load_cubemap_side(const char *path, GLenum target) {
|
||||
SDL_Surface *surface = textures_load_surface(path);
|
||||
/* TODO: sanity check whether all of them have same dimensions? */
|
||||
glTexImage2D(target,
|
||||
0,
|
||||
GL_RGBA8,
|
||||
surface->w, surface->h,
|
||||
0,
|
||||
surface->format->BytesPerPixel == 4 ? GL_RGBA : GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
surface->pixels);
|
||||
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);
|
||||
|
||||
SDL_free(surface->pixels);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
void finally_render_skybox(char *paths) {
|
||||
static GLuint cubemap = 0;
|
||||
static char *paths_cache = NULL;
|
||||
|
||||
bool loading_needed = false;
|
||||
|
||||
/* drop it */
|
||||
if (!paths_cache || (SDL_strcmp(paths_cache, paths) != 0)) {
|
||||
if (cubemap)
|
||||
glDeleteTextures(1, &cubemap);
|
||||
glGenTextures(1, &cubemap);
|
||||
if (paths_cache)
|
||||
SDL_free(paths_cache);
|
||||
paths_cache = paths;
|
||||
loading_needed = true;
|
||||
}
|
||||
|
||||
Matrix4 camera_look_at_matrix_solipsist = camera_look_at_matrix;
|
||||
camera_look_at_matrix_solipsist.row[3].x = 0;
|
||||
camera_look_at_matrix_solipsist.row[3].y = 0;
|
||||
camera_look_at_matrix_solipsist.row[3].z = 0;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&camera_look_at_matrix_solipsist.row[0].x);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
||||
|
||||
/* note: assumes that space pipeline is applied already */
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (loading_needed) {
|
||||
/* load all the sides */
|
||||
char *expanded = expand_asterisk(paths, "up");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
|
||||
SDL_free(expanded);
|
||||
|
||||
expanded = expand_asterisk(paths, "down");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
|
||||
SDL_free(expanded);
|
||||
|
||||
expanded = expand_asterisk(paths, "east");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_X);
|
||||
SDL_free(expanded);
|
||||
|
||||
expanded = expand_asterisk(paths, "north");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
|
||||
SDL_free(expanded);
|
||||
|
||||
expanded = expand_asterisk(paths, "west");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
|
||||
SDL_free(expanded);
|
||||
|
||||
expanded = expand_asterisk(paths, "south");
|
||||
load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
|
||||
SDL_free(expanded);
|
||||
}
|
||||
|
||||
/* TODO: use lists at the very least */
|
||||
/* TODO: figure out which coordinates to use to not have issues with far z */
|
||||
|
||||
glBegin(GL_QUADS); {
|
||||
/* up */
|
||||
glTexCoord3f(50.f, 50.f, 50.f);
|
||||
glVertex3f(50.f, 50.f, 50.f);
|
||||
glTexCoord3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glTexCoord3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glTexCoord3f(50.f, 50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, -50.f);
|
||||
|
||||
/* down */
|
||||
glTexCoord3f(50.f, -50.f, 50.f);
|
||||
glVertex3f(50.f, -50.f, 50.f);
|
||||
glTexCoord3f(50.f, -50.f, -50.f);
|
||||
glVertex3f(50.f, -50.f, -50.f);
|
||||
glTexCoord3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glTexCoord3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
|
||||
/* east */
|
||||
glTexCoord3f(50.f, -50.f, 50.f);
|
||||
glVertex3f(50.f, -50.f, 50.f);
|
||||
glTexCoord3f(50.f, 50.f, 50.f);
|
||||
glVertex3f(50.f, 50.f, 50.f);
|
||||
glTexCoord3f(50.f, 50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, -50.f);
|
||||
glTexCoord3f(50.f, -50.f, -50.f);
|
||||
glVertex3f(50.f, -50.f, -50.f);
|
||||
|
||||
/* west */
|
||||
glTexCoord3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glTexCoord3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glTexCoord3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
glTexCoord3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
|
||||
/* north */
|
||||
glTexCoord3f(-50.f, -50.f, 50.f);
|
||||
glVertex3f(-50.f, -50.f, 50.f);
|
||||
glTexCoord3f(-50.f, 50.f, 50.f);
|
||||
glVertex3f(-50.f, 50.f, 50.f);
|
||||
glTexCoord3f(50.f, 50.f, 50.f);
|
||||
glVertex3f(50.f, 50.f, 50.f);
|
||||
glTexCoord3f(50.f, -50.f, 50.f);
|
||||
glVertex3f(50.f, -50.f, 50.f);
|
||||
|
||||
/* south */
|
||||
glTexCoord3f(-50.f, -50.f, -50.f);
|
||||
glVertex3f(-50.f, -50.f, -50.f);
|
||||
glTexCoord3f(50.f, -50.f, -50.f);
|
||||
glVertex3f(50.f, -50.f, -50.f);
|
||||
glTexCoord3f(50.f, 50.f, -50.f);
|
||||
glVertex3f(50.f, 50.f, -50.f);
|
||||
glTexCoord3f(-50.f, 50.f, -50.f);
|
||||
glVertex3f(-50.f, 50.f, -50.f);
|
||||
} glEnd();
|
||||
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ void clear_draw_buffer(void) {
|
||||
(1.0f / 255) * 230,
|
||||
(1.0f / 255) * 230, 1);
|
||||
|
||||
/* TODO: don't clear color when skybox is applied? */
|
||||
glClear(GL_COLOR_BUFFER_BIT |
|
||||
GL_DEPTH_BUFFER_BIT |
|
||||
GL_STENCIL_BUFFER_BIT);
|
||||
|
@ -135,6 +135,7 @@ void render(void) {
|
||||
|
||||
clear_draw_buffer();
|
||||
render_space();
|
||||
render_skybox(); /* after space, as to use depth buffer for early rejection */
|
||||
render_2d();
|
||||
swap_buffers();
|
||||
}
|
||||
|
@ -219,4 +219,8 @@ void finally_draw_text(FontData const *font_data,
|
||||
Color color,
|
||||
VertexBuffer buffer);
|
||||
|
||||
void render_skybox(void);
|
||||
|
||||
void finally_render_skybox(char *paths_in_use);
|
||||
|
||||
#endif
|
||||
|
26
src/rendering/twn_skybox.c
Normal file
26
src/rendering/twn_skybox.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include "twn_rendering.h"
|
||||
#include "twn_rendering_c.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
char *paths_in_use;
|
||||
|
||||
void push_skybox(const char *paths) {
|
||||
if (paths_in_use && SDL_strcmp(paths, paths_in_use) == 0)
|
||||
return;
|
||||
|
||||
if (paths_in_use)
|
||||
SDL_free(paths_in_use);
|
||||
|
||||
paths_in_use = SDL_strdup(paths);
|
||||
}
|
||||
|
||||
|
||||
void render_skybox(void) {
|
||||
if (!paths_in_use)
|
||||
return;
|
||||
|
||||
/* note: ownership of 'paths_in_use' goes there */
|
||||
finally_render_skybox(paths_in_use);
|
||||
paths_in_use = NULL;
|
||||
}
|
Reference in New Issue
Block a user