diff options
author | pommicket <pommicket@gmail.com> | 2021-09-29 11:38:37 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2021-09-29 11:38:37 -0400 |
commit | 0b9cd314267fb3f654959ed4a33e604b4bfb4fa3 (patch) | |
tree | 0edf99621c19870f5ee5e9275116fc52efb4b1a9 | |
parent | 685bc525dec7b5582aee24ca97f6e2d49a25807a (diff) |
new idea: function sandbox
-rw-r--r-- | grainf.glsl (renamed from unlitf.glsl) | 0 | ||||
-rw-r--r-- | grainv.glsl | 9 | ||||
-rw-r--r-- | main.c | 206 | ||||
-rw-r--r-- | mainf.glsl | 22 | ||||
-rw-r--r-- | mainv.glsl | 29 | ||||
-rw-r--r-- | unlitv.glsl | 6 | ||||
-rw-r--r-- | vlib.h | 32 |
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); +} @@ -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); -} @@ -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 { |