commit 5444b48a0c2bced7eb200b56e274ad7de79fe000
parent 1a35612b18f3291266b0c4e84095c7e98d503cc9
Author: William Casarin <jb55@jb55.com>
Date: Sun, 26 Sep 2021 12:38:22 -0700
shader var overhaul
Diffstat:
58 files changed, 1915 insertions(+), 1483 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,24 +7,17 @@ DEFS= -DGLFW_INCLUDE_NONE -DDEBUG
# CFLAGS = $(DEFS) -ggdb -O0 -I src -Wall -Wextra -std=c99 \
-BASE_CFLAGS = $(DEFS) -O2 -g -I src -Wall -Werror -Wextra -std=c99 \
- -DSTBI_ONLY_TGA \
- -Wno-unused-function \
- -Wno-unused-parameter \
- -Wno-unused-variable \
- -Wmissing-field-initializers \
- -Wno-cast-align \
- -Wno-padded \
- $(shell pkg-config --cflags sdl2 gl)
-
-CFLAGS = $(BASE_CFLAGS)
-EM_CFLAGS = $(BASE_CFLAGS) -s STANDALONE_WASM -mbulk-memory
-
-LDFLAGS = $(shell pkg-config --libs sdl2 gl) -lm
+CFLAGS = $(DEFS) -O1 -g -I src -Wall -Werror -Wextra -std=c99 \
+ -Wno-unused-function \
+ -Wno-unused-parameter \
+ -Wno-unused-variable \
+ -Wmissing-field-initializers \
+ -Wno-cast-align \
+ -Wno-padded
+LDFLAGS = -lSDL2 -lGL -lm
SRC=src
SRCS=$(wildcard $(SRC)/*.c)
-HEADERS=$(wildcard $(SRC)/*.h)
PLYS=$(wildcard data/models/*.ply)
MODELS=$(PLYS:.ply=.mdl)
@@ -74,14 +67,14 @@ $(BIN): main.o $(OBJS)
@echo "link $@"
@$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
-$(BIN).wasm: main.c $(SRCS)
- emcc $(EM_CFLAGS) $^ -s WASM=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -o $@
-
install: $(BIN)
install -d $(PREFIX)/bin
install $(BIN) $(PREFIX)/bin
+TAGS:
+ etags $(SRCS)
+
tags:
ctags $(SRCS) $(HEADERS)
-.PHONY: TAGS tags
+.PHONY: TAGS
diff --git a/default.nix b/default.nix
@@ -14,7 +14,7 @@ stdenv.mkDerivation rec {
makeFlags = "PREFIX=$(out)";
- nativeBuildInputs = with pkgs; [ tinycc pkg-config gdb emscripten binaryen wabt ];
+ nativeBuildInputs = with pkgs; [ tinycc pkg-config gdb ];
buildInputs = with pkgs; [ SDL2 mesa libglvnd ] ++
(with xorg; [ libX11 libxcb libXau libXdmcp libXext libXcursor
diff --git a/etc/shaders/chess-piece.v.glsl b/etc/shaders/chess-piece.v.glsl
@@ -6,7 +6,7 @@ in vec3 normal;
#include uniforms.glsl
-uniform bool is_white;
+uniform int is_white;
out shader_data {
#include shadervars.glsl
@@ -14,7 +14,7 @@ out shader_data {
void main()
{
- vec3 color = is_white ? vec3(0.9, 0.9, 0.9) : vec3(0.3, 0.3, 0.3);
+ vec3 color = is_white == 1 ? vec3(0.9, 0.9, 0.9) : vec3(0.3, 0.3, 0.3);
#include standard_vtxos.glsl
gl_Position = mvp * v4_pos;
}
diff --git a/etc/shaders/main.f.glsl b/etc/shaders/main.f.glsl
@@ -41,7 +41,7 @@ void main() {
// vec3 color = reflect_env(vertex.color);
vec3 color = pbr(vertex.color, normalize(V), vertex.normal);
- if (fog_on) {
+ if (fog_on == 1) {
vec3 fog = apply_fog(color, vertex.position, length(V), camera_position, V);
color = fog;
}
diff --git a/etc/shaders/standard_vtxos.glsl b/etc/shaders/standard_vtxos.glsl
@@ -2,8 +2,8 @@ vec4 v4_pos = vec4(position, 1.0);
// data_out.normal = normal;
// data_out.position = position;
-data_out.normal = mat3(transpose(inverse(model))) * normal;
-data_out.position = vec3(model * v4_pos);
+data_out.normal = mat3(transpose(inverse(model_view))) * normal;
+data_out.position = vec3(model_view * v4_pos);
data_out.color_smooth = data_out.color = color;
data_out.shadow_coord = depth_mvp * v4_pos;
// TODO: move shadow coord calc from frag to here
diff --git a/etc/shaders/ui.v.glsl b/etc/shaders/ui.v.glsl
@@ -1,7 +1,6 @@
#include profile
in vec3 position;
-in vec3 color;
in vec2 tex_coords;
out vec3 v_color;
@@ -18,5 +17,5 @@ void main()
gl_Position = mvp * v4_pos;
v_tex_coords = tex_coords;
- v_color = color + v4_pos.xyz;
+ v_color = v4_pos.xyz;
}
diff --git a/etc/shaders/uniforms.glsl b/etc/shaders/uniforms.glsl
@@ -1,15 +1,13 @@
+precision highp int;
// uniform bool diffuse_on;
-uniform bool fog_on;
+uniform int fog_on;
uniform float sky_intensity;
uniform float light_intensity;
uniform mat4 depth_mvp;
-// uniform mat4 depth_vp;
-uniform mat4 model;
uniform mat4 mvp;
+uniform mat4 model_view;
uniform mat4 normal_matrix;
-// uniform float time;
-// uniform float ambient_str;
uniform vec3 sun_color;
uniform vec3 camera_position;
uniform vec3 light_dir;
diff --git a/main.c b/main.c
@@ -19,12 +19,10 @@
#include "update.h"
#include "util.h"
#include "window.h"
-
#include "test_game.h"
+//#include "rogue/rogue.h"
-
-#include <stdio.h>
#include <assert.h>
#include <time.h>
@@ -46,16 +44,16 @@ int main(void)
/* SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); */
int width = 640;
- int hello;
int height = 480;
- game_init(&engine, width, height);
- init_test_game(&test_game, &engine.gpu, width, height);
+ game_init(&engine, width, height);
+ //rogue_game_init(&rogue_game);
+ init_test_game(&engine, &test_game);
//reset_scene(&engine);
default_scene(&test_game);
//pbr_scene(&test_game);
- //chess_scene(&game);
+ chess_scene(&engine, &test_game);
check_gl();
double last = hires_time_in_seconds();
@@ -77,6 +75,7 @@ int main(void)
// render our game frame here
test_game_frame(&engine, &test_game);
+ //rogue_frame(&engine, rogue_game);
/* Swap front and back buffers */
SDL_GL_SwapWindow(engine.window);
diff --git a/src/chess.c b/src/chess.c
@@ -1,233 +1,321 @@
#include "chess.h"
#include "node.h"
+#include "gpu.h"
+#include "shader.h"
+#include "hash.h"
+#include "test_game.h"
-// v1------v0
-// | |
-// | |
-// | |
-// v2------v3
+// v1------v0
+// | |
+// | |
+// | |
+// v2------v3
static GLuint quad_indices[] = {0, 1, 2, 0, 2, 3};
static GLfloat quad_normals[] = {
- 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front
};
static GLfloat quad_vertices[] = {
- 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5,-0.5, 0.5, 0.5,-0.5, 0.5, // v0-v1-v2-v3 front
+ 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5,-0.5, 0.5, 0.5,-0.5, 0.5, // v0-v1-v2-v3 front
};
-
static GLfloat quad_uvs[] =
- {
- 1.0, 1.0, // v0
- 0.0, 1.0, // v1
- 0.0, 0.0, // v2
- 1.0, 0.0, // v3
- };
+ {
+ 1.0, 1.0, // v0
+ 0.0, 1.0, // v1
+ 0.0, 0.0, // v2
+ 1.0, 0.0, // v3
+ };
#define CELL_SIZE 10.0
+struct chess_piece {
+ int is_white;
+};
+
+#define CP_LENS(field, typ) { #field, offsetof(struct chess_piece, field), DATA_ID_##typ }
+static struct lens chess_piece_lenses[] = {
+ CP_LENS(is_white, INT),
+};
+
void make_grid(float *verts, float vert_capacity,
- u32 *indices, float index_capacity,
- float *normals, float normal_capacity,
- float *colors, float color_capacity,
- int width, int height)
+ u32 *indices, float index_capacity,
+ float *normals, float normal_capacity,
+ float *colors, float color_capacity,
+ int width, int height)
{
- int c = 0;
- for (int x = 0; x < width; x++) {
- for (int y = 0; y < height; y++, c++) {
- int grid_ind = y * height + x;
- int vind = grid_ind * ARRAY_SIZE(quad_vertices);
- int iind = grid_ind * ARRAY_SIZE(quad_indices);
- int i = 0;
-
- for (i = 0; i < 4; i++) {
- int nv = i*3;
- assert(vind+2+nv < vert_capacity);
- assert(vind+2+nv < color_capacity);
- assert(vind+2+nv < normal_capacity);
- verts[vind+0+nv] = (quad_vertices[0+nv] + x) * CELL_SIZE;
- verts[vind+1+nv] = (quad_vertices[1+nv] + y) * CELL_SIZE;
- verts[vind+2+nv] = quad_vertices[2+nv];
-
- // recenter
- verts[vind+0+nv] -= (width * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE;
- verts[vind+1+nv] -= (height * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE;
- verts[vind+2+nv] -= 0.5;
-
- normals[vind+0+nv] = quad_normals[0+nv];
- normals[vind+1+nv] = quad_normals[1+nv];
- normals[vind+2+nv] = quad_normals[2+nv];
-
- float checkers = (x ^ y) & 1;
- colors[vind+0+nv] = checkers;
- colors[vind+1+nv] = checkers;
- colors[vind+2+nv] = checkers;
- }
-
- for (i = 0; i < 2; i++) {
- int nv = i*3;
- assert(iind+2+nv < index_capacity);
- indices[iind+0+nv] = quad_indices[0+nv] + 4*c;
- indices[iind+1+nv] = quad_indices[1+nv] + 4*c;
- indices[iind+2+nv] = quad_indices[2+nv] + 4*c;
- }
- }
- }
+ int c = 0;
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++, c++) {
+ int grid_ind = y * height + x;
+ int vind = grid_ind * ARRAY_SIZE(quad_vertices);
+ int iind = grid_ind * ARRAY_SIZE(quad_indices);
+ int i = 0;
+
+ for (i = 0; i < 4; i++) {
+ int nv = i*3;
+ assert(vind+2+nv < vert_capacity);
+ assert(vind+2+nv < color_capacity);
+ assert(vind+2+nv < normal_capacity);
+ verts[vind+0+nv] = (quad_vertices[0+nv] + x) * CELL_SIZE;
+ verts[vind+1+nv] = (quad_vertices[1+nv] + y) * CELL_SIZE;
+ verts[vind+2+nv] = quad_vertices[2+nv];
+
+ // recenter
+ verts[vind+0+nv] -= (width * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE;
+ verts[vind+1+nv] -= (height * CELL_SIZE)/2.0 - 0.5 * CELL_SIZE;
+ verts[vind+2+nv] -= 0.5;
+
+ normals[vind+0+nv] = quad_normals[0+nv];
+ normals[vind+1+nv] = quad_normals[1+nv];
+ normals[vind+2+nv] = quad_normals[2+nv];
+
+ float checkers = (x ^ y) & 1;
+ colors[vind+0+nv] = checkers;
+ colors[vind+1+nv] = checkers;
+ colors[vind+2+nv] = checkers;
+ }
+
+ for (i = 0; i < 2; i++) {
+ int nv = i*3;
+ assert(iind+2+nv < index_capacity);
+ indices[iind+0+nv] = quad_indices[0+nv] + 4*c;
+ indices[iind+1+nv] = quad_indices[1+nv] + 4*c;
+ indices[iind+2+nv] = quad_indices[2+nv] + 4*c;
+ }
+ }
+ }
}
static void make_chessboard_geom(geometry_id *id)
{
- struct make_geometry mkgeom;
- init_make_geometry(&mkgeom);
-
- static float verts[12*8*8]; // array_size(quad) 12 * 8 * 8
- static float colors[12*8*8]; // array_size(quad) 12 * 8 * 8
- static float normals[12*8*8]; // array_size(quad) 12 * 8 * 8
- static u32 indices[6*8*8]; // array_size(quad) 6 * 8 * 8
-
- make_grid(verts, ARRAY_SIZE(verts),
- indices, ARRAY_SIZE(indices),
- normals, ARRAY_SIZE(normals),
- colors, ARRAY_SIZE(colors),
- 8, 8);
-
- mkgeom.indices = indices;
- mkgeom.vertices = verts;
- mkgeom.normals = normals;
- mkgeom.colors = colors;
- mkgeom.num_indices = ARRAY_SIZE(indices);
- mkgeom.num_verts = ARRAY_SIZE(verts)/3;
- mkgeom.num_uv_components = 0;
-
- init_id(id);
- struct geometry *geom = new_geometry(id);
- make_buffer_geometry(&mkgeom, geom);
- check_gl();
+ struct make_geometry mkgeom;
+ init_make_geometry(&mkgeom);
+
+ static float verts[12*8*8]; // array_size(quad) 12 * 8 * 8
+ static float colors[12*8*8]; // array_size(quad) 12 * 8 * 8
+ static float normals[12*8*8]; // array_size(quad) 12 * 8 * 8
+ static u32 indices[6*8*8]; // array_size(quad) 6 * 8 * 8
+
+ make_grid(verts, ARRAY_SIZE(verts),
+ indices, ARRAY_SIZE(indices),
+ normals, ARRAY_SIZE(normals),
+ colors, ARRAY_SIZE(colors),
+ 8, 8);
+
+ mkgeom.indices = indices;
+ mkgeom.vertices = verts;
+ mkgeom.normals = normals;
+ mkgeom.colors = colors;
+ mkgeom.num_indices = ARRAY_SIZE(indices);
+ mkgeom.num_verts = ARRAY_SIZE(verts)/3;
+ mkgeom.num_uv_components = 0;
+
+ init_id(id);
+ struct geometry *geom = new_geometry(id);
+ make_buffer_geometry(&mkgeom, geom);
+ check_gl();
}
static void position_piece(struct entity *piece, int x, int y)
{
- assert(x < 8);
- assert(y < 8);
+ assert(x < 8);
+ assert(y < 8);
- struct node *node = get_node(&piece->node_id);
- struct model *model = get_model(&piece->model_id);
- struct geometry *geom = get_geometry(&model->geom_id);
- assert(node);
+ struct node *node = get_node(&piece->node_id);
+ struct model *model = get_model(&piece->model_id);
+ struct geometry *geom = get_geometry(&model->geom_id);
+ assert(node);
- // reset to a1
- node->pos[0] = -3.5 * CELL_SIZE;
- node->pos[1] = -3.5 * CELL_SIZE;
- node->pos[2] = 0.0;
+ // reset to a1
+ node->pos[0] = -3.5 * CELL_SIZE;
+ node->pos[1] = -3.5 * CELL_SIZE;
+ node->pos[2] = 0.0;
- node->pos[0] += x * CELL_SIZE;
- node->pos[1] += y * CELL_SIZE;
+ node->pos[0] += x * CELL_SIZE;
+ node->pos[1] += y * CELL_SIZE;
}
static void setup_pieces(node_id *chessboard) {
- struct model *pirate_officer;
- get_model_by_name("pirate_officer", &pirate_officer);
-
- // make pawn model
- struct model_id pawn_model_id;
- init_id(&pawn_model_id.id);
- struct model *pawn_model = new_model(&pawn_model_id);
- pawn_model->geom_id = pirate_officer->geom_id;
- pawn_model->shader = CHESS_PIECE_PROGRAM;
-
- // pawns
- for (int i = 0; i < 16; i++) {
- struct entity *pawn = new_entity(NULL);
- struct node *pawn_node = get_node(&pawn->node_id);
- pawn->model_id = pawn_model_id;
- pawn->flags |= ENT_IS_WHITE | ENT_CASTS_SHADOWS;
-
- node_scale(pawn_node, 5.0);
- if (i >= 8) {
- pawn->flags &= ~ENT_IS_WHITE;
- node_rotate(pawn_node, V3(0.0,0.0,135.0));
- }
- node_attach(&pawn->node_id, chessboard);
-
- position_piece(pawn, i % 8, i < 8 ? 1 : 6);
- }
-
- for (int i = 0; i < 4; i++) {
- // rooks
- struct entity *rook = new_entity(NULL);
- struct model *rook_model;
- struct node *rook_node = get_node(&rook->node_id);
- rook->model_id = get_model_by_name("tower", &rook_model);
- rook->flags |= ENT_CASTS_SHADOWS | ENT_IS_WHITE;
- rook_model->shader = CHESS_PIECE_PROGRAM;
- node_attach(&rook->node_id, chessboard);
- /* node_rotate(rook_node, V3(0.0,0.0,20.0)); */
- if (i >= 2) {
- rook->flags &= ~ENT_IS_WHITE;
- node_rotate(rook_node, V3(0.0,0.0,135.0));
- }
- position_piece(rook, i % 2 ? 0 : 7, i < 2 ? 0 : 7);
- node_scale(rook_node, 0.25);
- }
+ struct model *pirate_officer, *pawn_model, *tower_model, *rook_model;
+ struct model_id pawn_model_id, rook_model_id;
+ u32 ent_type;
+
+ ent_type = hash_str("chess-piece");
+ debug("chess piece ent_type %d\n", ent_type);
+
+ get_model_by_name("pirate_officer", &pirate_officer);
+ get_model_by_name("tower", &tower_model);
+
+ // make pawn model
+ init_id(&pawn_model_id.id);
+ init_id(&rook_model_id.id);
+
+ pawn_model = new_model(&pawn_model_id);
+ pawn_model->geom_id = pirate_officer->geom_id;
+ pawn_model->shader = CHESS_PIECE_PROGRAM;
+ pawn_model->name = "pawn";
+
+ rook_model = new_model(&rook_model_id);
+ rook_model->geom_id = tower_model->geom_id;
+ rook_model->shader = CHESS_PIECE_PROGRAM;
+ rook_model->name = "rook";
+
+ // pawns
+ for (int i = 0; i < 16; i++) {
+ struct entity *ent = new_entity(NULL);
+ struct node *pawn_node = get_node(&ent->node_id);
+ struct chess_piece *pawn = (struct chess_piece*)ent->data;
+
+ ent->type = ent_type;
+ ent->model_id = pawn_model_id;
+ ent->flags |= ENT_CASTS_SHADOWS;
+
+ node_set_label(pawn_node, "pawn");
+
+ pawn->is_white = 1;
+
+ node_scale(pawn_node, 5.0);
+
+ if (i >= 8) {
+ pawn->is_white = 0;
+ node_rotate(pawn_node, V3(0.0,0.0,135.0));
+ }
+
+ node_attach(&ent->node_id, chessboard);
+
+ position_piece(ent, i % 8, i < 8 ? 1 : 6);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ // rooks
+ struct entity *ent = new_entity(NULL);
+ struct chess_piece *rook = (struct chess_piece*)ent->data;
+ struct node *rook_node = get_node(&ent->node_id);
+ ent->type = ent_type;
+ ent->model_id = rook_model_id;
+ ent->flags |= ENT_CASTS_SHADOWS;
+ rook->is_white = true;
+
+ node_attach(&ent->node_id, chessboard);
+ /* node_rotate(rook_node, V3(0.0,0.0,20.0)); */
+ if (i >= 2) {
+ rook->is_white = false;
+ node_rotate(rook_node, V3(0.0,0.0,135.0));
+ }
+ position_piece(ent, i % 2 ? 0 : 7, i < 2 ? 0 : 7);
+ node_scale(rook_node, 0.25);
+ }
+
+
+}
+
+static struct structure_binding *get_chess_piece_bindings(int *count)
+{
+ static struct structure_binding bindings[2];
+
+ bindings[0].lenses = get_common_lenses();
+ bindings[0].num_lenses = get_common_lenses_length();
+ assert(bindings[0].num_lenses > 1);
+
+ bindings[1].lenses = chess_piece_lenses;
+ bindings[1].num_lenses = ARRAY_SIZE(chess_piece_lenses);
+
+ *count = 2;
+
+ return bindings;
}
+static struct gpu_program *make_chess_program(struct gpu *gpu)
+{
+ struct gpu_program *program, *default_program;
+ struct shader *fragment, chess_piece_vertex;
+ struct structure_binding *bindings;
+ int num_bindings;
+ int ok;
+
+ ok = make_shader(GL_VERTEX_SHADER, SHADER("chess-piece.v.glsl"), &chess_piece_vertex);
+ rtassert(ok, "chess-piece vertex shader");
+ check_gl();
+
+ default_program = get_gpu_program_by_name(gpu, "vertex-color");
+ rtassert(default_program, "failed to get default program");
+ check_gl();
+
+ fragment = get_program_shader(default_program, GL_FRAGMENT_SHADER);
+ rtassert(fragment, "failed to get default fragment shader");
+
+ bindings = get_chess_piece_bindings(&num_bindings);
+
+ program = &gpu->programs[CHESS_PIECE_PROGRAM];
+ ok = make_program("chess-piece", &chess_piece_vertex, fragment, program,
+ bindings, num_bindings);
+ rtassert(ok, "chess-piece program");
+ check_gl();
+
+ return program;
+}
-void chess_scene(struct test_game *game)
+void chess_scene(struct game *engine, struct test_game *game)
{
- struct entity *ent = new_entity(NULL);
- struct node *node = get_node(&ent->node_id); assert(node);
- struct entity *player = get_entity(&game->player_id);
+ struct gpu_program *piece_program;
+ struct entity *ent = new_entity(NULL);
+ struct node *node = get_node(&ent->node_id); assert(node);
+ struct entity *player = get_entity(&game->player_id);
+ struct shader chess_piece_vertex;
- ent->model_id = get_model_by_name("icosphere", NULL);
- node_set_label(node, "sphere");
+ ent->model_id = get_model_by_name("icosphere", NULL);
+ node_set_label(node, "sphere");
- //
- // setup chessboard
- //
- geometry_id chessboard_geom;
- make_chessboard_geom(&chessboard_geom);
+ //
+ // setup chessboard
+ //
+ geometry_id chessboard_geom;
+ make_chessboard_geom(&chessboard_geom);
- struct model_id chessboard_model_id;
- init_id(&chessboard_model_id.id);
+ struct model_id chessboard_model_id;
+ init_id(&chessboard_model_id.id);
- struct model *chessboard_model = new_model(&chessboard_model_id);
- chessboard_model->shader = DEFAULT_PROGRAM;
- chessboard_model->geom_id = chessboard_geom;
+ struct model *chessboard_model = new_model(&chessboard_model_id);
+ chessboard_model->name = "chessboard";
+ chessboard_model->shader = 0;
+ chessboard_model->geom_id = chessboard_geom;
- player->model_id = chessboard_model_id;
- player->flags &= ~ENT_CASTS_SHADOWS;
+ player->model_id = chessboard_model_id;
+ player->flags &= ~ENT_CASTS_SHADOWS;
- //
- // setup camera
- //
- struct spherical *coords = &game->orbit_camera.coords;
- coords->radius = 72.0;
- coords->inclination = 0.5;
- coords->azimuth = -7.86;
+ //
+ // setup camera
+ //
+ struct spherical *coords = &game->orbit_camera.coords;
+ coords->radius = 72.0;
+ coords->inclination = 0.5;
+ coords->azimuth = -7.86;
- struct node *pnode = get_node(&player->node_id);
- node_translate(pnode, V3(240.0, 252.0, 373.0));
- pnode->orientation[2] = -0.005;
- pnode->orientation[3] = -1.0;
+ struct node *pnode = get_node(&player->node_id);
+ node_translate(pnode, V3(240.0, 252.0, 373.0));
+ pnode->orientation[2] = -0.005;
+ pnode->orientation[3] = -1.0;
- node_id *cam_id = &game->orbit_camera.node_id;
- struct node *cam_node = get_node(cam_id); assert(cam_node);
+ node_id *cam_id = &game->orbit_camera.node_id;
+ struct node *cam_node = get_node(cam_id); assert(cam_node);
- setup_pieces(&player->node_id);
+ make_chess_program(&engine->gpu);
+ setup_pieces(&player->node_id);
- node_recalc(pnode);
+ node_recalc(pnode);
- //player 1284.539062 1111.104126 14.273574
+ //player 1284.539062 1111.104126 14.273574
- // show terrain
- //terrain_ent->flags |= ENT_INVISIBLE;
+ // show terrain
+ //terrain_ent->flags |= ENT_INVISIBLE;
- // show player
- /* player->flags |= ENT_INVISIBLE; */
+ // show player
+ /* player->flags |= ENT_INVISIBLE; */
}
diff --git a/src/chess.h b/src/chess.h
@@ -3,7 +3,8 @@
#define POLYADVENT_CHESS_H
#include "test_game.h"
+#include "game.h"
-void chess_scene(struct test_game *game);
+void chess_scene(struct game *engine, struct test_game *game);
#endif /* POLYADVENT_CHESS_H */
diff --git a/src/common.h b/src/common.h
@@ -2,6 +2,8 @@
#ifndef POLYADVENT_COMMON_H
#define POLYADVENT_COMMON_H
+#include <inttypes.h>
+
typedef int bool;
#define false 0
#define true 1
@@ -22,8 +24,8 @@ typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
-typedef unsigned long long u64;
-typedef signed long long s64;
+typedef uint64_t u64;
+typedef int64_t s64;
struct point {
double x, y;
diff --git a/src/dae.c b/src/dae.c
@@ -351,7 +351,7 @@ void dae_attr(struct xmlparser *x, const char *t, size_t tl,
}
else if (data->state == PARSING_NODE
&& streq(a, "name")) {
- strncpy(data->current_name, v, sizeof(data->current_name)-1);
+ strncpy(data->current_name, v, sizeof(data->current_name));
}
else if (data->state == PARSING_NODE
&& streq(a, "type")
diff --git a/src/data_id.h b/src/data_id.h
@@ -0,0 +1,92 @@
+#pragma once
+
+#include "resource.h"
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+
+enum data_id_type {
+ DATA_ID_RESOURCE = 1,
+ DATA_ID_RAWPTR,
+};
+
+enum data_id_datatype {
+ DATA_ID_FLOAT = 1,
+ DATA_ID_INT,
+ DATA_ID_VEC2,
+ DATA_ID_VEC3,
+ DATA_ID_VEC3P,
+ DATA_ID_MAT3,
+ DATA_ID_MAT4,
+ DATA_ID_MAT4P,
+};
+
+struct lens {
+ const char *name;
+ int offset;
+ enum data_id_datatype type;
+};
+
+static inline int data_id_get_ptr_data(void *ptr, enum data_id_datatype typ, void *out)
+{
+ assert(out);
+ assert(ptr);
+ switch (typ) {
+ case DATA_ID_FLOAT:
+ break;
+ case DATA_ID_INT:
+ *((int*)out) = *(int*)ptr;
+ break;
+ case DATA_ID_VEC2:
+ case DATA_ID_VEC3:
+ case DATA_ID_MAT3:
+ case DATA_ID_MAT4:
+ assert(0);
+ break;
+ case DATA_ID_MAT4P:
+ case DATA_ID_VEC3P:
+ *((float**)out) = *(float**)ptr;
+ break;
+ default:
+ assert(0);
+ }
+
+ return 1;
+}
+
+
+static inline void *get_lens_offset_ptr(struct lens *lens, void *structure)
+{
+ return (void*)((unsigned char*)structure + lens->offset);
+}
+
+static inline float *get_lens_ptr(struct lens *lens, void *structure)
+{
+ assert(lens->type == DATA_ID_MAT4P || lens->type == DATA_ID_VEC3P);
+ float **p = (float**)get_lens_offset_ptr(lens, structure);
+ return *p;
+}
+
+static inline float *get_lens_float_array(struct lens *lens, void *structure)
+{
+ assert(lens->type == DATA_ID_MAT4 ||
+ lens->type == DATA_ID_VEC3 ||
+ lens->type == DATA_ID_VEC2 ||
+ lens->type == DATA_ID_MAT3);
+ void *p = get_lens_offset_ptr(lens, structure);
+ return (float*)p;
+}
+
+static inline float get_lens_float(struct lens *lens, void *structure)
+{
+ assert(lens->type == DATA_ID_FLOAT);
+ void *p = get_lens_offset_ptr(lens, structure);
+ return *(float*)p;
+}
+
+static inline int get_lens_int(struct lens *lens, void *structure)
+{
+ assert(lens->type == DATA_ID_INT);
+ void *p = get_lens_offset_ptr(lens, structure);
+ return *(int*)p;
+}
diff --git a/src/debug.c b/src/debug.c
@@ -3,7 +3,21 @@
#include <stdlib.h>
#include <stdio.h>
-void show_info_log(GLuint shader) {
+void show_program_info_log(int program)
+{
+ GLint msgLen = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &msgLen);
+
+ // The maxLength includes the NULL character
+ char *buffer = malloc(msgLen);
+ glGetProgramInfoLog(program, msgLen, &msgLen, buffer);
+
+ printf("program error: (%d) %.*s\n", msgLen, msgLen, buffer);
+
+ free(buffer);
+}
+
+void show_shader_info_log(GLuint shader) {
GLint msgLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &msgLen);
@@ -11,9 +25,9 @@ void show_info_log(GLuint shader) {
char *buffer = malloc(msgLen);
glGetShaderInfoLog(shader, msgLen, &msgLen, buffer);
- printf("shader error: (%d) %.*s\n", msgLen, msgLen, buffer);
+ printf("shader error: (%d) %.*s\n", msgLen, msgLen, buffer);
- free(buffer);
+ free(buffer);
}
diff --git a/src/debug.h b/src/debug.h
@@ -6,7 +6,8 @@
#include <stdio.h>
-void show_info_log(GLuint shader);
+void show_shader_info_log(GLuint shader);
+void show_program_info_log(int program);
// rtassert exists in release builds, use sparingly
#define rtassert(cond, msg) if (!cond) { \
diff --git a/src/delaunay.c b/src/delaunay.c
@@ -513,11 +513,11 @@ static halfedge_t* del_valid_left( halfedge_t* b )
v = b->next->pair->vertex; /* pair(next(next(halfedge)) point */
- if( v!=u && classify_point_seg(g, d, u) == ON_LEFT )
+ if( classify_point_seg(g, d, u) == ON_LEFT )
{
/* 3 points aren't colinear */
/* as long as the 4 points belong to the same circle, do the cleaning */
- //assert( v != u && "1: floating point precision error");
+ assert( v != u && "1: floating point precision error");
while( v != d && v != g && in_circle(g, d, u, v) == INSIDE )
{
c = b->next;
@@ -528,7 +528,7 @@ static halfedge_t* del_valid_left( halfedge_t* b )
v = b->next->pair->vertex;
}
- //assert( v != u && "2: floating point precision error");
+ assert( v != u && "2: floating point precision error");
if( v != d && v != g && in_circle(g, d, u, v) == ON_CIRCLE )
{
du = du->prev;
@@ -559,9 +559,9 @@ static halfedge_t* del_valid_right( halfedge_t *b )
v = b->prev->pair->vertex;
- if( v!=u && classify_point_seg(lv, rv, u) == ON_LEFT )
+ if( classify_point_seg(lv, rv, u) == ON_LEFT )
{
- //assert( v != u && "1: floating point precision error");
+ assert( v != u && "1: floating point precision error");
while( v != lv && v != rv && in_circle(lv, rv, u, v) == INSIDE )
{
c = b->prev;
@@ -572,7 +572,7 @@ static halfedge_t* del_valid_right( halfedge_t *b )
v = b->prev->pair->vertex;
}
- //assert( v != u && "1: floating point precision error");
+ assert( v != u && "1: floating point precision error");
if( v != lv && v != rv && in_circle(lv, rv, u, v) == ON_CIRCLE )
{
du = du->next;
diff --git a/src/entity.c b/src/entity.c
@@ -20,12 +20,10 @@ struct entity *get_all_entities(u32 *count, entity_id **ids) {
}
struct entity *init_entity(struct entity *ent, node_id *id) {
- node_id new_id;
init_id(&ent->model_id.id);
if (id == NULL) {
- init_id(&new_id);
- new_node(&new_id);
- ent->node_id = new_id;
+ init_id(&ent->node_id);
+ new_node(&ent->node_id);
/* debug("init_entity with new node_id %llu\n", new_id.uuid); */
}
else {
@@ -43,11 +41,6 @@ static inline struct entity *new_uninitialized_entity(entity_id *id) {
return new_resource(&esys, id);
}
-struct entity *new_entity_(entity_id *id) {
- return new_entity_with_node(id, NULL);
-}
-
-
struct entity *new_entity_with_node(entity_id *id, node_id *node)
{
diff --git a/src/entity.h b/src/entity.h
@@ -9,21 +9,23 @@
#include <assert.h>
#define MAX_ENTITIES 10048
+#define ENTITY_DATA_SIZE 128
enum entity_flags {
- ENT_IS_PLAYER = 1 << 0,
- ENT_INVISIBLE = 1 << 1,
- ENT_CASTS_SHADOWS = 1 << 2,
- ENT_ON_GROUND = 1 << 3,
- ENT_IS_WHITE = 1 << 4,
+ ENT_IS_PLAYER = 1 << 0,
+ ENT_INVISIBLE = 1 << 1,
+ ENT_CASTS_SHADOWS = 1 << 2,
+ ENT_ON_GROUND = 1 << 3,
};
struct entity {
- node_id node_id;
- struct model_id model_id;
- u32 flags;
- float velocity[3];
- float accel[3];
+ node_id node_id;
+ struct model_id model_id;
+ u32 flags;
+ u32 type;
+ float velocity[3]; // move into entity components
+ float accel[3];
+ u8 data[ENTITY_DATA_SIZE];
};
typedef struct resource_id entity_id;
@@ -36,16 +38,19 @@ void init_entity_system();
struct entity *get_entity(entity_id *);
const char *entity_label(struct entity *);
struct entity *get_all_entities(u32 *count, entity_id **ids);
-struct entity *new_entity_(entity_id *);
struct entity *new_entity_with_node(entity_id *, node_id *);
struct entity *new_debug_entity(entity_id *, float *pos);
void destroy_entity_system();
+static inline struct entity *new_entity_(entity_id *id) {
+ return new_entity_with_node(id, NULL);
+}
+
static inline struct entity *new_entity(entity_id *id)
{
- if (id)
- assert((int)id->index == -1 && "error: " __FILE__ ":" STRIZE(__LINE__) " missing init_id or already initialized");
- return new_entity_(id);
+ if (id)
+ assert((int)id->index == -1 && "error: " __FILE__ ":" STRIZE(__LINE__) " missing init_id or already initialized");
+ return new_entity_(id);
}
#endif /* ENTITY_H */
diff --git a/src/fbo.c b/src/fbo.c
@@ -3,8 +3,6 @@
#include "fbo.h"
#include "util.h"
-#include <stdio.h>
-
void create_fbo(struct fbo *fbo, int width, int height) {
glGenFramebuffers(1, &fbo->handle);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
diff --git a/src/file.c b/src/file.c
@@ -2,10 +2,8 @@
#include <stdio.h>
#include <stdlib.h>
#include "file.h"
-#include "debug.h"
#include <sys/stat.h>
-#include <string.h>
time_t file_mtime(const char *filename) {
// TODO: windows file_mtime
diff --git a/src/game.c b/src/game.c
@@ -30,7 +30,7 @@ bool was_key_pressed_this_frame(struct game *game, int scancode)
return is_key_down_on_frame(&game->input, scancode, game->frame);
}
-bool was_button_pressed_this_frame(struct game *game, int button)
+bool was_button_pressed_this_frame(struct game *game, SDL_GameControllerButton button)
{
return is_button_down_on_frame(&game->input, button, game->frame);
}
@@ -43,7 +43,7 @@ static void init_user_settings(struct user_settings *settings) {
static void init_sdl(SDL_Window **window, int width, int height)
{
- SDL_Init( 0);
+ SDL_Init( SDL_INIT_JOYSTICK );
/* SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); */
@@ -65,11 +65,9 @@ void init_misc(struct game *game) {
game->gpu.num_programs = 0;
//debug("creating ui...\n");
- //create_ui(&game->ui, width, height, &res->programs[UI_PROGRAM]);
//check_gl();
}
-/*
void init_controller(struct input *input) {
SDL_GameControllerAddMappingsFromFile("data/gamecontrollerdb.txt");
@@ -92,8 +90,6 @@ void init_controller(struct input *input) {
}
}
-*/
-
void game_init(struct game *game, int width, int height) {
game->width = width;
game->height = height;
@@ -103,23 +99,20 @@ void game_init(struct game *game, int width, int height) {
init_gl();
debug("init entities...\n");
init_entity_system();
- debug("init geom...\n");
init_geometry_manager();
- debug("init modelman...\n");
init_model_manager();
- debug("init nodeman...\n");
init_node_manager();
- debug("init user settings...\n");
init_user_settings(&game->user_settings);
check_gl();
game->wireframe = 0;
- debug("init input...\n");
init_input(&game->input);
+ init_controller(&game->input);
//init_controller(&game->input);
debug("init misc...\n");
init_misc(game);
+ printf("gpu programs %d\n", game->gpu.num_programs);
}
diff --git a/src/game.h b/src/game.h
@@ -16,8 +16,6 @@
#include "ui.h"
#include "gpu.h"
-#include <stdio.h>
-
#define PLAYER_HEIGHT 1.73
/*
@@ -48,7 +46,7 @@ void game_init(struct game *game, int width, int height);
void quit_game(struct game *game);
void should_update(struct game *game);
bool was_key_pressed_this_frame(struct game *game, int scancode);
-bool was_button_pressed_this_frame(struct game *game, int button);
+bool was_button_pressed_this_frame(struct game *game, SDL_GameControllerButton button);
int is_free_camera(struct game *game);
#endif /* PA_GAME_H */
diff --git a/src/geometry.c b/src/geometry.c
@@ -9,204 +9,210 @@ struct resource_manager geom_manager;
void
destroy_buffer_geometry(geometry_id *geom_id) {
- struct geometry *geom = get_geometry(geom_id);
- gpu_addr buffers[MAX_VERTEX_ATTRS];
-
- for (int i = 0; i < MAX_VERTEX_ATTRS; i++)
- buffers[i] = geom->vbos[i].handle;
- /* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */
- /* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */
- /* check_gl(); */
- /* glDisableVertexAttribArray(geom->buffer.normal_buffer.handle); */
- /* check_gl(); */
- /* glDisableVertexAttribArray(geom->buffer.index_buffer.handle); */
- /* check_gl(); */
- check_gl();
- glDeleteBuffers(ARRAY_SIZE(buffers), buffers);
- check_gl();
-
-
- geom->has_vbos = 0;
+ struct geometry *geom = get_geometry(geom_id);
+ gpu_addr buffers[MAX_VERTEX_ATTRS];
+
+ for (int i = 0; i < MAX_VERTEX_ATTRS; i++)
+ buffers[i] = geom->vbos[i].handle;
+ /* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */
+ /* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */
+ /* check_gl(); */
+ /* glDisableVertexAttribArray(geom->buffer.normal_buffer.handle); */
+ /* check_gl(); */
+ /* glDisableVertexAttribArray(geom->buffer.index_buffer.handle); */
+ /* check_gl(); */
+ check_gl();
+ glDeleteBuffers(ARRAY_SIZE(buffers), buffers);
+ check_gl();
+
+
+ geom->has_vbos = 0;
}
-void bind_geometry(struct geometry *geom, gpu_addr *vertex_attrs) {
- struct vbo *vbo;
- for (int i = 0; i < MAX_VERTEX_ATTRS; i++) {
- vbo = &geom->vbos[i];
- if (vbo->handle && vertex_attrs[i] != 0xFFFFFFFF) {
- bind_vbo(vbo, vertex_attrs[i], vbo->component_type);
- check_gl();
- }
- }
+void bind_geometry(struct geometry *geom, struct gpu_program *program) {
+ struct vbo *vbo;
+ for (int i = 0; i < MAX_VERTEX_ATTRS; i++) {
+ if (i != va_index && !(program->active_attributes & (1 << i))) {
+ continue;
+ }
+ vbo = &geom->vbos[i];
+ assert(program->vertex_attrs[i] != 0xFFFFFFFF);
+ if (vbo->handle) {
+ bind_vbo(vbo, program->vertex_attrs[i],
+ vbo->component_type);
+ check_gl();
+ } else {
+ printf("%s: %s attribute not bound\n",
+ program->name,
+ vertex_attr_str(i));
+ assert(0);
+ }
+ }
}
-void render_geometry(struct geometry *geom, gpu_addr *vertex_attrs,
- struct gpu_program *program)
+void render_geometry(struct geometry *geom, struct gpu_program *program)
{
- int type = GL_TRIANGLES;
- bind_geometry(geom, vertex_attrs);
- if (geom->num_indices) {
- glDrawElements(type,
- geom->num_indices, /* count */
- GL_UNSIGNED_INT, /* type */
- (void*)0 /* element array buffer offset */
- );
- //printf("render_geometry %d %s\n", geom->num_indices, program->name);
- check_gl();
- }
- else {
- /* printf("nverts %d\n", geom->num_verts); */
- glDrawArrays(type, 0, geom->num_verts);
- check_gl();
- }
+ int type = GL_TRIANGLES;
+ bind_geometry(geom, program);
+ if (geom->num_indices) {
+ glDrawElements(type,
+ geom->num_indices, /* count */
+ GL_UNSIGNED_INT, /* type */
+ (void*)0 /* element array buffer offset */
+ );
+ //printf("render_geometry %d %s\n", geom->num_indices, program->name);
+ check_gl();
+ }
+ else {
+ /* printf("nverts %d\n", geom->num_verts); */
+ glDrawArrays(type, 0, geom->num_verts);
+ check_gl();
+ }
}
void init_make_geometry(struct make_geometry *mkgeom) {
- *mkgeom = (struct make_geometry){
- .colors = NULL,
- .normals = NULL,
- .indices = NULL,
- .vertices = NULL,
- .tex_coords = NULL,
- .joint_ids = NULL,
- .joint_weights = NULL,
- .num_uv_components = 2,
- .num_verts = 0,
- .num_indices = 0,
- };
+ *mkgeom = (struct make_geometry){
+ .colors = NULL,
+ .normals = NULL,
+ .indices = NULL,
+ .vertices = NULL,
+ .tex_coords = NULL,
+ .joint_ids = NULL,
+ .joint_weights = NULL,
+ .num_uv_components = 2,
+ .num_verts = 0,
+ .num_indices = 0,
+ };
}
void init_geometry(struct geometry *geom) {
- geom->has_vbos = 0;
+ geom->has_vbos = 0;
- for (int i = 0; i < MAX_VERTEX_ATTRS; i++)
- init_vbo(&geom->vbos[i]);
+ for (int i = 0; i < MAX_VERTEX_ATTRS; i++)
+ init_vbo(&geom->vbos[i]);
- geom->num_uv_components = 2;
+ geom->num_uv_components = 2;
}
void make_buffer_geometry(struct make_geometry *mkgeom, struct geometry *geom)
{
- init_geometry(geom);
-
- // VBOs
- geom->num_uv_components = mkgeom->num_uv_components;
- geom->num_verts = mkgeom->num_verts;
- geom->num_indices = mkgeom->num_indices;
-
- assert(mkgeom->num_verts);
- assert(mkgeom->vertices);
- /* assert(geom->normals); */
- /* assert(geom->indices); */
- /* assert(geom->num_indices >= 1); */
-
- /* printf("making vertex buffer\n"); */
- make_float_vertex_buffer(&geom->vbos[va_position],
- mkgeom->vertices,
- mk_num_elements(mkgeom->num_verts),
- mk_components(3)
- );
-
- /* printf("making normal buffer\n"); */
- // cube normals
- if (mkgeom->normals) {
- make_float_vertex_buffer(&geom->vbos[va_normal],
- mkgeom->normals,
- mk_num_elements(mkgeom->num_verts),
- mk_components(3)
- );
- }
- if (mkgeom->joint_ids) {
- make_int_vertex_buffer(&geom->vbos[va_joint_ids],
- mkgeom->joint_ids,
- mk_num_elements(mkgeom->num_verts),
- mk_components(3)
- );
- }
-
- // vertex colors
- if (mkgeom->colors) {
- make_float_vertex_buffer(&geom->vbos[va_color],
- mkgeom->colors,
- mk_num_elements(mkgeom->num_verts),
- mk_components(3)
- );
- }
-
- if (mkgeom->tex_coords != NULL) {
- assert(geom->num_uv_components);
-
- make_uv_buffer(&geom->vbos[va_tex_coord],
- mkgeom->tex_coords,
- mk_num_elements(geom->num_verts),
- mk_components(geom->num_uv_components)
- );
- }
-
- /* printf("making index buffer\n"); */
- // cube indices
- if (mkgeom->indices)
- make_index_buffer(&geom->vbos[va_index],
- mkgeom->indices,
- mk_num_elements(mkgeom->num_indices)
- );
-
- geom->has_vbos = 1;
+ init_geometry(geom);
+
+ // VBOs
+ geom->num_uv_components = mkgeom->num_uv_components;
+ geom->num_verts = mkgeom->num_verts;
+ geom->num_indices = mkgeom->num_indices;
+
+ assert(mkgeom->num_verts);
+ assert(mkgeom->vertices);
+ /* assert(geom->normals); */
+ /* assert(geom->indices); */
+ /* assert(geom->num_indices >= 1); */
+
+ /* printf("making vertex buffer\n"); */
+ make_float_vertex_buffer(&geom->vbos[va_position],
+ mkgeom->vertices,
+ mk_num_elements(mkgeom->num_verts),
+ mk_components(3));
+
+ /* printf("making normal buffer\n"); */
+ // cube normals
+ if (mkgeom->normals) {
+ make_float_vertex_buffer(&geom->vbos[va_normal],
+ mkgeom->normals,
+ mk_num_elements(mkgeom->num_verts),
+ mk_components(3));
+ }
+ if (mkgeom->joint_ids) {
+ assert(0);
+ make_int_vertex_buffer(&geom->vbos[va_joint_ids],
+ mkgeom->joint_ids,
+ mk_num_elements(mkgeom->num_verts),
+ mk_components(3));
+ }
+
+ // vertex colors
+ if (mkgeom->colors) {
+ make_float_vertex_buffer(&geom->vbos[va_color],
+ mkgeom->colors,
+ mk_num_elements(mkgeom->num_verts),
+ mk_components(3));
+ }
+
+ if (mkgeom->tex_coords != NULL) {
+ assert(geom->num_uv_components);
+
+ make_uv_buffer(&geom->vbos[va_tex_coord],
+ mkgeom->tex_coords,
+ mk_num_elements(geom->num_verts),
+ mk_components(geom->num_uv_components)
+ );
+ }
+
+ /* printf("making index buffer\n"); */
+ // cube indices
+ if (mkgeom->indices)
+ make_index_buffer(&geom->vbos[va_index],
+ mkgeom->indices,
+ mk_num_elements(mkgeom->num_indices)
+ );
+
+ geom->has_vbos = 1;
}
void geometry_centroid(struct geometry *geom, float *dest) {
- vec3_subtract(geom->max, geom->min, dest);
- vec3_scale(dest, 0.5, dest);
+ vec3_subtract(geom->max, geom->min, dest);
+ vec3_scale(dest, 0.5, dest);
};
void init_geometry_manager() {
- init_resource_manager(&geom_manager, sizeof(struct geometry),
- DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry");
+ init_resource_manager(&geom_manager, sizeof(struct geometry),
+ DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry");
}
struct geometry *get_geometry(geometry_id *geom_id) {
- return get_resource(&geom_manager, geom_id);
+ return get_resource(&geom_manager, geom_id);
}
struct geometry *new_geometry(geometry_id *geom_id) {
- struct geometry *geom = new_resource(&geom_manager, geom_id);
- /* debug("new geometry %llu\n", geom_id->uuid); */
- return geom;
+ struct geometry *geom = new_resource(&geom_manager, geom_id);
+ /* debug("new geometry %llu\n", geom_id->uuid); */
+ return geom;
}
struct geometry *get_all_geometry(u32 *count, geometry_id **ids) {
- return get_all_resources(&geom_manager, count, ids);
+ return get_all_resources(&geom_manager, count, ids);
}
void destroy_geometry(geometry_id *geom_id)
{
- struct geometry *geom = get_geometry(geom_id); assert(geom);
- struct vbo *vbo;
+ struct geometry *geom = get_geometry(geom_id); assert(geom);
+ struct vbo *vbo;
- for (int i = 0; i < MAX_VERTEX_ATTRS; i++) {
- vbo = &geom->vbos[i];
- if (vbo->handle)
- glDeleteBuffers(1, &vbo->handle);
- }
+ for (int i = 0; i < MAX_VERTEX_ATTRS; i++) {
+ vbo = &geom->vbos[i];
+ if (vbo->handle)
+ glDeleteBuffers(1, &vbo->handle);
+ }
- destroy_resource(&geom_manager, geom_id);
+ destroy_resource(&geom_manager, geom_id);
}
void free_make_geometry(struct make_geometry *mkgeom)
{
- if (mkgeom->vertices)
- free(mkgeom->vertices);
+ if (mkgeom->vertices)
+ free(mkgeom->vertices);
- if (mkgeom->normals)
- free(mkgeom->normals);
+ if (mkgeom->normals)
+ free(mkgeom->normals);
- if (mkgeom->colors)
- free(mkgeom->colors);
+ if (mkgeom->colors)
+ free(mkgeom->colors);
- if (mkgeom->indices)
- free(mkgeom->indices);
+ if (mkgeom->indices)
+ free(mkgeom->indices);
}
diff --git a/src/geometry.h b/src/geometry.h
@@ -47,9 +47,8 @@ struct geometry_manager {
int num_geometry;
};
-void render_geometry(struct geometry *geom, gpu_addr *vertex_attrs,
- struct gpu_program *current_program);
-void bind_geometry(struct geometry *geom, gpu_addr *vertex_attrs);
+void render_geometry(struct geometry *geom, struct gpu_program *current_program);
+void bind_geometry(struct geometry *geom, struct gpu_program *program);
void init_geometry(struct geometry *geom);
void init_make_geometry(struct make_geometry *mkgeom);
void free_make_geometry(struct make_geometry *mkgeom);
diff --git a/src/gpu.c b/src/gpu.c
@@ -21,3 +21,19 @@ int try_reload_shaders(struct gpu *gpu) {
return ret;
}
+struct gpu_program *get_gpu_program_by_name(struct gpu *gpu, const char *name)
+{
+ int i;
+ struct gpu_program *program;
+
+ printf("num_programs %d\n", gpu->num_programs);
+
+ for (i = 0; i < gpu->num_programs; i++) {
+ program = &gpu->programs[i];
+ if (!strcmp(program->name, name))
+ return program;
+ }
+
+ return NULL;
+}
+
diff --git a/src/gpu.h b/src/gpu.h
@@ -10,3 +10,4 @@ struct gpu {
};
int try_reload_shaders(struct gpu *gpu);
+struct gpu_program *get_gpu_program_by_name(struct gpu *gpu, const char *name);
diff --git a/src/hash.h b/src/hash.h
@@ -0,0 +1,20 @@
+
+// TODO: move hash to it's own file
+#define FNV_32_PRIME ((u32)0x01000193)
+
+static inline unsigned int hash_str(const char *str)
+{
+ unsigned char *s = (unsigned char *)str; /* unsigned string */
+ unsigned int hval = 0;
+
+ /*
+ * FNV-1a hash each octet in the buffer
+ */
+ while (*s) {
+ hval ^= (u32)*s++;
+ hval *= FNV_32_PRIME;
+ }
+
+ /* return our new hash value */
+ return hval;
+}
diff --git a/src/hires.c b/src/hires.c
@@ -1,7 +1,7 @@
#include <time.h>
#include "common.h"
-#include <SDL.h>
+#include <SDL2/SDL.h>
double hires_time_in_seconds() {
double ticks_per_sec = (double)SDL_GetPerformanceFrequency();
diff --git a/src/input.c b/src/input.c
@@ -29,7 +29,7 @@ static void key_up(struct input *input, int scancode, u64 current_frame) {
static void button_up(struct input *input, SDL_JoyButtonEvent *event, u64 current_frame)
{
- if (event->button >= MAX_CONTROLLER_BUTTONS) return;
+ if (event->button >= SDL_CONTROLLER_BUTTON_MAX) return;
/* printf("button up %d\n", event->button); */
struct input_edge *edge = &input->button_edge_states[event->button];
@@ -39,7 +39,7 @@ static void button_up(struct input *input, SDL_JoyButtonEvent *event, u64 curren
static void button_down(struct input *input, SDL_JoyButtonEvent *event, u64 current_frame)
{
- if (event->button >= MAX_CONTROLLER_BUTTONS) return;
+ if (event->button >= SDL_CONTROLLER_BUTTON_MAX) return;
printf("button down %d\n", event->button);
struct input_edge *edge = &input->button_edge_states[event->button];
@@ -152,7 +152,7 @@ void init_input(struct input *input) {
input->last_my = 0;
input->resized_height = 0;
input->resized_width = 0;
- //input->controller = 0;
+ input->controller = 0;
assert(input->keystates);
}
@@ -163,7 +163,7 @@ bool is_key_down_on_frame(struct input *input, u8 scancode, u64 frame) {
return edge->down_frame == frame && edge->is_down;
}
-bool is_button_down_on_frame(struct input *input, int button, u64 frame)
+bool is_button_down_on_frame(struct input *input, SDL_GameControllerButton button, u64 frame)
{
struct input_edge *edge = &input->button_edge_states[button];
return edge->down_frame == frame && edge->is_down;
@@ -183,14 +183,11 @@ int input_is_dragging(struct input *input, int mouse_button) {
return input->mbuttons[mouse_button-1];
}
-bool is_button_down(struct input *input, int button)
+bool is_button_down(struct input *input, SDL_GameControllerButton button)
{
- return false;
- /*
if (!input->controller) {
return false;
}
return SDL_GameControllerGetButton(input->controller, button) == 1;
- */
}
diff --git a/src/input.h b/src/input.h
@@ -3,7 +3,7 @@
#ifndef POLYADVENT_INPUT_H
#define POLYADVENT_INPUT_H
-#include <SDL.h>
+#include <SDL2/SDL.h>
#include "common.h"
/* enum key_state { */
@@ -23,7 +23,6 @@
#define MAX_AXIS_VALUE 32767
#define MIN_AXIS_VALUE -32767
#define MAX_CONTROLLERS
-#define MAX_CONTROLLER_BUTTONS 15
struct input_edge {
int is_down;
@@ -31,13 +30,11 @@ struct input_edge {
u64 up_frame;
};
-
-
struct input {
/* enum key_state keys[0x7F-0x1F]; */
u8 const *keystates;
SDL_Keymod modifiers;
- //SDL_GameController *controller;
+ SDL_GameController *controller;
int mx, my, last_mx, last_my;
int axis[MAX_AXIS];
int axis_min_input;
@@ -53,14 +50,14 @@ struct input {
/* u8 frame_down_keys[KEY_BUFFER_SIZE]; */
/* u8 frame_up_keys[KEY_BUFFER_SIZE]; */
struct input_edge key_edge_states[SDL_NUM_SCANCODES];
- struct input_edge button_edge_states[MAX_CONTROLLER_BUTTONS];
+ struct input_edge button_edge_states[SDL_CONTROLLER_BUTTON_MAX];
};
int input_is_dragging(struct input *input, int mouse_button);
-bool is_button_down(struct input *input, int button);
+bool is_button_down(struct input *input, SDL_GameControllerButton button);
bool is_key_down_on_frame(struct input *input, u8 scancode, u64 frame);
-bool is_button_down_on_frame(struct input *input, int button, u64 frame);
+bool is_button_down_on_frame(struct input *input, SDL_GameControllerButton button, u64 frame);
void init_input(struct input *input);
void input_reset(struct input *input);
diff --git a/src/mdl.c b/src/mdl.c
@@ -41,7 +41,7 @@ void init_mdl_geometry(struct mdl_geometry *lgeom)
vec3_set(V3(0,0,0), lgeom->max);
}
-void save_mdl_fd(FILE *out, struct mdl_geometry *lgeom)
+void save_mdl_fd(FILE *out, struct model *model, struct mdl_geometry *lgeom)
{
struct make_geometry *mkgeom = &lgeom->mkgeom;
assert(mkgeom->vertices);
@@ -140,7 +140,7 @@ static inline int read_int(FILE *stream)
return val;
}
-#define MAX_MDL_ARRAY 1280000 // only enforced at dev time for sanity
+#define MAX_MDL_ARRAY 128000 // only enforced at dev time for sanity
static inline int read_nfloats(FILE *stream, int n, float *floats)
{
@@ -184,7 +184,6 @@ void load_mdl_fd(FILE *in, struct model *model, struct mdl_geometry *lgeom)
switch (tag) {
case MDL_POSITION:
mkgeom->num_verts = read_floats(in, &mkgeom->vertices) / 3;
- printf("mdl verts %d\n", mkgeom->num_verts);
break;
case MDL_NORMAL:
@@ -236,11 +235,11 @@ void load_mdl_fd(FILE *in, struct model *model, struct mdl_geometry *lgeom)
}
}
-void save_mdl(const char *filename, struct mdl_geometry *lgeom)
+void save_mdl(const char *filename, struct model *model, struct mdl_geometry *lgeom)
{
FILE *out = fopen(filename, "wb");
assert(out);
- save_mdl_fd(out, lgeom);
+ save_mdl_fd(out, model, lgeom);
fclose(out);
}
diff --git a/src/mdl.h b/src/mdl.h
@@ -4,7 +4,6 @@
#include "geometry.h"
#include "model.h"
-
#include <stdio.h>
enum mdl_tag {
@@ -27,8 +26,8 @@ struct mdl_geometry {
};
-void save_mdl(const char *filename, struct mdl_geometry *geom);
-void save_mdl_fd(FILE *out, struct mdl_geometry *geom);
+void save_mdl(const char *filename, struct model *model, struct mdl_geometry *geom);
+void save_mdl_fd(FILE *out, struct model *model, struct mdl_geometry *geom);
void load_mdl(const char *filename, struct model *model, struct mdl_geometry *geom);
void load_mdl_fd(FILE *in, struct model *model, struct mdl_geometry *geom);
diff --git a/src/model.c b/src/model.c
@@ -3,6 +3,7 @@
#include "ply.h"
#include "resource.h"
#include "debug.h"
+#include "hash.h"
#include "util.h"
#include <assert.h>
@@ -11,102 +12,87 @@
static struct resource_manager dyn_modelman;
struct model *init_model(struct model *model) {
- init_id(&model->geom_id);
- model->shader = DEFAULT_PROGRAM;
- model->texture = 0;
- model->nposes = 0;
- for (u16 i = 0; i < ARRAY_SIZE(model->poses); i++) {
- init_pose(model->poses);
- }
- return model;
+ init_id(&model->geom_id);
+ model->shader = 0;
+ model->texture = 0;
+ model->nposes = 0;
+ for (u16 i = 0; i < ARRAY_SIZE(model->poses); i++) {
+ init_pose(model->poses);
+ }
+ return model;
}
struct model *get_all_models(u32 *count, struct model_id **ids) {
- return get_all_resources(&dyn_modelman, count, (struct resource_id **)ids);
+ return get_all_resources(&dyn_modelman, count, (struct resource_id **)ids);
}
static inline struct model *new_uninitialized_model(struct model_id *id) {
- return new_resource(&dyn_modelman, &id->id);
+ return new_resource(&dyn_modelman, &id->id);
}
-static struct model *new_model_resource(struct model_id *model_id)
+struct model *new_model(struct model_id *model_id)
{
- struct model *model = new_uninitialized_model(model_id);
- /* debug("new model %llu\n", model_id->dyn_model_id.uuid); */
- init_id(&model->geom_id);
- new_geometry(&model->geom_id);
- return model;
+ struct model *model = new_uninitialized_model(model_id);
+ /* debug("new model %llu\n", model_id->dyn_model_id.uuid); */
+ init_model(model);
+ init_id(&model->geom_id);
+ new_geometry(&model->geom_id);
+ return model;
}
void init_model_manager()
{
- init_resource_manager(&dyn_modelman, sizeof(struct model),
- DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model");
+ init_resource_manager(&dyn_modelman, sizeof(struct model),
+ DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model");
}
-struct model *new_model(struct model_id *id)
-{
- return new_model_resource(id);
-}
-
struct model *get_model(struct model_id *model_id)
{
- return get_resource(&dyn_modelman, &model_id->id);
-}
-
-// TODO: move hash to it's own file
-#define FNV_32_PRIME ((u32)0x01000193)
-
-static u32 hash_str(const char *str)
-{
- u8 *s = (u8 *)str; /* unsigned string */
- u32 hval = 0;
-
- /*
- * FNV-1a hash each octet in the buffer
- */
- while (*s) {
- hval ^= (u32)*s++;
- hval *= FNV_32_PRIME;
- }
-
- /* return our new hash value */
- return hval;
+ return get_resource(&dyn_modelman, &model_id->id);
}
static struct model *load_model(const char *name, struct model_id *mid)
{
- static char path[128] = {0};
+ static char path[128] = {0};
+
+ struct model *model = new_model(mid);
+ struct geometry *geom = get_geometry(&model->geom_id);
+ struct mdl_geometry lgeom;
- struct model *model = new_model_resource(mid);
- struct geometry *geom = get_geometry(&model->geom_id);
- struct mdl_geometry lgeom;
+ init_mdl_geometry(&lgeom);
+ init_geometry(geom);
- init_mdl_geometry(&lgeom);
- init_geometry(geom);
+ model->name = name;
+ model->name_hash = hash_str(name);
- model->name = name;
- model->name_hash = hash_str(name);
+ assert(!geom->has_vbos);
+
+ /*
+ if (geom->has_vbos) {
+ debug("model %s already loaded\n", name);
+ return model;
+ }
+ */
- if (geom->has_vbos) {
- debug("model %s already loaded\n", name);
- return model;
- }
+ // Load mesh
+ debug("loading %s model uuid %" PRIu64 " with geom_id %" PRIu64 "\n", name,
+ mid->id.uuid, model->geom_id.uuid);
- // Load mesh
- debug("loading %s model with geom_id\n", name);
+ snprintf(path, 128, "data/models/%s.mdl", name);
+ load_mdl(path, model, &lgeom);
- snprintf(path, 128, "data/models/%s.mdl", name);
- load_mdl(path, model, &lgeom);
+ vec3_copy(lgeom.min, geom->min);
+ vec3_copy(lgeom.max, geom->max);
- vec3_copy(lgeom.min, geom->min);
- vec3_copy(lgeom.max, geom->max);
+ printf("%s min:%f,%f,%f max:%f,%f,%f\n", name,
+ geom->min[0], geom->min[1], geom->min[2],
+ geom->max[0], geom->max[1], geom->max[2]);
- make_buffer_geometry(&lgeom.mkgeom, geom);
- free_make_geometry(&lgeom.mkgeom);
+ make_buffer_geometry(&lgeom.mkgeom, geom);
+ free_make_geometry(&lgeom.mkgeom);
- return model;
+ return model;
}
struct model_id get_model_by_name(const char *name, struct model **found)
@@ -129,6 +115,10 @@ struct model_id get_model_by_name(const char *name, struct model **found)
if (model->name_hash == name_hash) {
if (found)
*found = model;
+ /*
+ printf("found %s:%s model_id:%"PRIu64" geom_id:%"PRIu64"\n",
+ name, model->name, ids[i].id.uuid, model->geom_id.uuid);
+ */
return ids[i];
}
}
@@ -142,10 +132,10 @@ struct model_id get_model_by_name(const char *name, struct model **found)
void destroy_model(struct model_id *model_id)
{
- struct model *model = get_model(model_id);
+ struct model *model = get_model(model_id);
- destroy_geometry(&model->geom_id);
- destroy_resource(&dyn_modelman, &model_id->id);
+ destroy_geometry(&model->geom_id);
+ destroy_resource(&dyn_modelman, &model_id->id);
}
diff --git a/src/model.h b/src/model.h
@@ -20,7 +20,7 @@ struct model_id {
struct model {
/* geometry_id geom_id; */
geometry_id geom_id;
- enum program_type shader;
+ int shader;
struct pose poses[MAX_POSES]; // TODO: separate animated_model buffer?
int nposes;
u32 texture;
diff --git a/src/node.c b/src/node.c
@@ -32,7 +32,7 @@ void destroy_node(node_id *id)
{
#ifdef DEBUG
struct node *node = get_node(id);
- debug("destroying node %llu %s\n", id->uuid, node->label);
+ debug("destroying node %" PRIu64 " %s\n", id->uuid, node->label);
#endif
destroy_resource(&node_manager, id);
@@ -216,6 +216,9 @@ void node_attach(struct resource_id *node_id, struct resource_id *to_id)
struct node *to = get_node(to_id);
assert(node);
+ if (to->n_children > MAX_NODE_CHILDREN) {
+ debug("to->n_children %d\n", to->n_children);
+ }
assert(to && to->n_children <= MAX_NODE_CHILDREN);
node->parent_id = *to_id;
diff --git a/src/node.h b/src/node.h
@@ -4,7 +4,7 @@
#include "resource.h"
-#define MAX_NODE_CHILDREN 20
+#define MAX_NODE_CHILDREN 32
enum node_flags {
NODE_IGNORE_RECALC = 1 << 0
diff --git a/src/orbit_util.c b/src/orbit_util.c
@@ -1,6 +1,7 @@
#include "orbit.h"
#include "input.h"
+#include "debug.h"
#include "entity.h"
void orbit_update_from_mouse(struct orbit *camera, struct input *input,
@@ -8,17 +9,20 @@ void orbit_update_from_mouse(struct orbit *camera, struct input *input,
float dt)
{
float target[3];
- struct node *target_node = get_node(&player->node_id);
- struct node *cam_node = get_node(&camera->node_id);
- struct model *pmodel = get_model(&player->model_id); assert(pmodel);
- struct geometry *player_geom = get_geometry(&pmodel->geom_id); assert(player_geom);
+ struct node *target_node = get_node(&player->node_id);
+ struct node *cam_node = get_node(&camera->node_id);
+ struct model *pmodel = get_model(&player->model_id);
+ assert(pmodel);
+
+ struct geometry *player_geom = get_geometry(&pmodel->geom_id);
+ assert(player_geom);
assert(target_node);
assert(cam_node);
node_recalc(target_node);
vec3_copy(node_world(target_node), target);
- assert(player_geom->max[2] != 0);
+ //assert(player_geom->max[2] != 0);
vec3_add(target, V3(0.0, 0.0, player_geom->max[2]), target);
/* vec3_add(target, V3(0.0, 0.0, 10.0), target); */
diff --git a/src/poisson.c b/src/poisson.c
@@ -5,8 +5,6 @@
#include "common.h"
#include "poisson.h"
-#include <stdio.h>
-
struct grid_info {
double size;
diff --git a/src/quickhull.c b/src/quickhull.c
@@ -998,7 +998,7 @@ qh_face_t* qh__build_tetrahedron(qh_context_t* context, float epsilon)
qh_vertex_t* v;
qh_face_t* dface = NULL;
- if (vertices[0] == (long)i || vertices[1] == (long)i || vertices[2] == (long)i) {
+ if (vertices[0] == i || vertices[1] == i || vertices[2] == i) {
continue;
}
@@ -1014,7 +1014,7 @@ qh_face_t* qh__build_tetrahedron(qh_context_t* context, float epsilon)
for (int j = 0; j < 3; ++j) {
qh_half_edge_t* e = context->edges + dface->edges[j];
- if ((long)i == e->to_vertex) {
+ if (i == e->to_vertex) {
valid = 0;
break;
}
diff --git a/src/render.h b/src/render.h
@@ -21,28 +21,27 @@ void wireframe_mode_on();
void wireframe_mode_off();
static inline void uniform_3f(struct gpu_program *program,
- enum uniform_id id, const float *v3)
+ int id, const float *v3)
{
glUniform3f(program->uniforms[id].location, v3[0], v3[1], v3[2]);
check_gl();
}
-static inline void uniform_1i(struct gpu_program *program,
- enum uniform_id id, int i)
+static inline void uniform_1i(struct gpu_program *program, int id, int i)
{
glUniform1i(program->uniforms[id].location, i);
check_gl();
}
static inline void uniform_m4f(struct gpu_program *program,
- enum uniform_id id, float *m)
+ int id, float *m)
{
glUniformMatrix4fv(program->uniforms[id].location, 1, 0, m);
check_gl();
}
static inline void uniform_1f(struct gpu_program *program,
- enum uniform_id id, float f)
+ int id, float f)
{
glUniform1f(program->uniforms[id].location, f);
check_gl();
diff --git a/src/resource.c b/src/resource.c
@@ -11,217 +11,217 @@ static u64 resource_uuids = 0;
static inline void *index_resource_(u8 *res, u32 elem_size, int i)
{
- assert(res);
- return res + (i * elem_size);
+ assert(res);
+ return res + (i * elem_size);
}
static inline void *index_resource(struct resource_manager *r, int i)
{
- return index_resource_(r->resources, r->elem_size, i);
+ return index_resource_(r->resources, r->elem_size, i);
}
void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_id **ids) {
- if (count != 0)
- *count = r->resource_count;
+ if (count != 0)
+ *count = r->resource_count;
- if (ids != 0)
- *ids = r->ids;
+ if (ids != 0)
+ *ids = r->ids;
- return r->resources;
+ return r->resources;
}
void init_id(struct resource_id *id) {
- id->index = -1;
- id->generation = -1;
- id->uuid = -1;
+ id->index = -1;
+ id->generation = -1;
+ id->uuid = -1;
}
void null_id(struct resource_id *id)
{
- id->generation = 0;
- id->uuid = -1;
- id->index = -1;
+ id->generation = 0;
+ id->uuid = -1;
+ id->index = -1;
}
void init_resource_manager(struct resource_manager *r, u32 elem_size,
- u32 initial_elements, u32 max_elements,
- const char *name)
+ u32 initial_elements, u32 max_elements,
+ const char *name)
{
- r->generation = 1;
- r->resource_count = 0;
- r->elem_size = elem_size;
- r->max_capacity = max_elements;
- r->current_capacity = initial_elements;
- r->name = name;
+ r->generation = 1;
+ r->resource_count = 0;
+ r->elem_size = elem_size;
+ r->max_capacity = max_elements;
+ r->current_capacity = initial_elements;
+ r->name = name;
- assert(initial_elements != 0);
+ assert(initial_elements != 0);
- r->resources = calloc(r->current_capacity, elem_size);
- r->ids = calloc(r->current_capacity, sizeof(struct resource_id));
+ r->resources = calloc(r->current_capacity, elem_size);
+ r->ids = calloc(r->current_capacity, sizeof(struct resource_id));
}
void destroy_resource_manager(struct resource_manager *r) {
- free(r->ids);
- free(r->resources);
+ free(r->ids);
+ free(r->resources);
}
static int refresh_id(struct resource_manager *r, struct resource_id *id,
- struct resource_id *new)
+ struct resource_id *new)
{
- // rollover is ok
- /* assert(->generation <= esys.generation); */
- if (id->generation != r->generation) {
- /* debug("id %llu gen %d != res gen %d, refreshing\n", */
- /* id->uuid, id->generation, r->generation); */
- // try to find uuid in new memory layout
- for (u32 i = 0; i < r->resource_count; i++) {
- struct resource_id *newer_id = &r->ids[i];
- if (newer_id->uuid == id->uuid) {
- /* debug("found %llu, ind %d -> %d\n", new_id->uuid, new_id->index, new->index); */
- new->index = newer_id->index;
- new->generation = r->generation;
- return REFRESHED_ID;
- }
- }
-
- // entity was deleted
- return RESOURCE_DELETED;
- }
-
- // doesn't need refreshed
- return REFRESH_NOT_NEEDED;
+ // rollover is ok
+ /* assert(->generation <= esys.generation); */
+ if (id->generation != r->generation) {
+ /* debug("id %llu gen %d != res gen %d, refreshing\n", */
+ /* id->uuid, id->generation, r->generation); */
+ // try to find uuid in new memory layout
+ for (u32 i = 0; i < r->resource_count; i++) {
+ struct resource_id *newer_id = &r->ids[i];
+ if (newer_id->uuid == id->uuid) {
+ /* debug("found %llu, ind %d -> %d\n", new_id->uuid, new_id->index, new->index); */
+ new->index = newer_id->index;
+ new->generation = r->generation;
+ return REFRESHED_ID;
+ }
+ }
+
+ // entity was deleted
+ return RESOURCE_DELETED;
+ }
+
+ // doesn't need refreshed
+ return REFRESH_NOT_NEEDED;
}
-int is_resource_destroyed(struct resource_id *id) {
- return id->generation == 0;
+int is_resource_destroyed(struct resource_manager *r, struct resource_id *id) {
+ return refresh_id(r, id, id) == RESOURCE_DELETED;
}
static void new_id(struct resource_manager *r, struct resource_id *id)
{
- id->index = r->resource_count;
- id->uuid = ++resource_uuids;
- id->generation = r->generation;
- assert(id->generation);
+ id->index = r->resource_count;
+ id->uuid = ++resource_uuids;
+ id->generation = r->generation;
+ assert(id->generation);
}
static void resize(struct resource_manager *r)
{
- debug("resizing %s resources, count %d+1 > current capacity %d\n",
- r->name, r->resource_count, r->current_capacity);
- void *new_mem;
- u32 new_size = r->resource_count * 1.5;
- if (new_size >= r->max_capacity)
- new_size = r->max_capacity;
-
- /* debug("resizing new_size %d\n", new_size); */
-
- new_mem = realloc(r->resources, (new_size+1) * r->elem_size);
- if (!new_mem) {
- // yikes, out of memory, bail
- assert(new_mem);
- return;
- }
-
- r->resources = new_mem;
- new_mem = realloc(r->ids, sizeof(struct resource_id) * (new_size+1));
-
- if (!new_mem) {
- // yikes, out of memory, bail
- assert(new_mem);
- return;
- }
- r->current_capacity = new_size;
- r->ids = new_mem;
+ debug("resizing %s resources, count %d+1 > current capacity %d\n",
+ r->name, r->resource_count, r->current_capacity);
+ void *new_mem;
+ u32 new_size = r->resource_count * 1.5;
+ if (new_size >= r->max_capacity)
+ new_size = r->max_capacity;
+
+ /* debug("resizing new_size %d\n", new_size); */
+
+ new_mem = realloc(r->resources, (new_size+1) * r->elem_size);
+ if (!new_mem) {
+ // yikes, out of memory, bail
+ assert(new_mem);
+ return;
+ }
+
+ r->resources = new_mem;
+ new_mem = realloc(r->ids, sizeof(struct resource_id) * (new_size+1));
+
+ if (!new_mem) {
+ // yikes, out of memory, bail
+ assert(new_mem);
+ return;
+ }
+ r->current_capacity = new_size;
+ r->ids = new_mem;
}
void print_id(struct resource_id *id, int nl)
{
- printf("id(u:%llu i:%d g:%d)%s",
- id->uuid, id->index, id->generation, nl?"\n":"");
+ printf("id(u:%" PRIu64 " i:%d g:%d)%s",
+ id->uuid, id->index, id->generation, nl?"\n":"");
}
void *new_resource(struct resource_manager *r, struct resource_id *id)
{
- assert(id);
- assert(id->index == 0xFFFFFFFF && "res_id is uninitialized");
+ assert(id);
+ assert(id->index == 0xFFFFFFFF && "res_id is uninitialized");
- struct resource_id *fresh_id;
+ struct resource_id *fresh_id;
- if (r->resource_count + 1 > r->max_capacity) {
- printf("new_resource: count %d > max cap %d\n", r->resource_count, r->max_capacity);
- return NULL;
- }
+ if (r->resource_count + 1 > r->max_capacity) {
+ printf("new_resource: count %d > max cap %d\n", r->resource_count, r->max_capacity);
+ return NULL;
+ }
- if (r->resource_count + 1 > r->current_capacity)
- resize(r);
+ if (r->resource_count + 1 > r->current_capacity)
+ resize(r);
- fresh_id = &r->ids[r->resource_count];
- new_id(r, fresh_id);
- *id = *fresh_id;
+ fresh_id = &r->ids[r->resource_count];
+ new_id(r, fresh_id);
+ *id = *fresh_id;
- return index_resource(r, r->resource_count++);
+ return index_resource(r, r->resource_count++);
}
void *get_resource(struct resource_manager *r, struct resource_id *id) {
- assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)");
+ assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)");
- if (id->generation == 0) {
- /* unusual("getting already deleted resource %llu\n", id->uuid); */
- return NULL;
- }
+ if (id->generation == 0) {
+ /* unusual("getting already deleted resource %llu\n", id->uuid); */
+ return NULL;
+ }
- enum refresh_status res = refresh_id(r, id, id);
+ enum refresh_status res = refresh_id(r, id, id);
- if (res == RESOURCE_DELETED) {
- /* unusual("getting deleted %s resource %llu\n", r->name, id->uuid); */
- return NULL;
- }
+ if (res == RESOURCE_DELETED) {
+ /* unusual("getting deleted %s resource %llu\n", r->name, id->uuid); */
+ return NULL;
+ }
- return index_resource(r, id->index);
+ return index_resource(r, id->index);
}
void destroy_resource(struct resource_manager *r, struct resource_id *id) {
- if (is_resource_destroyed(id)) {
- unusual("trying to destroy resource %llu which was already destroyed\n", id->uuid);
- return;
- }
+ if (is_resource_destroyed(r, id)) {
+ unusual("trying to destroy resource %" PRIu64 " which was already destroyed\n", id->uuid);
+ return;
+ }
- enum refresh_status res = refresh_id(r, id, id);
+ enum refresh_status res = refresh_id(r, id, id);
- // entity already deleted
- /* debug("refresh res %d uuid %llu gen %d index %d\n", res, */
- /* id->uuid, id->generation, id->index); */
+ // entity already deleted
+ /* debug("refresh res %d uuid %llu gen %d index %d\n", res, */
+ /* id->uuid, id->generation, id->index); */
- if (res == RESOURCE_DELETED) {
- unusual("trying to destroy resource %llu which was already destroyed (2)\n", id->uuid);
- id->generation = 0;
- return;
- }
+ if (res == RESOURCE_DELETED) {
+ unusual("trying to destroy resource %" PRIu64 " which was already destroyed (2)\n", id->uuid);
+ id->generation = 0;
+ return;
+ }
- /* debug("destroying %s resource %llu ind %d res_count %d\n", */
- /* r->name, id->uuid, id->index, r->resource_count); */
+ /* debug("destroying %s resource %llu ind %d res_count %d\n", */
+ /* r->name, id->uuid, id->index, r->resource_count); */
- r->resource_count--;
- r->generation++;
+ r->resource_count--;
+ r->generation++;
- if (r->resource_count > 0) {
- assert((int)r->resource_count - (int)id->index >= 0);
+ if (r->resource_count > 0) {
+ assert((int)r->resource_count - (int)id->index >= 0);
- // TODO: we're copying OOB here
- memmove(index_resource(r, id->index),
- index_resource(r, id->index+1),
- r->elem_size * (r->resource_count - id->index));
+ // TODO: we're copying OOB here
+ memmove(index_resource(r, id->index),
+ index_resource(r, id->index+1),
+ r->elem_size * (r->resource_count - id->index));
- memmove(&r->ids[id->index],
- &r->ids[id->index+1],
- sizeof(struct resource_id) * (r->resource_count - id->index));
- }
+ memmove(&r->ids[id->index],
+ &r->ids[id->index+1],
+ sizeof(struct resource_id) * (r->resource_count - id->index));
+ }
- for (u32 i = id->index; i < r->resource_count; i++) {
- r->ids[i].index--;
- }
+ for (u32 i = id->index; i < r->resource_count; i++) {
+ r->ids[i].index--;
+ }
}
diff --git a/src/resource.h b/src/resource.h
@@ -39,6 +39,7 @@ void destroy_resource_manager(struct resource_manager *);
void *new_resource(struct resource_manager *, struct resource_id *id);
void print_id(struct resource_id *, int nl);
void null_id(struct resource_id *id);
+int is_resource_destroyed(struct resource_manager *r, struct resource_id *id);
void init_resource_manager(struct resource_manager *r, u32 elem_size,
u32 initial_elements, u32 max_elements, const char *name);
diff --git a/src/scene.c b/src/scene.c
@@ -1 +0,0 @@
-
diff --git a/src/shader.c b/src/shader.c
@@ -20,319 +20,537 @@ static char *line_buff[MAX_LINES];
static u32 line_lens[MAX_LINES];
static char *cached_file_contents(const char *filename) {
- size_t len;
- for (int i = 0; i < file_buf_count; i++) {
- if (memcmp(file_names[i], filename, file_name_lens[i]) == 0) {
- return file_buffers[i];
- }
- }
-
- return (char*)file_contents(filename, &len);
+ size_t len;
+ for (int i = 0; i < file_buf_count; i++) {
+ if (memcmp(file_names[i], filename, file_name_lens[i]) == 0) {
+ return file_buffers[i];
+ }
+ }
+
+ return (char*)file_contents(filename, &len);
}
static char *strsep(char **stringp, const char *delim) {
- if (*stringp == NULL) { return NULL; }
- char *token_start = *stringp;
- *stringp = strpbrk(token_start, delim);
- if (*stringp)
- (*stringp)++;
- return token_start;
+ if (*stringp == NULL) { return NULL; }
+ char *token_start = *stringp;
+ *stringp = strpbrk(token_start, delim);
+ if (*stringp)
+ (*stringp)++;
+ return token_start;
}
static char **resolve_imports(char *contents, int *nlines, int level) {
- char *line;
- int nline = 0;
- char *resolved_contents;
- char fname_buf[32] = {0};
-
- while ((line = strsep(&contents, "\n"))) {
- nline++;
- int line_len = contents - line;
- int size = sizeof("#include");
- if (memcmp(line, "#include ", size) == 0) {
- char *filename = line + size;
- int file_name_len = line_len - size - 1;
- snprintf(fname_buf, 32, SHADER("%.*s"), file_name_len, filename);
- file_name_lens[file_buf_count] = file_name_len;
- file_names[file_buf_count] = filename;
-
- /* printf("got include %.*s at line %d level %d ind %d\n", */
- /* file_name_len, filename, nline, level, file_buf_count); */
-
- // TODO (perf): cache file contents based on filename
- resolved_contents = cached_file_contents(fname_buf);
- file_buffers[file_buf_count] = resolved_contents;
- file_buf_count++;
- resolve_imports(resolved_contents, nlines, level + 1);
- }
- else {
- line_buff[*nlines] = line;
- line_lens[*nlines] = line_len;
- (*nlines)++;
- /* printf("%d %.*s", *nlines, line_len, line); */
- }
- }
-
- return line_buff;
+ char *line;
+ int nline = 0;
+ char *resolved_contents;
+ char fname_buf[32] = {0};
+
+ while ((line = strsep(&contents, "\n"))) {
+ nline++;
+ int line_len = contents - line;
+ int size = sizeof("#include");
+ if (memcmp(line, "#include ", size) == 0) {
+ char *filename = line + size;
+ int file_name_len = line_len - size - 1;
+ snprintf(fname_buf, 32, SHADER("%.*s"), file_name_len, filename);
+ file_name_lens[file_buf_count] = file_name_len;
+ file_names[file_buf_count] = filename;
+
+ /* printf("got include %.*s at line %d level %d ind %d\n", */
+ /* file_name_len, filename, nline, level, file_buf_count); */
+
+ // TODO (perf): cache file contents based on filename
+ resolved_contents = cached_file_contents(fname_buf);
+ file_buffers[file_buf_count] = resolved_contents;
+ file_buf_count++;
+ resolve_imports(resolved_contents, nlines, level + 1);
+ }
+ else {
+ line_buff[*nlines] = line;
+ line_lens[*nlines] = line_len;
+ (*nlines)++;
+ /* printf("%d %.*s", *nlines, line_len, line); */
+ }
+ }
+
+ return line_buff;
}
-struct shader *get_program_shader(struct gpu_program *program, GLenum type) {
- struct shader *shader;
- for (int i = 0; i < program->n_shaders; i++) {
- shader = &program->shaders[i];
- if (shader->type == type)
- return shader;
- }
+struct shader *get_program_shader(struct gpu_program *program, GLenum type)
+{
+ struct shader *shader;
+ for (int i = 0; i < program->n_shaders; i++) {
+ shader = &program->shaders[i];
+ if (shader->type == type)
+ return shader;
+ }
- return NULL;
+ return NULL;
}
-
int make_shader(GLenum type, const char *filename, struct shader *shader) {
- size_t length;
- int nlines = 0;
- GLchar *source = (GLchar *)file_contents(filename, &length);
- if (!source)
- return 0;
+ size_t length;
+ int nlines = 0;
+ GLchar *source = (GLchar *)file_contents(filename, &length);
+ if (!source)
+ return 0;
- assert(file_buf_count == 0);
- char **lines = resolve_imports(source, &nlines, 0);
+ assert(file_buf_count == 0);
+ char **lines = resolve_imports(source, &nlines, 0);
+
+ GLint shader_ok;
+
+ shader->n_includes = 0;
+ shader->filename = filename;
+ shader->type = type;
+ shader->handle = glCreateShader(type);
+
+ glShaderSource(shader->handle, nlines, (const char**)lines,
+ (const int*)line_lens);
- GLint shader_ok;
+ // shader dependency stuff
+ for (int i = 0; i < file_buf_count; ++i) {
+ assert(i < MAX_SHADER_INCLUDES);
+ char *p = shader->includes[shader->n_includes];
+ int name_len = file_name_lens[i];
+ /* printf("%.*s name len %d\n", name_len, file_names[i], name_len); */
+ snprintf(p, MAX_INCLUDE_FNAME_LEN, SHADER("%.*s"), name_len, file_names[i]);
+ assert(name_len < MAX_INCLUDE_FNAME_LEN);
+ shader->include_mtimes[shader->n_includes] = file_mtime(p);
+ /* printf("'%s' included in '%s'\n", p, shader->filename); */
+ shader->n_includes++;
+ free(file_buffers[i]);
+ }
+ free(source);
- shader->n_includes = 0;
- shader->filename = filename;
- shader->type = type;
- shader->handle = glCreateShader(type);
+ file_buf_count = 0;
- glShaderSource(shader->handle, nlines, (const char**)lines,
- (const int*)line_lens);
+ glCompileShader(shader->handle);
+ glGetShaderiv(shader->handle, GL_COMPILE_STATUS, &shader_ok);
- // shader dependency stuff
- for (int i = 0; i < file_buf_count; ++i) {
- assert(i < MAX_SHADER_INCLUDES);
- char *p = shader->includes[shader->n_includes];
- int name_len = file_name_lens[i];
- /* printf("%.*s name len %d\n", name_len, file_names[i], name_len); */
- snprintf(p, MAX_INCLUDE_FNAME_LEN, SHADER("%.*s"), name_len, file_names[i]);
- assert(name_len < MAX_INCLUDE_FNAME_LEN);
- shader->include_mtimes[shader->n_includes] = file_mtime(p);
- /* printf("'%s' included in '%s'\n", p, shader->filename); */
- shader->n_includes++;
- free(file_buffers[i]);
- }
- free(source);
-
- file_buf_count = 0;
-
- glCompileShader(shader->handle);
-
- glGetShaderiv(shader->handle, GL_COMPILE_STATUS, &shader_ok);
-
- if (!shader_ok) {
- fprintf(stderr, "Failed to compile %s:\n", filename);
- show_info_log(shader->handle);
- glDeleteShader(shader->handle);
- return 0;
- }
-
- shader->load_mtime =
- file_mtime(shader->filename);
-
- return 1;
+ if (!shader_ok) {
+ fprintf(stderr, "Failed to compile %s:\n", filename);
+ show_shader_info_log(shader->handle);
+ glDeleteShader(shader->handle);
+ return 0;
+ }
+
+ shader->load_mtime = file_mtime(shader->filename);
+
+ return 1;
}
#define N_SHADERS 3
void init_gpu_program(struct gpu_program *program) {
- memset(program, 0, sizeof(*program));
+ memset(program, 0, sizeof(*program));
}
-void add_attribute(struct gpu_program *program, const char *name,
- enum vertex_attr attr)
+void link_attribute(struct gpu_program *program, const char *name,
+ enum vertex_attr attr)
{
- program->vertex_attrs[attr] =
- (gpu_addr)glGetAttribLocation(program->handle, name);
- check_gl();
+ program->vertex_attrs[attr] =
+ (gpu_addr)glGetAttribLocation(program->handle, name);
+ program->active_attributes |= 1 << attr;
+ check_gl();
}
-void add_uniform(struct gpu_program *program,
- const char *name,
- enum uniform_id id)
+static inline struct lens *get_uniform_lens(struct gpu_program *program,
+ int binding_id, int lens_id)
{
- struct uniform *var = &program->uniforms[id];
- var->name = name;
- var->id = id;
- var->location = glGetUniformLocation(program->handle, var->name);
- if (var->location == -1) {
- debug("warn: could not find uniform location: %s in program %s\n",
- var->name, program->name);
- }
- /* assert(var->location != -1); */
- check_gl();
+ struct structure_binding *binding =
+ &program->bindings[binding_id];
+
+ return &binding->lenses[lens_id];
}
-void find_program_uniforms(struct gpu_program *program,
- struct gpu_program *programs)
+void add_uniform(struct gpu_program *program,
+ int id,
+ int binding_id,
+ int lens_id)
{
- // Program variables
- add_uniform(program, "camera_position", UNIFORM_CAMERA_POSITION);
- add_uniform(program, "depth_mvp", UNIFORM_DEPTH_MVP);
- add_uniform(program, "light_intensity", UNIFORM_LIGHT_INTENSITY);
- add_uniform(program, "sky_intensity", UNIFORM_SKY_INTENSITY);
- add_uniform(program, "time", UNIFORM_TIME);
- add_uniform(program, "light_dir", UNIFORM_LIGHT_DIR);
- add_uniform(program, "sun_color", UNIFORM_SUN_COLOR);
- add_uniform(program, "fog_on", UNIFORM_FOG_ON);
- add_uniform(program, "model", UNIFORM_MODEL);
- add_uniform(program, "mvp", UNIFORM_MVP);
- add_uniform(program, "normal_matrix", UNIFORM_NORMAL_MATRIX);
-
- // Attributes
- add_attribute(program, "normal", va_normal);
- add_attribute(program, "position", va_position);
- add_attribute(program, "color", va_color);
-
- // chess stuff
- if (program == &programs[CHESS_PIECE_PROGRAM]) {
- add_uniform(program, "is_white",
- UNIFORM_IS_WHITE);
- }
+ struct uniform *var = &program->uniforms[id];
+ struct lens *lens = get_uniform_lens(program, binding_id, lens_id);
+
+ var->location = glGetUniformLocation(program->handle, lens->name);
+ var->id = id;
+ var->binding_id = binding_id;
+ var->lens_id = lens_id;
+
+ if (var->location == -1) {
+ debug("warn: could not find uniform location: %s in program %s\n",
+ lens->name, program->name);
+ }
+ /* assert(var->location != -1); */
+ check_gl();
}
-void find_uniforms(struct gpu_program *programs)
+static GLenum datatype_to_gl_type(enum data_id_datatype type)
{
- for (int i = 0; i < NUM_PROGRAMS; ++i) {
- struct gpu_program *program = &programs[i];
- if (program == NULL) {
- debug("program %d is NULL\n", i);
- continue;
- }
+ switch (type) {
+ case DATA_ID_INT: return GL_INT;
+ case DATA_ID_FLOAT: return GL_FLOAT;
+ case DATA_ID_VEC2: return GL_FLOAT_VEC2;
+ case DATA_ID_VEC3: return GL_FLOAT_VEC3;
+ case DATA_ID_VEC3P: return GL_FLOAT_VEC3;
+ case DATA_ID_MAT3: return GL_FLOAT_MAT3;
+ case DATA_ID_MAT4: return GL_FLOAT_MAT4;
+ case DATA_ID_MAT4P: return GL_FLOAT_MAT4;
+ }
- if (program->name == NULL) {
- debug("program %d name is NULL, not initialized?\n", i);
- continue;
- }
+ return -1;
+}
- find_program_uniforms(program, programs);
- }
+static const char *gl_type_str(GLenum type)
+{
+ switch (type) {
+ case GL_BYTE: return "byte";
+ case GL_UNSIGNED_BYTE: return "ubyte";
+ case GL_SHORT: return "short";
+ case GL_UNSIGNED_SHORT: return "ushort";
+ case GL_INT: return "int";
+ case GL_UNSIGNED_INT: return "uint";
+ case GL_FLOAT: return "float";
+ case GL_FLOAT_VEC2: return "float_vec2";
+ case GL_FLOAT_VEC3: return "float_vec3";
+ case GL_FLOAT_MAT3: return "float_mat3";
+ case GL_FLOAT_MAT4: return "float_mat4";
+ case GL_DOUBLE: return "double";
+ case GL_TEXTURE_2D: return "texture2d";
+ case GL_TEXTURE_3D: return "texture3d";
+ case GL_SAMPLER_2D: return "sampler2d";
+ case GL_SAMPLER_CUBE: return "samplerCube";
+ default: return "unknown";
+ }
+}
+int vertex_attr_from_name(const char *name, enum vertex_attr *attr)
+{
+ if (!strcmp(name, "position")) {
+ *attr = va_position;
+ return 1;
+ } else if (!strcmp(name, "color")) {
+ *attr = va_color;
+ return 1;
+ } else if (!strcmp(name, "normal")) {
+ *attr = va_normal;
+ return 1;
+ } else if (!strcmp(name, "index")) {
+ *attr = va_index;
+ return 1;
+ } else if (!strncmp(name, "tex_coord", 9)) {
+ *attr = va_tex_coord;
+ return 1;
+ }
+ return 0;
}
-#ifdef DEBUG
-int reload_program(struct gpu_program *program,
- struct gpu_program *programs) {
- int ok;
+void create_attribute_bindings(struct gpu_program *program)
+{
+ int i, size, length, count = 0;
+ char name[64];
+ GLenum type;
+ enum vertex_attr attr;
- int n_shaders = program->n_shaders;
- struct gpu_program new_program;
- struct shader new_shaders[n_shaders];
- struct shader *new_shaders_p[n_shaders];
+ glGetProgramiv(program->handle, GL_ACTIVE_ATTRIBUTES, &count);
+ program->active_attributes = 0;
- init_gpu_program(&new_program);
+ for (i = 0; i < count; i++) {
+ glGetActiveAttrib(program->handle, (GLuint)i, sizeof(name),
+ &length, &size, &type, name);
- int changes[n_shaders];
+ if (!vertex_attr_from_name(name, &attr)) {
+ printf("unknown vertex attribute: '%s'\n", name);
+ rtassert(0, "");
+ }
- for (int i = 0; i < n_shaders; i++) {
- changes[i] = 0;
- struct shader *shader = &program->shaders[i];
- new_shaders_p[i] = shader;
+ debug("%s: linking %s to %d\n", program->name, name, attr);
+ link_attribute(program, name, attr);
+ }
+}
- time_t mtime = file_mtime(shader->filename);
- int changed = mtime != shader->load_mtime;
+void create_uniform_bindings(struct gpu_program *program,
+ struct structure_binding *bindings,
+ int num_bindings)
+{
+ int i, binding_id, lens_id, size, length, count = 0, unis = 0;
+ GLenum type, lens_type;
+ struct lens *lens;
+ struct structure_binding *binding;
+ unsigned char *p;
+ char name[64];
+
+ program->bindings = bindings;
+ program->num_bindings = num_bindings;
+
+ glGetProgramiv(program->handle, GL_ACTIVE_UNIFORMS, &count);
+
+ for (i = 0; i < count; i++) {
+ glGetActiveUniform(program->handle, (GLuint)i, sizeof(name),
+ &length, &size, &type, name);
+
+ debug("%s: var '%s' :: %s\n", program->name, name,
+ gl_type_str(type));
+ // TODO: bind sampler uniforms
+ if (type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE) {
+ debug("create_uniform_bindings: skipping %s :: %s\n",
+ name, gl_type_str(type));
+ continue;
+ }
+
+ for (binding_id = 0; binding_id < num_bindings; binding_id++) {
+ binding = &bindings[binding_id];
+ for (lens_id = 0; lens_id < binding->num_lenses; lens_id++) {
+ lens = &binding->lenses[lens_id];
+ if (!strcmp(name, lens->name)) {
+ lens_type = datatype_to_gl_type(lens->type);
+ if (type != lens_type) {
+ printf("shader var type mismatch: %s shader(%s) != struct(%s)\n",
+ name,
+ gl_type_str(type),
+ gl_type_str(lens_type));
+ assert(0);
+ }
+ assert(type == datatype_to_gl_type(lens->type));
+ add_uniform(program, unis++, binding_id, lens_id);
+ goto cont;
+ }
+ }
+ }
+
+ printf("bind_uniforms: could not bind uniform '%s' in %s\n",
+ name, program->name);
+ assert(0);
+ cont:
+ ;
+ }
- for (int j = 0; j < shader->n_includes; ++j) {
- time_t include_mtime = shader->include_mtimes[j];
- time_t new_mtime = file_mtime(shader->includes[j]);
- changed |= include_mtime != new_mtime;
- }
+ program->num_uniforms = unis;
+}
- changes[i] = changed;
+static void bind_uniform_lens(struct lens *lens, int location, void *structure)
+{
+ float f;
+ float *fs;
+ int i;
+
+ switch (lens->type) {
+ case DATA_ID_FLOAT:
+ f = get_lens_float(lens, structure);
+ glUniform1f(location, f);
+ check_gl();
+ break;
+
+ case DATA_ID_INT:
+ i = get_lens_int(lens, structure);
+ glUniform1i(location, i);
+ check_gl();
+ break;
+
+ case DATA_ID_VEC2:
+ fs = get_lens_float_array(lens, structure);
+ glUniform2f(location, fs[0], fs[1]);
+ check_gl();
+ break;
+
+ case DATA_ID_VEC3:
+ fs = get_lens_float_array(lens, structure);
+ glUniform3f(location, fs[0], fs[1], fs[2]);
+ check_gl();
+ break;
+
+ case DATA_ID_VEC3P:
+ fs = get_lens_ptr(lens, structure);
+ glUniform3f(location, fs[0], fs[1], fs[2]);
+ check_gl();
+ break;
+
+ case DATA_ID_MAT3:
+ fs = get_lens_float_array(lens, structure);
+ glUniformMatrix3fv(location, 1, 0, fs);
+ check_gl();
+ break;
+
+ case DATA_ID_MAT4P:
+ fs = get_lens_ptr(lens, structure);
+ glUniformMatrix4fv(location, 1, 0, fs);
+ check_gl();
+ break;
+
+ case DATA_ID_MAT4:
+ fs = get_lens_float_array(lens, structure);
+ glUniformMatrix4fv(location, 1, 0, fs);
+ check_gl();
+ break;
+ }
+}
- if (changed) {
- /* printf("making shader %s\n", shader->filename); */
- ok = make_shader(shader->type, shader->filename, &new_shaders[i]);
- if (!ok) {
- // clean up all the new shaders we've created so far
- for (int k = 0; k < i; k++)
- glDeleteShader(new_shaders[k].handle);
- return 0;
- }
- new_shaders_p[i] = &new_shaders[i];
- }
- }
+void bind_uniforms(struct gpu_program *program, void **structures, int num_structs)
+{
+ int i;
+ struct uniform *uniform;
+ struct lens *lens;
+ struct structure_binding *binding;
+ void *structure;
+ void *data;
+
+ if (num_structs < program->num_bindings) {
+ debug("%s: num_structs(%d) < program->num_bindings(%d)\n",
+ program->name, num_structs, program->num_bindings);
+ }
+ assert(num_structs >= program->num_bindings);
+
+ assert(program->name);
+ /*
+ debug("bind_uniforms: %s num_uniforms %d\n",
+ program->name, program->num_uniforms);
+ */
+ for (i = 0; i < program->num_uniforms; i++) {
+ uniform = &program->uniforms[i];
+ binding = &program->bindings[uniform->binding_id];
+ lens = &binding->lenses[uniform->lens_id];
+ /*
+ debug("%s: binding %d %s binding_id:%d lens_id:%d\n",
+ program->name, i,
+ lens->name, uniform->binding_id,
+ uniform->lens_id);
+ */
+ structure = structures[uniform->binding_id];
+ bind_uniform_lens(lens, uniform->location, structure);
+ }
+}
- int any_changes = 0;
- for (int i = 0; i < n_shaders; i++)
- any_changes |= changes[i];
+static void link_uniform(struct gpu_program *program, struct uniform *u)
+{
+ struct lens *lens = get_uniform_lens(program, u->binding_id, u->lens_id);
+ u->location = glGetUniformLocation(program->handle, lens->name);
+ if (u->location == -1) {
+ debug("warn: could not find uniform location: %s in program %s\n",
+ lens->name, program->name);
+ }
+ /* assert(u->location != -1); */
+ check_gl();
+}
- if (!any_changes) {
- return 2;
- }
+int reload_program(struct gpu_program *program, struct gpu_program *programs)
+{
+ int ok;
- ok = make_program_from_shaders(program->name, new_shaders_p,
- n_shaders, &new_program);
+ int n_shaders = program->n_shaders;
+ struct gpu_program new_program;
+ struct shader new_shaders[n_shaders];
+ struct shader *new_shaders_p[n_shaders];
+
+ init_gpu_program(&new_program);
+
+ int changes[n_shaders];
+
+ for (int i = 0; i < n_shaders; i++) {
+ changes[i] = 0;
+ struct shader *shader = &program->shaders[i];
+ new_shaders_p[i] = shader;
+
+ time_t mtime = file_mtime(shader->filename);
+ int changed = mtime != shader->load_mtime;
+
+ for (int j = 0; j < shader->n_includes; ++j) {
+ time_t include_mtime = shader->include_mtimes[j];
+ time_t new_mtime = file_mtime(shader->includes[j]);
+ changed |= include_mtime != new_mtime;
+ }
+
+ changes[i] = changed;
+
+ if (changed) {
+ /* printf("making shader %s\n", shader->filename); */
+ ok = make_shader(shader->type, shader->filename, &new_shaders[i]);
+ if (!ok) {
+ // clean up all the new shaders we've created so far
+ for (int k = 0; k < i; k++)
+ glDeleteShader(new_shaders[k].handle);
+ return 0;
+ }
+ new_shaders_p[i] = &new_shaders[i];
+ }
+ }
+
+ int any_changes = 0;
+ for (int i = 0; i < n_shaders; i++)
+ any_changes |= changes[i];
- if (!ok) {
- for (int i = 0; i < n_shaders; i++) {
- glDeleteShader(program->shaders[i].handle);
- }
- return 0;
- }
+ if (!any_changes) {
+ return 2;
+ }
- *program = new_program;
+ ok = make_program_from_shaders(program->name, new_shaders_p,
+ n_shaders, &new_program,
+ program->bindings,
+ program->num_bindings);
+
+ if (!ok) {
+ for (int i = 0; i < n_shaders; i++) {
+ glDeleteShader(program->shaders[i].handle);
+ }
+ return 0;
+ }
- find_program_uniforms(program, programs);
- return 1;
+ *program = new_program;
+ return 1;
}
-#endif
int
-make_program(const char *name,
- struct shader *vertex,
- struct shader *fragment,
- struct gpu_program *program)
+make_program(const char *name, struct shader *vertex, struct shader *fragment,
+ struct gpu_program *program, struct structure_binding *bindings,
+ int num_bindings)
{
- struct shader *shaders[] = { vertex, fragment };
- return make_program_from_shaders(name, shaders, 2, program);
+ struct shader *shaders[] = { vertex, fragment };
+ return make_program_from_shaders(name, shaders, 2, program, bindings,
+ num_bindings);
}
int make_program_from_shaders(const char *name, struct shader **shaders,
- int n_shaders, struct gpu_program *program)
+ int n_shaders, struct gpu_program *program,
+ struct structure_binding *bindings,
+ int num_bindings)
{
GLint program_ok;
// TODO: relax these constraints
program->handle = glCreateProgram();
- check_gl();
- program->n_shaders = n_shaders;
- program->name = name;
-
- assert(n_shaders <= MAX_SHADERS);
- for (int i = 0; i < n_shaders; i++) {
- struct shader *shader = shaders[i];
- program->shaders[i] = *shader;
- /* printf("attaching shader %s\n", shader->filename); */
- /* for (int j = 0; j < shader->n_includes; ++j) { */
- /* printf("attaching shader %s dep %s \n", shader->filename, */
- /* shader->includes[j]); */
- /* } */
- glAttachShader(program->handle, shader->handle);
- check_gl();
- }
+ check_gl();
+ program->n_shaders = n_shaders;
+ program->name = name;
+
+ assert(n_shaders <= MAX_SHADERS);
+ for (int i = 0; i < n_shaders; i++) {
+ struct shader *shader = shaders[i];
+ program->shaders[i] = *shader;
+ /* printf("attaching shader %s\n", shader->filename); */
+ /* for (int j = 0; j < shader->n_includes; ++j) { */
+ /* printf("attaching shader %s dep %s \n", shader->filename, */
+ /* shader->includes[j]); */
+ /* } */
+ glAttachShader(program->handle, shader->handle);
+ check_gl();
+ }
glLinkProgram(program->handle);
- check_gl();
+ check_gl();
glGetProgramiv(program->handle, GL_LINK_STATUS, &program_ok);
if (!program_ok) {
fprintf(stderr, "Failed to link shader program:\n");
- show_info_log(program->handle);
+ show_program_info_log(program->handle);
glDeleteProgram(program->handle);
return 0;
}
+ if (num_bindings > 0)
+ create_uniform_bindings(program, bindings, num_bindings);
+
+ create_attribute_bindings(program);
+
return 1;
}
diff --git a/src/shader.h b/src/shader.h
@@ -4,88 +4,76 @@
#include <time.h>
#include "gl.h"
#include "vbo.h"
+#include "data_id.h"
#define SHADER(f) "etc/shaders/" f
#define MAX_SHADER_INCLUDES 16
#define MAX_INCLUDE_FNAME_LEN 64
#define MAX_SHADERS 5
+#define MAX_UNIFORMS 64
+#define MAX_SHADER_STRUCTS 4
+
+/* structure binding */
+struct structure_binding {
+ struct lens *lenses;
+ int num_lenses;
+};
struct shader {
GLenum type;
GLuint handle;
- int n_includes;
+ int n_includes;
const char *filename;
- char includes[MAX_SHADER_INCLUDES][MAX_INCLUDE_FNAME_LEN];
- time_t include_mtimes[MAX_SHADER_INCLUDES];
+ char includes[MAX_SHADER_INCLUDES][MAX_INCLUDE_FNAME_LEN];
+ time_t include_mtimes[MAX_SHADER_INCLUDES];
time_t load_mtime;
};
-enum program_type {
- DEFAULT_PROGRAM,
- TERRAIN_PROGRAM,
- UI_PROGRAM,
- SKYBOX_PROGRAM,
- CHESS_PIECE_PROGRAM,
- NUM_PROGRAMS,
-};
-
-
-enum uniform_id {
- UNIFORM_AMBIENT_STR,
- UNIFORM_CAMERA_POSITION,
- UNIFORM_DEPTH_MVP,
- UNIFORM_DEPTH_VP,
- UNIFORM_DIFFUSE_ON,
- UNIFORM_FOG_ON,
- UNIFORM_LIGHT_DIR,
- UNIFORM_LIGHT_INTENSITY,
- UNIFORM_MODEL,
- UNIFORM_MODEL_VIEW,
- UNIFORM_MVP,
- UNIFORM_NORMAL_MATRIX,
- UNIFORM_SKY_INTENSITY,
- UNIFORM_SUN_COLOR,
- UNIFORM_TIME,
- UNIFORM_VIEW_PROJ,
- UNIFORM_IS_WHITE,
- MAX_UNIFORMS
-};
-
struct uniform {
- enum uniform_id id;
- const char *name;
- int location;
+ int id;
+ int location;
+ int binding_id;
+ int lens_id;
};
struct gpu_program {
struct shader shaders[MAX_SHADERS];
- struct uniform uniforms[MAX_UNIFORMS];
+ struct uniform uniforms[MAX_UNIFORMS];
+ struct structure_binding *bindings;
+ int num_bindings;
gpu_addr vertex_attrs[MAX_VERTEX_ATTRS];
- int n_shaders;
+ int n_shaders;
+ int num_uniforms;
+ int active_attributes;
GLuint handle;
- const char *name;
+ const char *name;
};
-void add_uniform(struct gpu_program *program, const char *name, enum uniform_id id);
-void add_attribute(struct gpu_program *program, const char *name, enum vertex_attr attr);
+void add_uniform(struct gpu_program *program, int id, int binding_id, int lens_id);
+
+void create_shader_bindings(struct gpu_program *program, struct structure_binding *bindings, int num_bindings);
#define NO_GEOM_SHADER NULL
int reload_program(struct gpu_program *program, struct gpu_program *programs);
int make_shader(GLenum type, const char *filename, struct shader *shader);
-void find_uniforms(struct gpu_program *programs);
-void find_program_uniforms(struct gpu_program *program,
- struct gpu_program *programs);
+void bind_uniforms(struct gpu_program *program, void **structures, int num_structs);
+
void init_gpu_program(struct gpu_program *program);
int make_program_from_shaders(const char *name,
struct shader **shaders,
int n_shaders,
- struct gpu_program *program);
+ struct gpu_program *program,
+ struct structure_binding *bindings,
+ int n_bindings
+ );
struct shader *get_program_shader(struct gpu_program *program, GLenum type);
-int make_program(const char *name, struct shader *vertex, struct shader *fragment, struct gpu_program *program);
+int make_program(const char *name, struct shader *vertex, struct shader *fragment,
+ struct gpu_program *program, struct structure_binding *bindings,
+ int n_bindings);
#endif /* POLYADVENT_SHADER_H */
diff --git a/src/skybox.c b/src/skybox.c
@@ -3,8 +3,6 @@
#include "util.h"
#include "texture.h"
-#include <stdio.h>
-
static GLfloat skybox_vertices[] = {
1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 top
1.0, 1.0,-1.0, 1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, // v5-v0-v3-v4 right
@@ -35,6 +33,16 @@ static u32 skybox_indices[] = {
};
+#define SKY_LENS(field, typ) { #field, offsetof(struct skybox, field), DATA_ID_##typ }
+static struct lens skybox_lenses[] = {
+ SKY_LENS(mvp, MAT4P),
+};
+#undef SKY_LENS
+
+static struct structure_binding skybox_bindings[] = {
+ { skybox_lenses, ARRAY_SIZE(skybox_lenses) }
+};
+
void create_skybox(struct skybox *skybox, struct gpu_program *program) {
struct shader vertex, frag;
struct shader *shaders[] = {&vertex, &frag};
@@ -60,6 +68,7 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) {
struct model *model = new_model(&skybox->model_id); assert(model);
struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
+ model->name = "skybox";
make_buffer_geometry(&mkgeom, geom);
static const char *faces[6] = {
@@ -82,25 +91,16 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) {
/* }; */
model->texture = create_cubemap(faces);
- printf("cubemap texture %d\n", model->texture);
make_shader(GL_VERTEX_SHADER, SHADER("skybox.v.glsl"), &vertex);
check_gl();
make_shader(GL_FRAGMENT_SHADER, SHADER("skybox.f.glsl"), &frag);
check_gl();
- ok = make_program("skybox", &vertex, &frag, skybox->program);
+ ok = make_program("skybox", &vertex, &frag, skybox->program,
+ skybox_bindings, ARRAY_SIZE(skybox_bindings));
assert(ok);
check_gl();
-
- skybox->uniforms.mvp =
- glGetUniformLocation(skybox->program->handle, "mvp");
-
- skybox->attrs[va_position] = (gpu_addr)
- glGetAttribLocation(skybox->program->handle, "position");
-
- skybox->attrs[va_tex_coord] = (gpu_addr)
- glGetAttribLocation(skybox->program->handle, "tex_coord");
}
@@ -108,6 +108,9 @@ void render_skybox(struct skybox *skybox, mat4 *camera) {
struct model *model = get_model(&skybox->model_id); assert(model);
struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
+ void *structures[] = { skybox };
+
+ skybox->mvp = camera;
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
@@ -116,13 +119,12 @@ void render_skybox(struct skybox *skybox, mat4 *camera) {
glUseProgram(skybox->program->handle);
check_gl();
- glUniformMatrix4fv(skybox->uniforms.mvp, 1, 0, camera);
- check_gl();
+ bind_uniforms(skybox->program, structures, ARRAY_SIZE(structures));
glBindTexture(GL_TEXTURE_CUBE_MAP, model->texture);
check_gl();
- render_geometry(geom, skybox->attrs, skybox->program);
+ render_geometry(geom, skybox->program);
check_gl();
glDepthMask(GL_TRUE);
diff --git a/src/skybox.h b/src/skybox.h
@@ -8,13 +8,10 @@
#include "mat4.h"
struct skybox {
- struct gpu_program *program;
- struct model_id model_id;
- gpu_addr attrs[MAX_VERTEX_ATTRS];
- struct node node;
- struct {
- int mvp;
- } uniforms;
+ struct gpu_program *program;
+ struct model_id model_id;
+ struct node node;
+ float *mvp;
};
void create_skybox(struct skybox *skybox, struct gpu_program *program);
diff --git a/src/terrain.c b/src/terrain.c
@@ -1,4 +1,5 @@
+
#include "terrain.h"
#include "util.h"
#include "delaunay.h"
@@ -6,9 +7,6 @@
#include "vec3.h"
#include "perlin.h"
#include "poisson.h"
-#include "mdl.h"
-
-static const double pdist = 24.0;
static const float plane_verts[] = {
-1,-1,0, -1,1,0, 1,1,0, 1,-1,0
@@ -55,13 +53,6 @@ void reset_terrain(struct terrain *terrain, float size) {
assert(ent);
}
-double offset_fn(struct terrain* terrain, double x, double y) {
- struct perlin_settings *perlin = &terrain->settings;
- double ox = perlin->ox;
- double oy = perlin->oy;
- return old_noisy_boi(terrain, ox+x, oy+y);
-}
-
void init_terrain(struct terrain *terrain, float size) {
init_id(&terrain->entity_id);
@@ -70,9 +61,7 @@ void init_terrain(struct terrain *terrain, float size) {
struct model *model = new_model(&ent->model_id); assert(model);
/* struct model *model = init_model(&ent->model_id); assert(model); */
- assert(terrain->entity_id.index == 0);
-
- model->shader = TERRAIN_PROGRAM;
+ model->shader = 1;
node_set_label(node, "terrain");
ent->flags &= ~ENT_CASTS_SHADOWS;
@@ -80,22 +69,18 @@ void init_terrain(struct terrain *terrain, float size) {
/* node->pos[2] = 20.0; */
reset_terrain(terrain, size);
+}
- terrain->fn = offset_fn;
- terrain->cell_size = pdist;
- terrain->n_cells = round(size / terrain->cell_size) + 1;
- debug("n_cells %d\n", terrain->n_cells);
-
- struct terrain_cell *grid =
- calloc(terrain->n_cells * terrain->n_cells, sizeof(struct terrain_cell));
-
- terrain->grid = grid;
-
+double offset_fn(struct terrain* terrain, double x, double y) {
+ struct perlin_settings *perlin = &terrain->settings;
+ double ox = perlin->ox;
+ double oy = perlin->oy;
+ return old_noisy_boi(terrain, ox+x, oy+y);
}
void gen_terrain_samples(struct terrain *terrain, float scale, const double pdist) {
- debug("generating terrain samples...\n");
+ debug("generating terrain samples\n");
if (terrain->samples)
free(terrain->samples);
@@ -105,12 +90,9 @@ void gen_terrain_samples(struct terrain *terrain, float scale, const double pdis
/* struct point *samples = */
/* uniform_samples(n_samples, game->terrain.size); */
-
struct point *samples =
poisson_disk_samples(pdist, terrain->size, 30, &n_samples);
- debug("done generating terrain samples\n");
-
/* remap_samples(samples, n_samples, game->terrain.size); */
/* draw_samples(samples, pdist, n_samples, game->terrain.size); */
@@ -123,6 +105,7 @@ void gen_terrain_samples(struct terrain *terrain, float scale, const double pdis
static inline struct terrain_cell *index_terrain_cell(struct terrain *terrain, int x, int y)
{
if (x < 0 || y < 0 || x >= terrain->n_cells || y >= terrain->n_cells) {
+ assert(!"terrain oob");
return NULL;
}
@@ -133,11 +116,10 @@ static inline struct terrain_cell *query_terrain_cell(struct terrain *terrain,
float x, float y,
int *grid_x, int *grid_y)
{
- if (x < 0) return NULL;
- if(y < 0) return NULL;
- if(x >= terrain->size) return NULL;
- if(y >= terrain->size) return NULL;
-
+ assert(x >= 0);
+ assert(y >= 0);
+ assert(x < terrain->size);
+ assert(y < terrain->size);
*grid_x = grid_index(terrain, x);
*grid_y = grid_index(terrain, y);
@@ -147,7 +129,7 @@ static inline struct terrain_cell *query_terrain_cell(struct terrain *terrain,
void query_terrain_grid(struct terrain *terrain, float x, float y,
struct terrain_cell *cells[9])
{
- int grid_x = 0, grid_y = 0;
+ int grid_x, grid_y;
// middle
cells[4] = query_terrain_cell(terrain, x, y, &grid_x, &grid_y);
@@ -218,94 +200,45 @@ static double distance_to_closest_edge(double size, double x, double y) {
return min(top, min(left, min(right, bottom)));
}
-static void compute_bounding(float *vertices, int num_verts, vec3 *min, vec3 *max)
-{
- int i;
- for (i = 0; i < num_verts; i++) {
- }
-}
-
-void create_terrain_collision(struct terrain *terrain)
-{
- double x, y;
- int n;
- u32 i;
-
- for (i = 0; i < (u32)terrain->n_verts; i++) {
- n = i*3;
- /* double dx, dy; */
-
- x = terrain->verts[n+0];
- y = terrain->verts[n+1];
-
- int grid_x = x / terrain->cell_size;
- int grid_y = y / terrain->cell_size;
-
- // clamp height at edge
- printf("%f %f %f %d grid_x %d grid_y %f cell_size\n",
- x, y, terrain->verts[n+2],
- grid_x, grid_y, terrain->cell_size);
-
- struct terrain_cell *cell =
- index_terrain_cell(terrain, grid_x, grid_y);
-
- insert_grid_vertex(cell, n);
- }
-}
-
-
-void load_terrain(struct terrain *terrain)
-{
- int seed;
-
- assert(terrain->size > 0);
- struct mdl_geometry terrain_mdl;
- init_mdl_geometry(&terrain_mdl);
- load_mdl("terrain.mdl", NULL, &terrain_mdl);
-
- struct entity *ent = get_entity(&terrain->entity_id); assert(ent);
- struct model *model = get_model(&ent->model_id); assert(model);
- struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
-
- assert(terrain_mdl.mkgeom.joint_weights == 0);
-
- make_buffer_geometry(&terrain_mdl.mkgeom, geom);
-
- terrain->verts = terrain_mdl.mkgeom.vertices;
- terrain->n_verts = terrain_mdl.mkgeom.num_verts;
-
- //struct vert_tris *vert_tris = calloc(terrain->n_verts, sizeof(struct vert_tris));
- //terrain->vtris = vert_tris;
-
- //create_terrain_collision(terrain);
-}
-
void create_terrain(struct terrain *terrain, float scale, int seed) {
u32 i;
- int n;
- double x, y, z;
const double size = terrain->size;
+ static const double pdist = 24.0;
terrain->settings.seed = seed;
float tmp1[3], tmp2[3];
if (!terrain->n_samples) {
gen_terrain_samples(terrain, scale, pdist);
- //save_samples(terrain->samples, seed, terrain->n_samples);
+ /* save_samples(terrain->samples, seed, terrain->n_samples); */
}
assert(terrain->n_samples > 0);
del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points));
float *verts = calloc(terrain->n_samples * 3, sizeof(*verts));
+ terrain->cell_size = pdist;
+ terrain->n_cells = round(size / terrain->cell_size) + 1;
+ debug("n_cells %d\n", terrain->n_cells);
+
+ struct terrain_cell *grid =
+ calloc(terrain->n_cells * terrain->n_cells, sizeof(struct terrain_cell));
+
+ terrain->grid = grid;
+
+ /* float *normals = calloc(terrain->n_samples * 3, sizeof(*verts)); */
+
+ terrain->fn = offset_fn;
+ // n random samples from our noise function
for (i = 0; i < (u32)terrain->n_samples; i++) {
- n = i*3;
+ int n = i*3;
+ double x, y;
+ /* double dx, dy; */
+
x = terrain->samples[i].x;
y = terrain->samples[i].y;
double z = terrain->fn(terrain, x, y);
- double d = distance_to_closest_edge(size, x, y);
- z *= (d / (size/2.0)) * 2.0;
points[i].x = x;
points[i].y = y;
@@ -313,17 +246,28 @@ void create_terrain(struct terrain *terrain, float scale, int seed) {
verts[n] = (float)x;
verts[n+1] = (float)y;
+ int grid_x = verts[n] / terrain->cell_size;
+ int grid_y = verts[n+1] / terrain->cell_size;
+
+ // clamp height at edge
+
+ double d = distance_to_closest_edge(size, x, y);
+ z *= (d / (size/2.0)) * 2.0;
+
+ struct terrain_cell *cell =
+ index_terrain_cell(terrain, grid_x, grid_y);
+
+ assert(cell);
+
+ insert_grid_vertex(cell, n);
+
static const double limit = 1.4;
if (x < limit || x > size-limit || y < limit || y > size-limit)
- verts[n+2] = 0;
+ verts[n+2] = 0;
else
- verts[n+2] = (float)z;
+ verts[n+2] = (float)z;
}
- /* float *normals = calloc(terrain->n_samples * 3, sizeof(*verts)); */
-
- // n random samples from our noise function
-
delaunay2d_t *del = delaunay2d_from(points, terrain->n_samples);
tri_delaunay2d_t *tri = tri_delaunay2d_from(del);
@@ -388,27 +332,20 @@ void create_terrain(struct terrain *terrain, float scale, int seed) {
struct entity *ent = get_entity(&terrain->entity_id);
assert(ent);
- struct mdl_geometry terrain_mdl;
- init_mdl_geometry(&terrain_mdl);
-
- struct make_geometry *mkgeom = &terrain_mdl.mkgeom;
+ struct make_geometry mkgeom;
+ init_make_geometry(&mkgeom);
- mkgeom->num_verts = num_verts;
- mkgeom->vertices = (float*)del_verts;
- mkgeom->normals = (float*)del_norms;
- mkgeom->indices = (u32*)del_indices;
- mkgeom->num_indices = num_verts;
+ mkgeom.num_verts = num_verts;
+ mkgeom.vertices = (float*)del_verts;
+ mkgeom.normals = (float*)del_norms;
+ mkgeom.indices = (u32*)del_indices;
+ mkgeom.num_indices = num_verts;
struct model *model = get_model(&ent->model_id); assert(model);
struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
- assert(mkgeom->joint_weights == 0);
-
- make_buffer_geometry(mkgeom, geom);
-
- compute_bounding(mkgeom->vertices, mkgeom->num_verts, terrain_mdl.min,
- terrain_mdl.max);
- save_mdl("terrain.mdl", &terrain_mdl);
+ assert(mkgeom.joint_weights == 0);
+ make_buffer_geometry(&mkgeom, geom);
delaunay2d_release(del);
tri_delaunay2d_release(tri);
@@ -423,8 +360,6 @@ void create_terrain(struct terrain *terrain, float scale, int seed) {
terrain->verts = verts;
terrain->n_verts = num_verts;
- create_terrain_collision(terrain);
-
// we might need norms in memory eventually as well ?
free(del_norms);
free(del_indices);
diff --git a/src/terrain.h b/src/terrain.h
@@ -7,8 +7,8 @@
#include "model.h"
#include "debug.h"
-#define MAX_CELL_VERTS 16
-#define MAX_VERT_TRIS 32
+#define MAX_CELL_VERTS 4
+#define MAX_VERT_TRIS 20
struct point;
@@ -68,7 +68,6 @@ void gen_terrain_samples(struct terrain *terrain, float scale, const double pdis
void init_terrain(struct terrain *terrain, float size);
void reset_terrain(struct terrain *terrain, float size);
void create_terrain(struct terrain *terrain, float scale, int seed);
-void load_terrain(struct terrain *terrain);
void destroy_terrain(struct terrain *terrain);
void query_terrain_grid(struct terrain *terrain, float x, float y, struct terrain_cell *cells[9]);
diff --git a/src/terrain_collision.c b/src/terrain_collision.c
@@ -1,7 +1,6 @@
#include "terrain_collision.h"
-
-#include <float.h>
+#include <stdint.h>
struct grid_query {
struct terrain_cell *cell;
@@ -23,8 +22,6 @@ static void get_closest_verts(struct terrain *terrain,
{
for (int i = 0; i < 9; i++) {
struct terrain_cell *cell = cells[i];
- if (!cell)
- continue;
for (int j = 0; j < cell->vert_count; j++) {
vec3 *vpos = &terrain->verts[cell->verts_index[j]];
float d = vec3_distsq(pos, vpos);
@@ -170,7 +167,7 @@ struct tri *collide_terrain(struct terrain *terrain, float *pos, float *move, fl
struct terrain_cell *cells[9] = {0};
struct grid_query queries[3];
for (int i = 0; i < 3; i++) {
- queries[i].distance = FLT_MAX;
+ queries[i].distance = 3.402823e+38;
queries[i].cell = NULL;
queries[i].cell_vert_index = -1;
}
diff --git a/src/test_game.c b/src/test_game.c
@@ -6,9 +6,11 @@
#include "game.h"
#include "node.h"
#include "render.h"
+#include "shader.h"
#include "quat.h"
#include "movement.h"
#include "gpu.h"
+#include "util.h"
#include "terrain_collision.h"
#include "orbit_util.h"
#include "mat_util.h"
@@ -21,8 +23,33 @@ static const float bias_matrix[] = {
0.5, 0.5, 0.5, 1.0
};
+#define CU_LENS(field, typ) { #field, offsetof(struct common_uniforms, field), DATA_ID_##typ }
+static struct lens common_lenses[] = {
+ CU_LENS(fog_on, INT),
+ CU_LENS(sky_intensity, FLOAT),
+ CU_LENS(light_intensity, FLOAT),
+ CU_LENS(depth_mvp, MAT4),
+ CU_LENS(mvp, MAT4),
+ CU_LENS(model_view, MAT4),
+ CU_LENS(normal_matrix, MAT4),
+ CU_LENS(sun_color, VEC3),
+ CU_LENS(camera_position, VEC3P),
+ CU_LENS(light_dir, VEC3),
+};
+#undef CU_LENS
+
+struct lens *get_common_lenses()
+{
+ return common_lenses;
+}
+
+int get_common_lenses_length()
+{
+ return ARRAY_SIZE(common_lenses);
+}
+
static void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
- float *m4_ortho, int width, int height)
+ float *m4_ortho, int width, int height)
{
if (shadow_buffer->handle) {
// TODO: remove once delete_fbo deletes attachments
@@ -37,15 +64,15 @@ static void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
struct model *model = get_model(&player->model_id); assert(model);
struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
- float left = geom->min[0] - factor;
+ float left = geom->min[0] - factor;
float right = geom->max[0] + factor;
float bottom = geom->min[1] - factor;
- float top = geom->max[1] + factor;
+ float top = geom->max[1] + factor;
- /* float left = -factor; */
- /* float right = factor; */
+ /* float left = -factor; */
+ /* float right = factor; */
/* float bottom = factor; */
- /* float top = -factor; */
+ /* float top = -factor; */
const float near = -50.0;
const float far = 50.0;
@@ -55,7 +82,7 @@ static void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
create_fbo(shadow_buffer, width, height );
/* fbo_attach_renderbuffer(&res->shadow_buffer, GL_DEPTH24_STENCIL8, */
- /* GL_DEPTH_STENCIL_ATTACHMENT); */
+ /* GL_DEPTH_STENCIL_ATTACHMENT); */
/* fbo_attach_color_texture(&res->shadow_buffer); */
fbo_attach_depth_texture(shadow_buffer);
@@ -63,7 +90,7 @@ static void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
check_fbo(shadow_buffer);
/* fbo_attach_texture(&res->shadow_buffer, GL_DEPTH_COMPONENT16, */
- /* GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); */
+ /* GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); */
}
@@ -80,217 +107,225 @@ static struct entity *get_terrain_entity(struct terrain *t) {
}
static void player_movement(struct game *engine, struct entity *player) {
- /* if (player->flags & ENT_ON_GROUND) */
- /* entity_movement(game, player); */
+ /* if (player->flags & ENT_ON_GROUND) */
+ /* entity_movement(game, player); */
struct node *node = get_node(&player->node_id);
movement(engine, node, 2.0);
}
static void camera_keep_above_ground(struct terrain *terrain,
- struct node *camera) {
- if (get_entity(&terrain->entity_id)->flags & ENT_INVISIBLE)
- return;
- float move[3];
- float *camworld = node_world(camera);
- float pen = 0.0;
- static const float penlim = 1.0;
- struct tri *tri = collide_terrain(terrain, camworld, move, &pen);
-
- if (!tri)
- return;
-
- if (pen < penlim) {
- float dir[3], above[3];
- vec3_normalize(move, dir);
- vec3_scale(dir, pen < 0 ? penlim : -penlim, above);
- vec3_add(camworld, move, camworld);
- vec3_add(camworld, above, camworld);
- /* vec3_add(move, above, move); */
- /* vec3_add(camworld, move, camworld); */
- }
+ struct node *camera) {
+ if (get_entity(&terrain->entity_id)->flags & ENT_INVISIBLE)
+ return;
+ float move[3];
+ float *camworld = node_world(camera);
+ float pen = 0.0;
+ static const float penlim = 1.0;
+ struct tri *tri = collide_terrain(terrain, camworld, move, &pen);
+
+ if (!tri)
+ return;
+
+ if (pen < penlim) {
+ float dir[3], above[3];
+ vec3_normalize(move, dir);
+ vec3_scale(dir, pen < 0 ? penlim : -penlim, above);
+ vec3_add(camworld, move, camworld);
+ vec3_add(camworld, above, camworld);
+ /* vec3_add(move, above, move); */
+ /* vec3_add(camworld, move, camworld); */
+ }
}
static void entity_movement(struct game *game, struct entity *ent)
{
- static const float move_accel = 1.0f;
- static const float max_speed = 10.0f;
- struct node *node = get_node(&ent->node_id);
+ static const float move_accel = 1.0f;
+ static const float max_speed = 10.0f;
+ struct node *node = get_node(&ent->node_id);
- float vel[3];
+ float vel[3];
- float amt = 10.0 * game->dt;
+ float amt = 10.0 * game->dt;
- if (game->input.keystates[SDL_SCANCODE_W]) {
- vec3_forward(ent->velocity, node->orientation, V3(0,amt,0), vel);
- if (vec3_lengthsq(vel) <= max_speed*max_speed)
- vec3_copy(vel, ent->velocity);
- }
+ if (game->input.keystates[SDL_SCANCODE_W]) {
+ vec3_forward(ent->velocity, node->orientation, V3(0,amt,0), vel);
+ if (vec3_lengthsq(vel) <= max_speed*max_speed)
+ vec3_copy(vel, ent->velocity);
+ }
}
static void player_terrain_collision(struct terrain *terrain, struct node *node) {
- // player movement
- static vec3 last_pos[3] = {0};
+ // player movement
+ static vec3 last_pos[3] = {0};
- if (!vec3_approxeq(node->pos, last_pos)) {
- float player_z = node->pos[2];
+ if (!vec3_approxeq(node->pos, last_pos)) {
+ float player_z = node->pos[2];
- float terrain_z =
- terrain->fn(terrain, node->pos[0], node->pos[1]);
+ float terrain_z =
+ terrain->fn(terrain, node->pos[0], node->pos[1]);
- float inset =
- min(0.0, player_z - terrain_z);
+ float inset =
+ min(0.0, player_z - terrain_z);
- if (inset <= 0)
- node_translate(node, V3(0.0, 0.0, -inset));
- }
+ if (inset <= 0)
+ node_translate(node, V3(0.0, 0.0, -inset));
+ }
}
// TODO: match based on some real concept of time
static void day_night_cycle(float time, struct test_game *res) {
- float val = time * 0.0001;
- float intensity = 1.0;//max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0))); */
- struct entity *player = get_player(res);
- struct node *pnode = get_node(&player->node_id);
- assert(pnode);
- struct node *suncam = get_node(&res->sun_camera_id);
- assert(suncam);
+ float val = time * 0.0001;
+ float intensity = 1.0;//max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0))); */
+ struct entity *player = get_player(res);
+ struct node *pnode = get_node(&player->node_id);
+ assert(pnode);
+ struct node *suncam = get_node(&res->sun_camera_id);
+ assert(suncam);
+ struct common_uniforms *cvars = &res->common_vars;
- float light_pos[3];
+ float light_pos[3];
- float g = 0.6;
- float b = 0.4;
- res->sun_color[0] = 1.0;
- res->sun_color[1] = g+intensity*(1.0-g);
- res->sun_color[2] = b+intensity*(1.0-b);
+ float g = 0.6;
+ float b = 0.4;
+ cvars->sun_color[0] = 1.0;
+ cvars->sun_color[1] = g+intensity*(1.0-g);
+ cvars->sun_color[2] = b+intensity*(1.0-b);
- /* res->sun_color[0] = 1.0; */
- /* res->sun_color[1] = 1.0; */
- /* res->sun_color[2] = 1.0; */
+ /* res->sun_color[0] = 1.0; */
+ /* res->sun_color[1] = 1.0; */
+ /* res->sun_color[2] = 1.0; */
- /* vec3_scale(res->sun_color, res->light_intensity, gtmp); */
+ /* vec3_scale(res->sun_color, res->light_intensity, gtmp); */
- /* float intensity = angle <= 0.5 */
- /* ? clamp(roots, darkest, 1.0) */
- /* : clamp(-roots * 0.4, darkest, 0.5); */
+ /* float intensity = angle <= 0.5 */
+ /* ? clamp(roots, darkest, 1.0) */
+ /* : clamp(-roots * 0.4, darkest, 0.5); */
- res->light_intensity = intensity;
+ cvars->light_intensity = intensity;
- /* vec3_normalize(res->light_intensity, res->light_intensity); */
+ /* vec3_normalize(res->light_intensity, res->light_intensity); */
- res->light_dir[0] = 0.0;
- /* res->light_dir[1] = sin(val); */
- /* res->light_dir[2] = cos(val) + 1.0; */
- res->light_dir[1] = 0.8;
- res->light_dir[2] = 0.8;
+ cvars->light_dir[0] = 0.0;
+ /* res->light_dir[1] = sin(val); */
+ /* res->light_dir[2] = cos(val) + 1.0; */
+ cvars->light_dir[1] = 0.8;
+ cvars->light_dir[2] = 0.8;
- vec3_normalize(res->light_dir, res->light_dir);
+ vec3_normalize(cvars->light_dir, cvars->light_dir);
- /* printf("intensity %f(%f) n %f light_dir %f %f\n", roots, intensity, */
- /* n, res->light_dir[1], res->light_dir[2]); */
+ /* printf("intensity %f(%f) n %f light_dir %f %f\n", roots, intensity, */
+ /* n, res->light_dir[1], res->light_dir[2]); */
- vec3_add(pnode->pos, res->light_dir, light_pos);
+ vec3_add(pnode->pos, cvars->light_dir, light_pos);
- /* float target[3]; */
- /* float hh = player->model.geom.max[2] / 2.0; */
- /* vec3_copy(player->node.pos, target); */
- /* target[2] += 2.0; */
+ /* float target[3]; */
+ /* float hh = player->model.geom.max[2] / 2.0; */
+ /* vec3_copy(player->node.pos, target); */
+ /* target[2] += 2.0; */
- look_at(light_pos, pnode->pos, V3(0, 0, 1.0), suncam->mat);
- /* look_at(light_pos, player->node.pos, V3(0, 0, 1.0), res->sun_camera.mat); */
+ look_at(light_pos, pnode->pos, V3(0, 0, 1.0), suncam->mat);
+ /* look_at(light_pos, player->node.pos, V3(0, 0, 1.0), res->sun_camera.mat); */
}
static void player_update(struct game *engine, struct test_game *game, struct entity *player)
{
- struct orbit *camera = &game->orbit_camera;
- struct node *node = get_node(&player->node_id);
- struct node *cam_node = get_node(&game->camera_node_id);
- assert(node);
- assert(cam_node);
-
- orbit_update_from_mouse(camera, &engine->input,engine->user_settings.mouse_sens,
- player, engine->dt);
-
- camera_keep_above_ground(&game->terrain, cam_node);
-
- // move player camera toward camera orientation
- if (input_is_dragging(&engine->input, SDL_BUTTON_RIGHT)) {
- float yaw = game->orbit_camera.coords.azimuth;
- quat_axis_angle(V3(0.0, 0.0, 1.0), -yaw - RAD(90), node->orientation);
- }
-
- struct terrain *terrain = &game->terrain;
-
- player_terrain_collision(terrain, node);
-
- float move[3];
- float pos[3];
- float pen = 0.0;
- vec3_copy(node_world(node), pos);
- /* debug("node_world(player) %f %f %f\n", pos[0], pos[1], pos[2]); */
- struct tri *tri = collide_terrain(terrain, pos, move, &pen);
- //struct tri *tri = NULL;
- /* node_translate(node, move); */
-
- if (tri) {
- if (vec3_eq(move, V3(0,0,0), 0.1)) {
- player->flags |= ENT_ON_GROUND;
- }
- else if (pen < 0) {
- node_translate(node, move);
- /* vec3_all(player->velocity, 0); */
- vec3_scale(player->velocity, 0.1, player->velocity);
- }
- else {
- player->flags &= ~ENT_ON_GROUND;
- }
- }
- else {
- static int tric = 0;
- /* debug("%d no tri\n", tric++); */
- }
-
- if (player->flags & ENT_ON_GROUND &&
- (was_key_pressed_this_frame(engine, SDL_SCANCODE_SPACE) /*||
- was_button_pressed_this_frame(engine, SDL_CONTROLLER_BUTTON_X)*/)) {
- entity_jump(player, 2.0);
- }
-
- /* debug("player velocity %f %f %f\n", */
- /* player->velocity[0], */
- /* player->velocity[1], */
- /* player->velocity[2]); */
-
-// if (player->flags & ENT_AT_REST)
+ struct orbit *camera = &game->orbit_camera;
+ struct node *node = get_node(&player->node_id);
+ struct node *cam_node = get_node(&game->camera_node_id);
+ assert(node);
+ assert(cam_node);
+
+ orbit_update_from_mouse(camera, &engine->input,
+ engine->user_settings.mouse_sens,
+ player, engine->dt);
+
+ camera_keep_above_ground(&game->terrain, cam_node);
+
+ // move player camera toward camera orientation
+ if (input_is_dragging(&engine->input, SDL_BUTTON_RIGHT)) {
+ float yaw = game->orbit_camera.coords.azimuth;
+ quat_axis_angle(V3(0.0, 0.0, 1.0), -yaw - RAD(90), node->orientation);
+ }
+
+ struct terrain *terrain = &game->terrain;
+
+ player_terrain_collision(terrain, node);
+
+ float move[3];
+ float pos[3];
+ float pen = 0.0;
+ vec3_copy(node_world(node), pos);
+ /* debug("node_world(player) %f %f %f\n", pos[0], pos[1], pos[2]); */
+ struct tri *tri = collide_terrain(terrain, pos, move, &pen);
+ //struct tri *tri = NULL;
+ /* node_translate(node, move); */
+
+ if (tri) {
+ if (vec3_eq(move, V3(0,0,0), 0.1)) {
+ player->flags |= ENT_ON_GROUND;
+ }
+ else if (pen < 0) {
+ node_translate(node, move);
+ /* vec3_all(player->velocity, 0); */
+ vec3_scale(player->velocity, 0.1, player->velocity);
+ }
+ else {
+ player->flags &= ~ENT_ON_GROUND;
+ }
+ }
+ else {
+ static int tric = 0;
+ /* debug("%d no tri\n", tric++); */
+ }
+
+ if (player->flags & ENT_ON_GROUND &&
+ (was_key_pressed_this_frame(engine, SDL_SCANCODE_SPACE) /*||
+ was_button_pressed_this_frame(engine, SDL_CONTROLLER_BUTTON_X)*/)) {
+ entity_jump(player, 2.0);
+ }
+
+ /* debug("player velocity %f %f %f\n", */
+ /* player->velocity[0], */
+ /* player->velocity[1], */
+ /* player->velocity[2]); */
+
+// if (player->flags & ENT_AT_REST)
// vec3_scale(player->velocity, 0.00001, player->velocity);
- node_translate(node, player->velocity);
- node_recalc(node);
+ node_translate(node, player->velocity);
+ node_recalc(node);
}
+enum binding_structs {
+ COMMON_UNIFORMS,
+ CHESS_PIECE_UNIFORMS,
+};
+
+static struct structure_binding uniform_bindings[] = {
+ [COMMON_UNIFORMS] =
+ { common_lenses, ARRAY_SIZE(common_lenses) },
+};
void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height)
{
- struct shader vertex, terrain_vertex, chess_piece_vertex, terrain_geom, fragment, fragment_smooth;
+ struct shader vertex, terrain_vertex, terrain_geom, fragment, fragment_smooth;
struct shader terrain_teval, terrain_tc;
float tmp_matrix[16];
int ok = 0;
+ gpu->num_programs = NUM_TEST_GAME_PROGRAMS;
// Shaders
ok = make_shader(GL_VERTEX_SHADER, SHADER("vertex-color.glsl"),
- &vertex);
+ &vertex);
rtassert(ok, "vertex-color shader");
ok = make_shader(GL_VERTEX_SHADER, SHADER("terrain.v.glsl"), &terrain_vertex);
rtassert(ok, "terrain vertex shader");
check_gl();
- ok = make_shader(GL_VERTEX_SHADER, SHADER("chess-piece.v.glsl"), &chess_piece_vertex);
- rtassert(ok, "chess-piece vertex shader");
- check_gl();
-
ok = make_shader(GL_FRAGMENT_SHADER, SHADER("main.f.glsl"), &fragment);
rtassert(ok, "default fragment shader");
check_gl();
@@ -303,38 +338,35 @@ void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height
game->proj_persp);
struct gpu_program *programs = gpu->programs;
- struct gpu_program *program;
ok = make_program("terrain", &terrain_vertex, &fragment,
- &programs[TERRAIN_PROGRAM]);
- // TODO: replace rtassert with error reporting/handling
+ &programs[TERRAIN_PROGRAM],
+ uniform_bindings,
+ ARRAY_SIZE(uniform_bindings));
rtassert(ok, "terrain program");
check_gl();
- ok = make_program("vertex-color", &vertex, &fragment, &programs[DEFAULT_PROGRAM]);
+ ok = make_program("vertex-color", &vertex, &fragment,
+ &programs[DEFAULT_PROGRAM],
+ uniform_bindings,
+ ARRAY_SIZE(uniform_bindings));
rtassert(ok, "vertex-color program");
check_gl();
-
- program = &programs[CHESS_PIECE_PROGRAM];
- ok = make_program("chess-piece", &chess_piece_vertex, &fragment, program);
- rtassert(ok, "chess-piece program");
-
- find_uniforms(programs);
}
-void init_gpu_programs(struct gpu *gpu)
-{
-}
+// TODO: add uniforms automatically?
+static void render_test_game(struct game *game, struct test_game *res, struct render_config *config) {
+ float gtmp[3];
+ u32 num_entities;
-void render_test_game(struct game *game, struct test_game *res, struct render_config *config) {
- float gtmp[3];
+ struct common_uniforms *cvars = &res->common_vars;
- glEnable(GL_DEPTH_TEST);
+ cvars->sky_intensity = clamp(cvars->light_intensity, 0.2, 1.0);
+ vec3_scale(cvars->sun_color, cvars->sky_intensity, gtmp);
- float sky_intensity = clamp(res->light_intensity, 0.2, 1.0);
- vec3_scale(res->sun_color, sky_intensity, gtmp);
+ glEnable(GL_DEPTH_TEST);
glClearColor( gtmp[0], gtmp[1], gtmp[2], 1.0 ); //clear background screen to black
/* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */
@@ -346,23 +378,19 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
static float view[MAT4_ELEMS] = { 0 };
static float view_proj[MAT4_ELEMS] = { 0 };
static float normal_matrix[MAT4_ELEMS] = { 0 };
- static float model_view[MAT4_ELEMS] = { 0 };
- static float depth_mvp[MAT4_ELEMS] = { 0 };
+
mat4_id(id);
- mat4_id(model_view);
+ mat4_id(cvars->model_view);
- mat4 *mvp = res->test_mvp;
mat4 *projection = config->projection;
- mat4 *light = res->light_dir;
struct node *camera_node = get_node(&config->camera);
assert(camera_node);
const mat4 *camera = camera_node->mat;
- u32 num_entities;
struct entity *entities =
- get_all_entities(&num_entities, NULL);
+ get_all_entities(&num_entities, NULL);
struct gpu_program *program = NULL;
@@ -370,11 +398,11 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
mat4_multiply(projection, view, view_proj);
if (config->is_depth_pass) {
- glDisable(GL_CULL_FACE);
- mat4_multiply(bias_matrix, view_proj, config->depth_vp);
+ glDisable(GL_CULL_FACE);
+ mat4_multiply(bias_matrix, view_proj, config->depth_vp);
}
else {
- glCullFace(GL_BACK);
+ glCullFace(GL_BACK);
}
mat4_inverse((float *)camera, view);
@@ -386,6 +414,8 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_model->texture);
check_gl();
+ cvars->camera_position = (float*)&camera[M_X];
+
for (u32 i = 0; i < num_entities; ++i) {
struct entity *entity = &entities[i];
struct model *model = get_model(&entity->model_id);
@@ -394,44 +424,39 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
assert(node);
if (entity->flags & ENT_INVISIBLE)
- continue;
+ continue;
if (config->is_depth_pass && !(entity->flags & ENT_CASTS_SHADOWS))
- continue;
+ continue;
program = &game->gpu.programs[model->shader];
glUseProgram(program->handle);
check_gl();
- uniform_3f(program, UNIFORM_CAMERA_POSITION, &camera[M_X]);
-
- if (model->shader == CHESS_PIECE_PROGRAM) {
- uniform_1i(program, UNIFORM_IS_WHITE,
- (entity->flags & ENT_IS_WHITE) == ENT_IS_WHITE);
- }
+ mat4_multiply(view_proj, node->mat, cvars->mvp);
+ mat4_copy(node->mat, cvars->model_view);
+ mat4_multiply(config->depth_vp, cvars->model_view, cvars->depth_mvp);
- uniform_1i(program, UNIFORM_FOG_ON, res->fog_on);
- uniform_3f(program, UNIFORM_LIGHT_DIR, light);
- uniform_1f(program, UNIFORM_LIGHT_INTENSITY, res->light_intensity);
- uniform_1f(program, UNIFORM_SKY_INTENSITY, sky_intensity);
- uniform_3f(program, UNIFORM_SUN_COLOR, res->sun_color);
+ void *shader_data[] = {
+ [COMMON_UNIFORMS] = cvars,
+ [CHESS_PIECE_UNIFORMS] = entity->data,
+ };
- mat4_multiply(view_proj, node->mat, mvp);
- mat4_copy(node->mat, model_view);
- mat4_multiply(config->depth_vp, model_view, depth_mvp);
- uniform_m4f(program, UNIFORM_DEPTH_MVP, depth_mvp);
- uniform_m4f(program, UNIFORM_MVP, mvp);
- uniform_m4f(program, UNIFORM_MODEL, node->mat);
+ bind_uniforms(program, shader_data, ARRAY_SIZE(shader_data));
+ check_gl();
+ /*
recalc_normals(program->uniforms[UNIFORM_NORMAL_MATRIX].location,
- model_view, normal_matrix);
+ model_view, normal_matrix);
+
check_gl();
+ */
struct geometry *geo = get_geometry(&model->geom_id);
/* debug("geo node %s\n", node->label); */
assert(geo);
- render_geometry(geo, program->vertex_attrs, program);
+ render_geometry(geo, program);
check_gl();
}
@@ -451,7 +476,7 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
}
if (config->draw_ui)
- render_ui(&game->ui, view);
+ render_ui(&res->ui, view);
//player
// y tho
@@ -472,17 +497,18 @@ void render_test_game(struct game *game, struct test_game *res, struct render_co
void update_test_game (struct game *engine, struct test_game *game) {
static int toggle_fog = 0;
static int needs_terrain_update = 0;
- //struct terrain *terrain = &game->terrain;
- struct node *root = get_node(&game->root_id);
- struct entity *player = get_player(game);
- struct node *pnode = get_node(&player->node_id);
- struct node *cam_node = get_node(&game->camera_node_id);
+ //struct terrain *terrain = &game->terrain;
+ struct node *root = get_node(&game->root_id);
+ struct entity *player = get_player(game);
+ struct node *pnode = get_node(&player->node_id);
+ struct node *cam_node = get_node(&game->camera_node_id);
+ struct common_uniforms *cvars = &game->common_vars;
assert(pnode);
assert(cam_node);
float *time = &game->time;
- float *light = game->light_dir;
+ float *light = cvars->light_dir;
gravity(player, engine->dt);
@@ -491,8 +517,8 @@ void update_test_game (struct game *engine, struct test_game *game) {
needs_terrain_update = 0;
}
- /* spherical_dir(game->test_resources.camera.coords, camera_dir); */
- /* vec3_scale(camera_dir, -1, camera_dir); */
+ /* spherical_dir(game->test_resources.camera.coords, camera_dir); */
+ /* vec3_scale(camera_dir, -1, camera_dir); */
if (engine->input.modifiers & KMOD_ALT &&
ideq(&game->camera_node_id, &game->free_camera_id))
@@ -510,8 +536,9 @@ void update_test_game (struct game *engine, struct test_game *game) {
player_update(engine, game, player);
#ifdef DEBUG
- if (was_key_pressed_this_frame(engine, SDL_SCANCODE_R))
+ if (was_key_pressed_this_frame(engine, SDL_SCANCODE_R)) {
try_reload_shaders(&engine->gpu);
+ }
#endif
if (was_key_pressed_this_frame(engine, SDL_SCANCODE_F5)) {
@@ -538,7 +565,7 @@ void update_test_game (struct game *engine, struct test_game *game) {
}
if (toggle_fog) {
- game->fog_on = !game->fog_on;
+ cvars->fog_on ^= 1;
toggle_fog = 0;
}
@@ -563,7 +590,7 @@ void test_game_frame(struct game *engine, struct test_game *game)
};
struct render_config default_config = {
- .draw_ui = 0,
+ .draw_ui = 1,
.is_depth_pass = 0,
.camera = game->camera_node_id,
.projection = game->proj_persp,
@@ -571,7 +598,7 @@ void test_game_frame(struct game *engine, struct test_game *game)
};
struct entity *player = get_entity(&game->player_id);
- if (engine->input.resized_height) {
+ if (engine->input.resized_height) {
mat4_perspective(60 /* fov */,
(float)engine->width / (float)engine->height, 0.1,
10000.0, game->proj_persp);
@@ -580,28 +607,27 @@ void test_game_frame(struct game *engine, struct test_game *game)
engine->width, engine->height);
}
- update_test_game(engine, game);
+ update_test_game(engine, game);
- struct fbo *fbo = &game->shadow_buffer;
- check_fbo(fbo);
- bind_fbo(fbo);
- /* glDrawBuffer(GL_NONE); */
+ struct fbo *fbo = &game->shadow_buffer;
+ check_fbo(fbo);
+ bind_fbo(fbo);
+ /* glDrawBuffer(GL_NONE); */
- render_test_game(engine, game, &fbo_render_config);
- unbind_fbo(&game->shadow_buffer);
- render_test_game(engine, game, &default_config);
+ render_test_game(engine, game, &fbo_render_config);
+ unbind_fbo(&game->shadow_buffer);
+ render_test_game(engine, game, &default_config);
}
-void init_test_game(struct test_game *game, struct gpu *gpu, int width, int height)
+void init_test_game(struct game *engine, struct test_game *game)
{
memset(game, 0, sizeof(*game));
struct terrain *terrain = &game->terrain;
struct entity *player;
+ struct model *model;
+ struct common_uniforms *cvars = &game->common_vars;
- init_test_gl(game, gpu, width, height);
-
- mat4 *mvp = game->test_mvp;
- mat4 *light_dir = game->light_dir;
+ init_test_gl(game, &engine->gpu, engine->width, engine->height);
init_id(&game->root_id);
init_id(&game->sun_camera_id);
@@ -618,50 +644,46 @@ void init_test_game(struct test_game *game, struct gpu *gpu, int width, int heig
//double scale = 0.03;
double scale = 0.03;
- create_skybox(&game->skybox, &gpu->programs[SKYBOX_PROGRAM]);
+ create_skybox(&game->skybox, &engine->gpu.programs[SKYBOX_PROGRAM]);
+ create_ui(&game->ui, engine->width, engine->height, &engine->gpu.programs[UI_PROGRAM]);
terrain->settings = (struct perlin_settings){
- .depth = 1,
- .freq = scale * 0.08,
- .o1 = 2.0, .o1s = 0.5,
- .o2 = 4.0, .o2s = 0.25,
- .amplitude = 70.0,
- .ox = 0,
- .oy = 0,
- .exp = 5.3,
- .scale = scale
+ .depth = 1,
+ .freq = scale * 0.08,
+ .o1 = 2.0, .o1s = 0.5,
+ .o2 = 4.0, .o2s = 0.25,
+ .amplitude = 70.0,
+ .ox = 0,
+ .oy = 0,
+ .exp = 5.3,
+ .scale = scale
};
init_terrain(terrain, size);
/* terrain->samples = load_samples(&seed, &terrain->n_samples); */
terrain->n_samples = 0;
- //create_terrain(terrain, size, game->seed);
- load_terrain(terrain);
+ create_terrain(terrain, size, engine->seed);
+ //load_terrain(terrain);
/* update_terrain(terrain, terrain->cell_size); */
/* get_entity(&terrain->entity_id)->flags |= ENT_INVISIBLE; */
/* node_scale(&game->skybox.node, size/4.0); */
- mat4_id(mvp);
+ mat4_id(cvars->mvp);
- game->time = 0;
- game->light_intensity = 0.8;
+ cvars->light_intensity = 0.8;
- light_dir[0] = 0.8;
- light_dir[1] = 0.8;
- light_dir[2] = 0.8;
+ cvars->light_dir[0] = 0.8;
+ cvars->light_dir[1] = 0.8;
+ cvars->light_dir[2] = 0.8;
- game->piece_color[0] = 1.0;
- game->piece_color[1] = 1.0;
- game->piece_color[2] = 1.0;
+ cvars->sun_color[0] = 0.5;
+ cvars->sun_color[1] = 0.6;
+ cvars->sun_color[2] = 0.7;
- game->sun_color[0] = 0.5;
- game->sun_color[1] = 0.6;
- game->sun_color[2] = 0.7;
-
- game->fog_on = 0;
- game->diffuse_on = 0;
+ cvars->fog_on = 0;
+ //cvars->diffuse_on = 0;
node_init(root);
node_init(sun_camera);
@@ -681,6 +703,7 @@ void init_test_game(struct test_game *game, struct gpu *gpu, int width, int heig
player->model_id = get_model_by_name("pirate_officer", NULL);
assert(!is_null_id(&player->model_id.id));
+
node_set_label(pnode, "player");
/* node_rotate(pnode, V3(-5.0,0,0)); */
node_attach(&player->node_id, &game->root_id);
@@ -704,7 +727,7 @@ void init_test_game(struct test_game *game, struct gpu *gpu, int width, int heig
// FBO STUFF
init_fbo(&game->shadow_buffer);
- resize_fbos(player, &game->shadow_buffer, game->proj_ortho, width, height);
+ resize_fbos(player, &game->shadow_buffer, game->proj_ortho, engine->width, engine->height);
// FBO STUFF END
// TEXTURES
@@ -724,11 +747,12 @@ void default_scene(struct test_game *game) {
struct entity *tower = new_entity(NULL);
struct node *tnode = get_node(&tower->node_id);
+ struct node *pnode = get_node(&player->node_id);
assert(tnode);
tower->model_id = get_model_by_name("tower", NULL);
node_set_label(tnode, "tower");
- //node_attach(&tower->node_id, &player->node_id);
+ node_attach(&tower->node_id, &player->node_id);
node_translate(tnode, V3(0.0, 50.0, 0.0));
node_recalc(tnode);
float z = terrain->fn(terrain, tnode->mat[M_X], tnode->mat[M_Y]);
@@ -740,40 +764,40 @@ void default_scene(struct test_game *game) {
void entity_test_scene(struct terrain *terrain)
{
- struct model_id rock_model;
- init_id(&rock_model.id);
+ struct model_id rock_model;
+ init_id(&rock_model.id);
- /* model_id rock_model = get_static_model(model_tower, NULL); */
- struct model *pmodel = new_model(&rock_model); assert(pmodel);
- struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom);
- proc_sphere(geom);
+ /* model_id rock_model = get_static_model(model_tower, NULL); */
+ struct model *pmodel = new_model(&rock_model); assert(pmodel);
+ struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom);
+ proc_sphere(geom);
- for (int i = 0; i < 200; i++) {
- struct entity *ent = new_entity(NULL);
- struct node *node = get_node(&ent->node_id);
+ for (int i = 0; i < 200; i++) {
+ struct entity *ent = new_entity(NULL);
+ struct node *node = get_node(&ent->node_id);
- ent->model_id = rock_model;
+ ent->model_id = rock_model;
- double x = rand_0to1() * terrain->size;
- double y = rand_0to1() * terrain->size;
- double z = terrain->fn(terrain, x, y);
+ double x = rand_0to1() * terrain->size;
+ double y = rand_0to1() * terrain->size;
+ double z = terrain->fn(terrain, x, y);
- node_scale(node, pow(15.0, rand_0to1()));
- node_rotate(node, V3(rand_0to1(),rand_0to1(),rand_0to1()));
- node_translate(node, V3(x, y, z));
- node_set_label(node, "rock");
+ node_scale(node, pow(15.0, rand_0to1()));
+ node_rotate(node, V3(rand_0to1(),rand_0to1(),rand_0to1()));
+ node_translate(node, V3(x, y, z));
+ node_set_label(node, "rock");
- node_recalc(node);
- }
+ node_recalc(node);
+ }
}
void pbr_scene(struct test_game *game)
{
- struct entity *ent = new_entity(NULL);
- struct node *node = get_node(&ent->node_id); assert(node);
- struct entity *player = get_player(game);
+ struct entity *ent = new_entity(NULL);
+ struct node *node = get_node(&ent->node_id); assert(node);
+ struct entity *player = get_player(game);
- ent->model_id = get_model_by_name("icosphere", NULL);
- node_set_label(node, "sphere");
+ ent->model_id = get_model_by_name("icosphere", NULL);
+ node_set_label(node, "sphere");
}
diff --git a/src/test_game.h b/src/test_game.h
@@ -10,11 +10,38 @@
#include "gpu.h"
#include "game.h"
+enum test_game_programs {
+ DEFAULT_PROGRAM,
+ TERRAIN_PROGRAM,
+ UI_PROGRAM,
+ SKYBOX_PROGRAM,
+ CHESS_PIECE_PROGRAM,
+ NUM_TEST_GAME_PROGRAMS,
+};
+
+struct common_uniforms {
+// int diffuse_on;
+ int fog_on;
+ float sky_intensity;
+ float light_intensity;
+ float depth_mvp[MAT4_ELEMS];
+ // mat4 *depth_vp;
+ float model_view[MAT4_ELEMS];
+ float mvp[MAT4_ELEMS];
+ float normal_matrix[MAT4_ELEMS];
+ // float time;
+ // float ambient_str;
+ float sun_color[3];
+ float *camera_position;
+ float light_dir[3];
+};
+
struct test_game {
struct terrain terrain;
struct vbo vertex_buffer, element_buffer, normal_buffer;
struct fbo shadow_buffer;
+ struct common_uniforms common_vars;
node_id root_id;
entity_id player_id;
struct geometry qh_test;
@@ -25,26 +52,22 @@ struct test_game {
u32 test_cubemap;
float time;
- bool fog_on, diffuse_on;
struct skybox skybox;
- float sun_color[3];
- float piece_color[3];
- float test_mvp[MAT4_ELEMS];
- float light_dir[3];
- float light_intensity;
+ struct ui ui;
float proj_persp[MAT4_ELEMS];
float proj_ortho[MAT4_ELEMS];
};
void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height);
-void render_test_game(struct game *engine, struct test_game *game, struct render_config *config);
-void init_test_game(struct test_game *game, struct gpu *gpu, int width, int height);
+void init_test_game(struct game *engine, struct test_game *game);
void test_game_frame(struct game *engine, struct test_game *game);
void default_scene(struct test_game *);
void entity_test_scene(struct terrain *);
void pbr_scene(struct test_game *);
-void chess_scene(struct test_game *);
+void chess_scene(struct game *, struct test_game *);
+struct lens *get_common_lenses();
+int get_common_lenses_length();
diff --git a/src/ui.c b/src/ui.c
@@ -5,8 +5,7 @@
#include "geometry.h"
#include "util.h"
#include "common.h"
-
-#include <stdio.h>
+#include "data_id.h"
// v1------v0
@@ -53,29 +52,43 @@ static void create_quad(geometry_id *id)
check_gl();
}
-void render_ui(struct ui *ui, float *view) {
- static float mvp[MAT4_ELEMS];
- glDisable(GL_DEPTH_TEST);
- glUseProgram(ui->shader->handle);
- check_gl();
-
- float uipos[2] = {0.01, 0.01};
- float uisize[2] = {0.4, 0.4};
- mat4_multiply(ui->ortho, view, mvp);
-
- // setup camera for shader
- /* glUniform2f(ui->uipos_uniform, uipos[0] * uisize[0], uipos[1] * uisize[1]); */
- glUniform2f(ui->uniforms.uipos, uipos[0], uipos[1]);
- glUniform2f(ui->uniforms.uisize, uisize[0], uisize[1]);
- glUniform1i(ui->uniforms.texture, 0);
+#define UI_LENS(field, typ) { #field, offsetof(struct ui, field), DATA_ID_##typ }
+static struct lens ui_lenses[] = {
+ UI_LENS(uipos, VEC2),
+ UI_LENS(uisize, VEC2),
+ UI_LENS(mvp, MAT4P),
+ UI_LENS(texture, INT),
+};
+#undef UI_LENS
- glUniformMatrix4fv(ui->uniforms.mvp, 1, 0, ui->ortho);
- check_gl();
+static struct structure_binding ui_bindings[] = {
+ { ui_lenses, ARRAY_SIZE(ui_lenses) },
+};
- // render quad
- render_geometry(get_geometry(&ui->quad_geom_id), ui->attrs, ui->shader);
- check_gl();
+void render_ui(struct ui *ui, float *view) {
+ glDisable(GL_DEPTH_TEST);
+ glUseProgram(ui->shader->handle);
+ check_gl();
+
+ ui->uipos[0] = 0.01;
+ ui->uipos[1] = 0.01;
+ ui->uisize[0] = 0.4;
+ ui->uisize[1] = 0.4;
+ ui->texture = 0;
+
+ void *structures[] = { ui };
+
+ assert(ARRAY_SIZE(structures) == ARRAY_SIZE(ui_bindings));
+
+ ui->mvp = ui->ortho;
+ //mat4_multiply(ui->ortho, view, ui->mvp);
+ bind_uniforms(ui->shader, structures, ARRAY_SIZE(structures));
+ check_gl();
+
+ // render quad
+ render_geometry(get_geometry(&ui->quad_geom_id), ui->shader);
+ check_gl();
}
@@ -90,7 +103,6 @@ void resize_ui(struct ui *ui, int width, int height) {
mat4_ortho(left, right, bottom, top, near, far, ui->ortho);
}
-
void create_ui(struct ui *ui, int width, int height, struct gpu_program *shader) {
struct shader vertex;
struct shader fragment;
@@ -108,23 +120,10 @@ void create_ui(struct ui *ui, int width, int height, struct gpu_program *shader)
ok = make_shader(GL_FRAGMENT_SHADER, SHADER("ui.f.glsl"), &fragment);
assert(ok && "ui fragment shader");
- ok = make_program("ui", &vertex, &fragment, ui->shader);
+ ok = make_program("ui", &vertex, &fragment, ui->shader, ui_bindings,
+ ARRAY_SIZE(ui_bindings));
assert(ok && "ui program");
- GLuint program = ui->shader->handle;
-
- ui->uniforms.mvp = glGetUniformLocation(program, "mvp");
- ui->uniforms.uipos = glGetUniformLocation(program, "uipos");
- ui->uniforms.uisize = glGetUniformLocation(program, "uisize");
-
- ui->uniforms.texture =
- glGetUniformLocation(program, "screen_texture");
-
- /* ui->attrs.normal = (gpu_addr)glGetAttribLocation(program, "normal"); */
- ui->attrs[va_position] = (gpu_addr)glGetAttribLocation(program, "position");
- ui->attrs[va_color] = (gpu_addr)glGetAttribLocation(program, "color");
- ui->attrs[va_tex_coord] = (gpu_addr)glGetAttribLocation(program, "tex_coords");
-
check_gl();
resize_ui(ui, width, height);
check_gl();
diff --git a/src/ui.h b/src/ui.h
@@ -7,18 +7,15 @@
#include "geometry.h"
struct ui {
- struct gpu_program *shader;
- geometry_id quad_geom_id;
- gpu_addr attrs[MAX_VERTEX_ATTRS];
-
- struct ui_uniforms {
- GLint mvp;
- GLint uipos;
- GLint uisize;
- GLint texture;
- } uniforms;
-
- float ortho[MAT4_ELEMS];
+ struct gpu_program *shader;
+ geometry_id quad_geom_id;
+
+ GLint texture;
+ float uipos[2];
+ float uisize[2];
+
+ float *mvp;
+ float ortho[MAT4_ELEMS];
};
void create_ui(struct ui *ui, int width, int height,
diff --git a/src/update.c b/src/update.c
@@ -16,25 +16,3 @@
#include "debug.h"
#include <math.h>
-
-static void remap_samples(struct point *points, int n_samples,
- double size)
-{
- double middle = size / 2.0;
-
- for (int i = 0; i < n_samples; ++i) {
- struct point *point = &points[i];
-
- /* double x = point->x/size; */
- /* double y = point->y/size; */
- double dx = point->x - middle;
- double dy = point->y - middle;
- double dist = sqrt(dx*dx + dy*dy);
- double nx = dx / dist;
- double ny = dy / dist;
- double factor = -log(dist)*50.0;
- point->x += nx * factor;
- point->y += ny * factor;
- }
-}
-
diff --git a/src/vbo.h b/src/vbo.h
@@ -17,6 +17,18 @@ enum vertex_attr {
MAX_VERTEX_ATTRS
};
+static inline const char *vertex_attr_str(enum vertex_attr addr)
+{
+ switch(addr) {
+ case va_position: return "position";
+ case va_normal: return "normal";
+ case va_color: return "color";
+ case va_index: return "index";
+ case va_tex_coord: return "tex_coord";
+ default: return "unknown";
+ }
+}
+
struct vbo {
u32 type;
int component_type;
diff --git a/test/test_data_id.c b/test/test_data_id.c
@@ -0,0 +1,63 @@
+
+#include "resource.h"
+#include "data_id.h"
+#include <stdio.h>
+
+struct test_struct {
+ struct {
+ char ca, cb;
+ int bleh;
+ } s;
+ float a;
+ float mat4[MAT4_ELEMS];
+ float b;
+};
+
+static void test_data_ids()
+{
+ printf("test_data_ids\n");
+ struct resource_manager r;
+ struct resource_id id;
+ struct test_struct *ts;
+ struct data_id a_id, b_id;
+ float a, b;
+ int ret;
+ // 2 item case
+ init_resource_manager(&r, sizeof(struct test_struct), 1, 2, "test_struct");
+ init_id(&id);
+
+ ts = new_resource(&r, &id);
+ assert(ts);
+
+ new_resource_data_id(&a_id, &r, id, DATA_ID_FLOAT, struct test_struct, a);
+ new_ptr_data_id(&b_id, &a, DATA_ID_FLOAT);
+
+ ts->a = 1337.0;
+ ts->b = 123.0;
+
+ assert(get_data_id_float(&a_id, &a));
+
+ assert(a == 1337.0);
+ a = 123.0;
+
+ assert(get_data_id_float(&b_id, &b));
+ assert(b == 123.0);
+
+ destroy_resource(&r, &id);
+ ret = get_data_id_float(&a_id, &a);
+ assert(ret == 0);
+ assert(is_resource_destroyed(&r, &a_id.res_id.id));
+
+ b = 0.0;
+ assert(get_data_id_float(&b_id, &b));
+ assert(b == 123.0);
+
+ destroy_resource_manager(&r);
+}
+
+int main(int argc, char *argv[])
+{
+ test_data_ids();
+
+ return 0;
+}
diff --git a/tools/compile-model.c b/tools/compile-model.c
@@ -60,7 +60,7 @@ int main(int argc, char *argv[])
int ok = parse_ply_with_mkgeom(filename, &mdl_geom);
assert(ok);
- save_mdl(outfile, &mdl_geom);
+ save_mdl(outfile, &model, &mdl_geom);
return 0;
}