summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-09-26 18:04:23 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2021-09-26 18:04:23 -0400
commit685bc525dec7b5582aee24ca97f6e2d49a25807a (patch)
tree696f0d15d914e9d817a8905d55487e904e984367
parent4502fee2542cf3a2523d6bb615faa5009cfd00aa (diff)
placing objects
-rw-r--r--main.c168
-rw-r--r--mainf.glsl4
-rw-r--r--mainv.glsl19
-rw-r--r--vlib.h3
4 files changed, 158 insertions, 36 deletions
diff --git a/main.c b/main.c
index 285bcfe..16bd8a2 100644
--- a/main.c
+++ b/main.c
@@ -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:
diff --git a/mainf.glsl b/mainf.glsl
index 46ebdcb..7910ab3 100644
--- a/mainf.glsl
+++ b/mainf.glsl
@@ -1,4 +1,4 @@
-uniform vec3 u_color;
+uniform vec4 u_color;
uniform vec3 u_directional_light1; // (direction to light)
uniform vec3 u_directional_light1_color;
uniform vec3 u_directional_light2;
@@ -18,5 +18,5 @@ void main() {
} else {
L = vec3(1.0, 1.0, 1.0);
}
- gl_FragColor = vec4(L * u_color, 1.0);
+ gl_FragColor = vec4(L * u_color.xyz, u_color.w);
}
diff --git a/mainv.glsl b/mainv.glsl
index d78f63d..b26ee6f 100644
--- a/mainv.glsl
+++ b/mainv.glsl
@@ -3,10 +3,27 @@ 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() {
- gl_Position = u_transform * vec4(v_pos * u_scale + u_offset, 1.0);
+ 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/vlib.h b/vlib.h
index 7750a71..55c9d06 100644
--- a/vlib.h
+++ b/vlib.h
@@ -12788,6 +12788,9 @@ typedef struct {
V_DECL bool model_load(Model *model, GLProgram *program, const char *filename) {
char *dot = strchr(filename, '.');
+
+ memset(model, 0, sizeof *model);
+
if (dot) {
FILE *fp = fopen(filename, "r");
if (fp) {