twn_skybox.c

This commit is contained in:
2024-09-26 21:02:56 +03:00
parent 0fe1023667
commit c0dcdf8c0a
22 changed files with 268 additions and 13 deletions
+1
View File
@@ -1,3 +1,4 @@
*.png filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.xm filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
+3
View File
@@ -99,6 +99,7 @@ set(TWN_SOURCE_FILES
src/rendering/twn_text.c
src/rendering/twn_triangles.c
src/rendering/twn_circles.c
src/rendering/twn_skybox.c
# for dynamic load based solution main is compiled in a separate target
$<$<NOT:$<BOOL:${TWN_FEATURE_DYNLIB_GAME}>>:src/twn_main.c
@@ -300,6 +301,8 @@ function(use_townengine target sources output_directory data_dir)
set(TWN_BOOTSTRAP_EXEC_ARGS
"$<IF:$<BOOL:${TWN_ARCHIVE_DATA}>,--data-dir ./data.${PACKAGE_EXTENSION},--data-dir ${data_dir}>")
# todo: generate by python script instead
# todo: handle the case where no numerical trace exists
string(JOIN "\n" TWN_BOOTSTRAP_SH
"#!/bin/env sh"
"cd \"$(dirname \"$0\")\""
+13 -11
View File
@@ -58,28 +58,30 @@ static void ingame_tick(State *state) {
for (int y = 64; y--;) {
for (int x = 64; x--;) {
float d0 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 20 - 6;
float d1 = stb_perlin_noise3((float)(x + 1) * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 20 - 6;
float d2 = stb_perlin_noise3((float)(x + 1) * TERRAIN_FREQUENCY, (float)(y - 1) * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 20 - 6;
float d3 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)(y - 1) * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 20 - 6;
float d0 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
float d1 = stb_perlin_noise3((float)(x + 1) * TERRAIN_FREQUENCY, (float)y * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
float d2 = stb_perlin_noise3((float)(x + 1) * TERRAIN_FREQUENCY, (float)(y - 1) * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
float d3 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)(y - 1) * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 3 - 6;
unfurl_triangle("/assets/grass.gif",
unfurl_triangle("/assets/grass.png",
(Vec3){ (float)x, d0, (float)y },
(Vec3){ (float)x + 1, d1, (float)y },
(Vec3){ (float)x, d3, (float)y - 1 },
(Vec2sh){ 1024, 768 },
(Vec2sh){ 1024, 0 },
(Vec2sh){ 0, 768 });
(Vec2sh){ 128, 128 },
(Vec2sh){ 128, 0 },
(Vec2sh){ 0, 128 });
unfurl_triangle("/assets/grass.gif",
unfurl_triangle("/assets/grass.png",
(Vec3){ (float)x + 1, d1, (float)y },
(Vec3){ (float)x + 1, d2, (float)y - 1 },
(Vec3){ (float)x, d3, (float)y - 1 },
(Vec2sh){ 1024, 0 },
(Vec2sh){ 128, 0 },
(Vec2sh){ 0, 0 },
(Vec2sh){ 0, 768 });
(Vec2sh){ 0, 128 });
}
}
push_skybox("/assets/miramar/miramar_*.tga");
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

BIN
View File
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
THIS SKY WAS UPDATED AT THE 27TH
THE ORIG HAD SOME ERRORS
MIRAMAR
high res 1024^2 environment map
ships as TGA.
By Jockum Skoglund aka hipshot
hipshot@zfight.com
www.zfight.com
Stockholm, 2005 08 25
Modify however you like, just cred me for my work, maybe link to my page.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -73,4 +73,7 @@ TWN_API void unfurl_triangle(const char *path,
/* pushes a camera state to be used for all future unfurl_* commands */
TWN_API void set_camera(const Camera *camera);
/* expects '*' masks that will be expanded to 6 names: 'up', 'down', 'east', 'west', 'north' and 'south' */
TWN_API void push_skybox(const char *paths);
#endif
+150
View File
@@ -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);
}
+1
View File
@@ -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);
+1
View File
@@ -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();
}
+4
View File
@@ -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
View 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;
}
+2 -2
View File
@@ -42,7 +42,7 @@ static int load_eof_callback(void *user) {
return context->position == context->size;
}
static SDL_Surface *image_to_surface(const char *path) {
SDL_Surface *textures_load_surface(const char *path) {
SDL_RWops *handle = PHYSFSRWOPS_openRead(path);
if (handle == NULL)
goto ERR_CANNOT_OPEN_FILE;
@@ -359,7 +359,7 @@ static TextureKey textures_load(TextureCache *cache, const char *path) {
if (i >= 0)
return (TextureKey){ (uint16_t)i };
SDL_Surface *surface = image_to_surface(path);
SDL_Surface *surface = textures_load_surface(path);
Texture new_texture = {
.data = surface,
.mode = infer_texture_mode(surface),
+4
View File
@@ -89,4 +89,8 @@ size_t textures_get_num_atlases(const TextureCache *cache);
/* TODO: should recieve texture_cache, get_key optimization cache should be cleared some other way */
void textures_reset_state(void);
/* uncached low-level loading */
/* warn: surface->pixels must be freed along side the surface itself */
SDL_Surface *textures_load_surface(const char *path);
#endif
+17
View File
@@ -253,3 +253,20 @@ bool repeat_ftimer(float *value, float at) {
}
return false;
}
/* TODO: handle utf8 */
char *expand_asterisk(const char *mask, const char *to) {
const char *offset = SDL_strchr(mask, '*');
if (!offset) {
CRY("Invalid path", "Asterisk should be given.");
return NULL;
}
size_t const mask_len = SDL_strlen(mask);
size_t const to_len = SDL_strlen(to);
char *str = SDL_malloc(mask_len + to_len); /* NULL included, replacing the original asterisk */
SDL_memcpy(str, mask, offset - mask);
SDL_memcpy(str + (offset - mask), to, to_len);
SDL_memcpy(str + (offset - mask) + to_len, offset + 1, mask_len - (offset - mask));
str[mask_len + to_len] = '\0';
return str;
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef TWN_UTIL_C_H
#define TWN_UTIL_C_H
/* note: you must free the returned string */
char *expand_asterisk(const char *mask, const char *to);
#endif