summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2021-09-29 11:38:37 -0400
committerpommicket <pommicket@gmail.com>2021-09-29 11:38:37 -0400
commit0b9cd314267fb3f654959ed4a33e604b4bfb4fa3 (patch)
tree0edf99621c19870f5ee5e9275116fc52efb4b1a9
parent685bc525dec7b5582aee24ca97f6e2d49a25807a (diff)
new idea: function sandbox
-rw-r--r--grainf.glsl (renamed from unlitf.glsl)0
-rw-r--r--grainv.glsl9
-rw-r--r--main.c206
-rw-r--r--mainf.glsl22
-rw-r--r--mainv.glsl29
-rw-r--r--unlitv.glsl6
-rw-r--r--vlib.h32
7 files changed, 93 insertions, 211 deletions
diff --git a/unlitf.glsl b/grainf.glsl
index 93b04d8..93b04d8 100644
--- a/unlitf.glsl
+++ b/grainf.glsl
diff --git a/grainv.glsl b/grainv.glsl
new file mode 100644
index 0000000..2584fd3
--- /dev/null
+++ b/grainv.glsl
@@ -0,0 +1,9 @@
+attribute vec3 v_pos;
+uniform mat4 u_transform;
+uniform sampler2D u_offset_tex;
+
+void main() {
+ ivec2 texel_pos = ivec2(gl_InstanceID & 1023, gl_InstanceID >> 10);
+ vec3 offset = texelFetch(u_offset_tex, texel_pos, 0).xyz;
+ gl_Position = u_transform * vec4(v_pos + offset, 1.0);
+}
diff --git a/main.c b/main.c
index 16bd8a2..6338951 100644
--- a/main.c
+++ b/main.c
@@ -4,35 +4,16 @@
static const float PLAYER_HEIGHT = 1.5f;
-static GLProgram *program_unlit, *program_main;
-static Model model_rod;
+static GLProgram *program_unlit, *program_main, *program_grain;
static mat4 g_camera;
static bool g_wireframe;
-typedef enum {
- OBJ_NONE,
- OBJ_METAL_ROD
-} ObjectType;
-
-typedef struct {
- ObjectType type;
- vec3 pos;
- float yaw, pitch;
-} ObjectAny;
-
-typedef union {
- ObjectType type;
- ObjectAny any;
-} Object;
-
typedef struct {
- Object *objects; // dynamic array
+ vec3 *grains; // dynamic array in order of creation
} World;
typedef struct {
vec3 pos; // position of player's feet
- ObjectType placing; // which object player is placing / OBJ_NONE if the player isn't placing anything
- float place_dist; // distance from player to place object (in the direction of player's vision)
float yaw, pitch;
} Player;
@@ -45,105 +26,64 @@ static void APIENTRY gl_message_callback(GLenum source, GLenum type, unsigned in
debug_print("Message from OpenGL: %s.\n", message);
}
-static void object_render_sequence_begin(void) {
- gl_program_use(program_main);
- gl_uniformM4(program_main, "u_transform", &g_camera);
- gl_uniform1i(program_main, "u_lighting_enabled", !g_wireframe);
- gl_uniform3f(program_main, "u_directional_light1", normalize3(Vec3(1, 1, 1)));
- gl_uniform3f(program_main, "u_directional_light2", normalize3(Vec3(-1, 0.2f, -0.5f)));
- gl_uniform3f(program_main, "u_directional_light1_color", Vec3(1,1,.9f));
- gl_uniform3f(program_main, "u_directional_light2_color", Vec3(.9f,.9f,.8f));
- gl_uniform3f(program_main, "u_ambient_light", Vec3(.3f,.3f,.3f));
-}
-
-// returns true if player is placing an object, and fills out *obj with the details
-static bool player_object_placing(const Player *player, Object *obj) {
- if (player->placing) {
- vec3 view = {0, 0, -1};
- mat3 yaw = mat3_yaw(player->yaw);
- mat3 pitch = mat3_pitch(player->pitch);
- mat3 rot = mat3_mul(&yaw, &pitch);
- view = transform3(&rot, view);
-
- vec3 player_hand_pos = player->pos;
- player_hand_pos.y += 0.6f * PLAYER_HEIGHT;
-
-
- obj->type = player->placing;
- obj->any.pos = add3(player_hand_pos, scale3(view, player->place_dist));
- obj->any.yaw = player->yaw;
- obj->any.pitch = player->pitch;
- return true;
- } else {
- return false;
- }
-}
-
-// call object_render_sequence_begin before this
-enum {
- OBJ_RENDER_GHOST = 0x01
-};
-static void object_render(const Object *obj, uint flags) {
- vec3 pos = obj->any.pos;
- float alpha = (flags & OBJ_RENDER_GHOST) ? 0.5f : 1;
-
- gl_uniform3f(program_main, "u_offset", pos);
- gl_uniform1f(program_main, "u_yaw", obj->any.yaw);
- gl_uniform1f(program_main, "u_pitch", obj->any.pitch);
-
- switch (obj->type) {
- case OBJ_NONE:
- break;
- case OBJ_METAL_ROD:
- gl_uniform4f(program_main, "u_color", Vec4(.2f, .2f, .2f, alpha));
- gl_uniform3f(program_main, "u_scale", Vec3(.2f, .2f, .2f));
- model_render(&model_rod);
- break;
- }
-}
-
int main(int argc, char **argv) {
if (!window_create("sandbox", 1280, 720, 0)) {
return -1;
}
+ if (gl_version_major * 100 + gl_version_minor < 310) {
+ window_message_box_error("Error", "Couldn't get OpenGL 3.1 context (your graphics drivers are too old).");
+ return -1;
+ }
Player player_data = {0}, *player = &player_data;
World world_data = {0}, *world = &world_data;
program_unlit = gl_program_new("unlitv.glsl", "unlitf.glsl");
program_main = gl_program_new("mainv.glsl", "mainf.glsl");
+ program_grain = gl_program_new("grainv.glsl", "grainf.glsl");
typedef struct {
vec3 pos;
} UnlitVertex;
- GLVBO ground_vbo = gl_vbo_new(UnlitVertex, "ground");
- GLVAO ground_vao = gl_vao_new(program_unlit, "ground");
- GLIBO ground_ibo = gl_ibo_new("ground");
+ GLVBO grain_vbo = gl_vbo_new(UnlitVertex, "grain");
+ GLVAO grain_vao = gl_vao_new(program_grain, "grain");
{
+ float h = 0.005f;
+ float HS3 = 0.866025403784f; // sqrt(3)/2
UnlitVertex vertices[] = {
- {-100, 0, -100},
- {-100, 0, +100},
- {+100, 0, +100},
- {+100, 0, -100},
+ {0,h*.5f,0},
+ {-h*HS3,-h*.5f,0},
+ {+h*HS3,-h*.5f,0},
+ {0,h*.5f,0},
+ {0,-h*.5f,-h*HS3},
+ {0,-h*.5f,+h*HS3},
};
- GLuint indices[] = {
- 0, 1, 2, 0, 2, 3
- };
- gl_vbo_set_static_data(&ground_vbo, vertices, static_arr_len(vertices));
- gl_ibo_set_static_data(&ground_ibo, indices, static_arr_len(indices));
- gl_vao_add_data3f(&ground_vao, ground_vbo, "v_pos", UnlitVertex, pos);
+ gl_vbo_set_static_data(&grain_vbo, vertices, static_arr_len(vertices));
+ gl_vao_add_data3f(&grain_vao, grain_vbo, "v_pos", UnlitVertex, pos);
}
-
- model_load(&model_rod, program_main, "assets/rod.obj");
+ GLuint grains_texture = 0;
+ gl.GenTextures(1, &grains_texture);
window_set_relative_mouse(1);
- player->place_dist = 3;
+ for (int i = 0; i < 100000; ++i) {
+ arr_add(world->grains, addc3(scale3(rand_vec3(), 4),-2));
+ }
+ const uint32_t tex_width = 1024;
+ uint32_t tex_chunk_size = tex_width * 4; // height must be a multiple of 4
+ uint32_t tex_area = ((arr_len(world->grains) + tex_chunk_size-1) / tex_chunk_size) * tex_chunk_size; // width * height of grain pos texture
+ if (tex_area < tex_chunk_size) tex_area = tex_chunk_size;
+ uint32_t tex_height = tex_area / tex_width;
+
+ arr_reserve(world->grains, tex_area);
+
+ float leftover_time = 0;
while (1) {
SDL_Event event = {0};
float dt = window_frame();
+ float timestep = 0.01f;
while (SDL_PollEvent(&event)) {
switch (event.type) {
@@ -154,13 +94,6 @@ int main(int argc, char **argv) {
case SDLK_z:
g_wireframe = !g_wireframe;
break;
- case SDLK_r:
- player->placing = OBJ_METAL_ROD;
- break;
- case SDLK_ESCAPE:
- if (player->placing)
- player->placing = OBJ_NONE;
- break;
}
break;
case SDL_MOUSEMOTION: {
@@ -172,21 +105,16 @@ int main(int argc, char **argv) {
player->yaw = fmodf(player->yaw, 2 * PI);
player->pitch = clamp(player->pitch, -PI * 0.5f, PI * 0.5f);
} break;
- case SDL_MOUSEBUTTONDOWN: {
- Object obj = {0};
- if (player_object_placing(player, &obj)) {
- arr_add(world->objects, obj);
- }
- } break;
}
}
{
- int dx = window_is_key_down(KEY_D) - window_is_key_down(KEY_A);
- int dz = window_is_key_down(KEY_S) - window_is_key_down(KEY_W);
- if (dx || dz) {
+ int dx = (window_is_key_down(KEY_D) || window_is_key_down(KEY_RIGHT)) - (window_is_key_down(KEY_A) || window_is_key_down(KEY_LEFT));
+ int dy = window_is_key_down(KEY_PAGEUP) - window_is_key_down(KEY_PAGEDOWN);
+ int dz = (window_is_key_down(KEY_S) || window_is_key_down(KEY_DOWN)) - (window_is_key_down(KEY_W) || window_is_key_down(KEY_UP));
+ if (dx || dy || dz) {
const float player_speed = 3;
- vec3 dp = scale3(normalize3(Vec3((float)dx, 0, (float)dz)), player_speed * dt);
+ vec3 dp = scale3(normalize3(Vec3((float)dx, (float)dy, (float)dz)), player_speed * dt);
mat3 yaw = mat3_yaw(player->yaw);
dp = transform3(&yaw, dp);
player->pos = add3(player->pos, dp);
@@ -195,39 +123,45 @@ int main(int argc, char **argv) {
gl.PolygonMode(GL_FRONT_AND_BACK, g_wireframe ? GL_LINE : GL_FILL);
- if (!g_wireframe) {
+ if (!g_wireframe)
gl.Enable(GL_DEPTH_TEST);
- gl.Enable(GL_CULL_FACE);
- }
+ { // fixed time step (for consistency)
+ float t = dt + leftover_time;
+ while (t >= timestep) {
+ arr_foreachp(world->grains, vec3, g) {
+ float x = g->x, y = g->y, z = g->z;
+ (void)x; (void)y; (void)z;
+ vec3 wind = Vec3(-z, y, x);
+ *g = add3(*g, scale3(wind, timestep));
+ }
+ t -= timestep;
+ }
+ leftover_time = t;
+ }
+
{
vec3 p = player->pos;
p.y += PLAYER_HEIGHT;
- g_camera = mat4_camera(p, player->yaw, player->pitch, degree2rad(45), 0.1f, 50);
+ g_camera = mat4_camera(p, player->yaw, player->pitch, degree2rad(45), 1, 50);
}
- gl_program_use(program_unlit);
- gl_uniformM4(program_unlit, "u_transform", &g_camera);
-
- gl_vao_render(ground_vao, &ground_ibo);
- gl_uniform4f(program_unlit, "u_color", Vec4(.5f,.5f,.5f,1));
+ gl_program_use(program_grain);
+ gl_uniformM4(program_grain, "u_transform", &g_camera);
+ gl_uniform4f(program_grain, "u_color", Vec4(1,0,0,1));
+ gl.BindTexture(GL_TEXTURE_2D, grains_texture);
+ gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, (GLsizei)tex_width, (GLsizei)tex_height, 0, GL_RGB, GL_FLOAT, world->grains);
+ gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl.ActiveTexture(GL_TEXTURE0);
+ gl.BindTexture(GL_TEXTURE_2D, grains_texture);
+
+ gl_uniform1i(program_grain, "u_offset_tex", 0);
-// Object test_obj;
-// test_obj.type = OBJ_METAL_ROD;
-// test_obj.any.pos = Vec3(1,1,1);
- object_render_sequence_begin();
- arr_foreachp(world->objects, Object, obj) {
- object_render(obj, 0);
- }
-
-
- Object ghost = {0};
- if (player_object_placing(player, &ghost)) {
- gl.Enable(GL_BLEND);
- object_render_sequence_begin();
- object_render(&ghost, OBJ_RENDER_GHOST);
- gl.Disable(GL_BLEND);
- }
+ gl.BindVertexArray(grain_vao.id);
+ gl.DrawArraysInstanced(GL_TRIANGLES, 0, 6, (GLsizei)arr_len(world->grains));
}
diff --git a/mainf.glsl b/mainf.glsl
deleted file mode 100644
index 7910ab3..0000000
--- a/mainf.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-uniform vec4 u_color;
-uniform vec3 u_directional_light1; // (direction to light)
-uniform vec3 u_directional_light1_color;
-uniform vec3 u_directional_light2;
-uniform vec3 u_directional_light2_color;
-uniform vec3 u_ambient_light;
-uniform int u_lighting_enabled;
-
-varying vec3 normal;
-
-void main() {
- vec3 N = normalize(normal);
- vec3 L;
- if (u_lighting_enabled != 0) {
- L = max(0.0, dot(u_directional_light1, N)) * u_directional_light1_color
- + max(0.0, dot(u_directional_light2, N)) * u_directional_light2_color
- + u_ambient_light;
- } else {
- L = vec3(1.0, 1.0, 1.0);
- }
- gl_FragColor = vec4(L * u_color.xyz, u_color.w);
-}
diff --git a/mainv.glsl b/mainv.glsl
deleted file mode 100644
index b26ee6f..0000000
--- a/mainv.glsl
+++ /dev/null
@@ -1,29 +0,0 @@
-attribute vec3 v_pos;
-attribute vec3 v_normal;
-uniform mat4 u_transform;
-uniform vec3 u_offset;
-uniform vec3 u_scale;
-uniform float u_yaw, u_pitch;
-
-varying vec3 normal;
-
-void main() {
- float cy = cos(u_yaw), sy = sin(u_yaw);
- float cp = cos(u_pitch), sp = sin(u_pitch);
- float x = v_pos.x, y = v_pos.y, z = v_pos.z;
- vec3 pos;
- pos = vec3(
- x,
- cp * y - sp * z,
- sp * y + cp * z
- );
- x = pos.x; y = pos.y; z = pos.z;
- pos = vec3(
- +cy * x + sy * z,
- y,
- -sy * x + cy * z
- );
-
- gl_Position = u_transform * vec4(pos * u_scale + u_offset, 1.0);
- normal = v_normal;
-}
diff --git a/unlitv.glsl b/unlitv.glsl
deleted file mode 100644
index 2b427cd..0000000
--- a/unlitv.glsl
+++ /dev/null
@@ -1,6 +0,0 @@
-attribute vec3 v_pos;
-uniform mat4 u_transform;
-
-void main() {
- gl_Position = u_transform * vec4(v_pos, 1.0);
-}
diff --git a/vlib.h b/vlib.h
index 55c9d06..c05340a 100644
--- a/vlib.h
+++ b/vlib.h
@@ -2697,6 +2697,8 @@ typedef union {
f(DebugMessageCallback, DEBUGMESSAGECALLBACK) \
f(DebugMessageControl, DEBUGMESSAGECONTROL) \
f(DrawArrays, DRAWARRAYS) \
+ f(DrawArraysInstanced, DRAWARRAYSINSTANCED) \
+ f(DrawElementsInstanced, DRAWELEMENTSINSTANCED) \
f(EnableVertexAttribArray, ENABLEVERTEXATTRIBARRAY) \
f(PolygonMode, POLYGONMODE) \
f(Flush, FLUSH) \
@@ -4277,24 +4279,17 @@ static void arr_reserve_(void **arr, size_t member_size, size_t n) {
} else {
// increase capacity of array
ArrHeader *hdr = arr_hdr_(*arr);
- uint32_t curr_cap = hdr->cap;
- if (n > curr_cap) {
- ArrHeader *old_hdr = hdr;
- while (n > curr_cap) {
- if (curr_cap < UINT32_MAX/2)
- curr_cap *= 2;
- else
- curr_cap = UINT32_MAX;
- }
- hdr = (ArrHeader *)realloc(hdr, sizeof(ArrHeader) + curr_cap * member_size);
- if (hdr) {
- hdr->cap = curr_cap;
- } else {
- // growing failed
- free(old_hdr);
- *arr = NULL;
- return;
- }
+ ArrHeader *old_hdr = hdr;
+ if (old_hdr->len > n) old_hdr->len = (uint32_t)n;
+ hdr = (ArrHeader *)realloc(hdr, sizeof(ArrHeader) + n * member_size);
+ if (hdr) {
+ hdr->cap = (uint32_t)n;
+ memset((char *)hdr->data + member_size * hdr->len, 0, (hdr->cap - hdr->len) * member_size);
+ } else {
+ // growing failed
+ free(old_hdr);
+ *arr = NULL;
+ return;
}
*arr = hdr->data;
}
@@ -12778,6 +12773,7 @@ V_DECL float window_frame(void) {
V_last_frame = now;
V_vertex_count = 0;
+ dt = clamp(dt, 0.001f, 0.1f); // prevent really short/long frames
return dt;
}
typedef struct {