diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 168 |
1 files changed, 135 insertions, 33 deletions
@@ -5,6 +5,36 @@ static const float PLAYER_HEIGHT = 1.5f; static GLProgram *program_unlit, *program_main; +static Model model_rod; +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 +} 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; static void APIENTRY gl_message_callback(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char *message, const void *userParam) { @@ -15,14 +45,70 @@ 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; } - vec3 player_pos = {0}; // position of player's feet - float player_yaw = 0; - float player_pitch = 0; + 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"); @@ -48,14 +134,11 @@ int main(int argc, char **argv) { gl_vao_add_data3f(&ground_vao, ground_vbo, "v_pos", UnlitVertex, pos); } - Model model_rod; model_load(&model_rod, program_main, "assets/rod.obj"); window_set_relative_mouse(1); - bool wireframe = false; - - //gl.Enable(GL_MULTISAMPLE); + player->place_dist = 3; while (1) { SDL_Event event = {0}; @@ -69,17 +152,31 @@ int main(int argc, char **argv) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_z: - wireframe = !wireframe; + 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: { float dx = (float)event.motion.xrel; float dy = (float)event.motion.yrel; const float rot_speed = 0.001f; - player_yaw -= dx * rot_speed; - player_pitch -= dy * rot_speed; - player_yaw = fmodf(player_yaw, 2 * PI); - player_pitch = clamp(player_pitch, -PI * 0.5f, PI * 0.5f); + player->yaw -= dx * rot_speed; + player->pitch -= dy * rot_speed; + 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; } } @@ -90,43 +187,48 @@ int main(int argc, char **argv) { if (dx || dz) { const float player_speed = 3; vec3 dp = scale3(normalize3(Vec3((float)dx, 0, (float)dz)), player_speed * dt); - mat3 yaw = mat3_yaw(player_yaw); + mat3 yaw = mat3_yaw(player->yaw); dp = transform3(&yaw, dp); - player_pos = add3(player_pos, dp); + player->pos = add3(player->pos, dp); } } - gl.PolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL); - if (!wireframe) { + gl.PolygonMode(GL_FRONT_AND_BACK, g_wireframe ? GL_LINE : GL_FILL); + if (!g_wireframe) { gl.Enable(GL_DEPTH_TEST); gl.Enable(GL_CULL_FACE); } - mat4 camera; { - vec3 p = player_pos; + vec3 p = player->pos; p.y += PLAYER_HEIGHT; - camera = mat4_camera(p, player_yaw, player_pitch, degree2rad(45), 0.1f, 50); + g_camera = mat4_camera(p, player->yaw, player->pitch, degree2rad(45), 0.1f, 50); } gl_program_use(program_unlit); - gl_uniformM4(program_unlit, "u_transform", &camera); + gl_uniformM4(program_unlit, "u_transform", &g_camera); - gl_uniform4f(program_unlit, "u_color", Vec4(.5f,.5f,.5f,1)); gl_vao_render(ground_vao, &ground_ibo); + gl_uniform4f(program_unlit, "u_color", Vec4(.5f,.5f,.5f,1)); - gl_program_use(program_main); - gl_uniformM4(program_main, "u_transform", &camera); - gl_uniform1i(program_main, "u_lighting_enabled", !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)); - gl_uniform3f(program_main, "u_color", Vec3(.2f,.2f,.2f)); - gl_uniform3f(program_main, "u_scale", Vec3(.2f,.2f,.2f)); - gl_uniform3f(program_main, "u_offset", Vec3(0,0.5f,0)); - model_render(&model_rod); +// 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); + } + } quit: |