void device_frustum(device_t device, float left, float right, float top, float bottom, float near, float far) { struct matrix4 *dst = &device->cur_proj; float rml = right-left; float tmb = top-bottom; float nmf = near-far; float nearx2 = 2.0f*near; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); dst->x.x = nearx2 / rml; dst->z.x = (left+right) / rml; dst->y.y = nearx2 / tmb; dst->z.y = (bottom+top) / tmb; dst->z.z = (far+near) / nmf; dst->t.z = 2.0f * (near*far) / nmf; dst->z.w = -1.0f; }
void device_frustum(gs_device_t device, float left, float right, float top, float bottom, float zNear, float zFar) { matrix4 *dst = &device->curProjMatrix; float rml = right-left; float bmt = bottom-top; float fmn = zFar-zNear; float nearx2 = 2.0f*zNear; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); dst->x.x = nearx2 / rml; dst->z.x = (left+right) / -rml; dst->y.y = nearx2 / -bmt; dst->z.y = (bottom+top) / bmt; dst->z.z = zFar / fmn; dst->t.z = (zNear*zFar) / -fmn; dst->z.w = 1.0f; }
void device_ortho(device_t device, float left, float right, float top, float bottom, float near, float far) { struct matrix4 *dst = &device->cur_proj; float rml = right-left; float bmt = bottom-top; float fmn = far-near; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); dst->x.x = 2.0f / rml; dst->t.x = (left+right) / -rml; dst->y.y = 2.0f / -bmt; dst->t.y = (bottom+top) / bmt; dst->z.z = -2.0f / fmn; dst->t.z = (far+near) / -fmn; dst->t.w = 1.0f; }
void device_ortho(gs_device_t device, float left, float right, float top, float bottom, float zNear, float zFar) { matrix4 *dst = &device->curProjMatrix; float rml = right-left; float bmt = bottom-top; float fmn = zFar-zNear; vec4_zero(&dst->x); vec4_zero(&dst->y); vec4_zero(&dst->z); vec4_zero(&dst->t); dst->x.x = 2.0f / rml; dst->t.x = (left+right) / -rml; dst->y.y = 2.0f / -bmt; dst->t.y = (bottom+top) / bmt; dst->z.z = 1.0f / fmn; dst->t.z = zNear / -fmn; dst->t.w = 1.0f; }
vec4 image_get(image* i, int u, int v) { u = image_wrap(u, i->width, i->repeat_type); v = image_wrap(v, i->height, i->repeat_type); if (u == -1) { return vec4_zero(); } if (v == -1) { return vec4_zero(); } float r = (float)i->data[u * 4 + v * i->width * 4 + 0] / 255; float g = (float)i->data[u * 4 + v * i->width * 4 + 1] / 255; float b = (float)i->data[u * 4 + v * i->width * 4 + 2] / 255; float a = (float)i->data[u * 4 + v * i->width * 4 + 3] / 255; return vec4_new(r, g, b, a); }
static void destiny_detail_render(void *data, gs_effect_t *effect) { gs_reset_blend_state(); vec4 clear_color; vec4_zero(&clear_color); clear_color.w = 1.0; clear_color.y = 255; // This clears the entire view gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0); }
static inline void render_child(obs_source_t *transition, obs_source_t *child, size_t idx) { uint32_t cx = transition->transition_actual_cx; uint32_t cy = transition->transition_actual_cy; struct vec4 blank; if (!child) return; if (gs_texrender_begin(transition->transition_texrender[idx], cx, cy)) { vec4_zero(&blank); gs_clear(GS_CLEAR_COLOR, &blank, 0.0f, 0); gs_matrix_push(); gs_matrix_mul(&transition->transition_matrices[idx]); obs_source_video_render(child); gs_matrix_pop(); gs_texrender_end(transition->transition_texrender[idx]); } }
static inline void render_item(struct obs_scene_item *item) { if (item->item_render) { uint32_t width = obs_source_get_width(item->source); uint32_t height = obs_source_get_height(item->source); uint32_t cx = calc_cx(item, width); uint32_t cy = calc_cy(item, height); if (cx && cy && gs_texrender_begin(item->item_render, cx, cy)) { float cx_scale = (float)width / (float)cx; float cy_scale = (float)height / (float)cy; struct vec4 clear_color; vec4_zero(&clear_color); gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0); gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f); gs_matrix_scale3f(cx_scale, cy_scale, 1.0f); gs_matrix_translate3f( -(float)item->crop.left, -(float)item->crop.top, 0.0f); obs_source_video_render(item->source); gs_texrender_end(item->item_render); } } gs_matrix_push(); gs_matrix_mul(&item->draw_transform); if (item->item_render) { render_item_texture(item); } else { obs_source_video_render(item->source); } gs_matrix_pop(); }
int main(int argc, char **argv) { SDL_Surface *screen; SDL_Event event; struct vec4 cubeCenter, cube[8]; scalar rota; struct mat4 rot; int i; SDL_Init( SDL_INIT_EVERYTHING ); screen = SDL_SetVideoMode(width, height, 32, 0); proj = proj_perspective(45, (scalar) width / (scalar) height, 1, 10); cubeCenter = vec4_zero(); while(1) { rota = (scalar) SDL_GetTicks() / 1000.0; cubeCenter.z = 5 + sin(rota); rot = mat4_aangle(_vec4(0, 1, 0, 1), rota); cube[0] = vec4_add(mat4_mulv(rot, _vec4( 1, -1, 1, 0)), cubeCenter); cube[1] = vec4_add(mat4_mulv(rot, _vec4(-1, -1, 1, 0)), cubeCenter); cube[2] = vec4_add(mat4_mulv(rot, _vec4(-1, 1, 1, 0)), cubeCenter); cube[3] = vec4_add(mat4_mulv(rot, _vec4( 1, 1, 1, 0)), cubeCenter); cube[4] = vec4_add(mat4_mulv(rot, _vec4( 1, -1, -1, 0)), cubeCenter); cube[5] = vec4_add(mat4_mulv(rot, _vec4(-1, -1, -1, 0)), cubeCenter); cube[6] = vec4_add(mat4_mulv(rot, _vec4(-1, 1, -1, 0)), cubeCenter); cube[7] = vec4_add(mat4_mulv(rot, _vec4( 1, 1, -1, 0)), cubeCenter); SDL_FillRect(screen, 0, 0); drawLine3d(screen, cube[0], cube[1]); drawLine3d(screen, cube[0], cube[3]); drawLine3d(screen, cube[1], cube[2]); drawLine3d(screen, cube[2], cube[3]); drawLine3d(screen, cube[4], cube[5]); drawLine3d(screen, cube[4], cube[7]); drawLine3d(screen, cube[5], cube[6]); drawLine3d(screen, cube[6], cube[7]); drawLine3d(screen, cube[0], cube[4]); drawLine3d(screen, cube[1], cube[5]); drawLine3d(screen, cube[2], cube[6]); drawLine3d(screen, cube[3], cube[7]); SDL_Flip(screen); while(SDL_PollEvent(&event) != 0) { switch(event.type) { case (SDL_QUIT): SDL_Quit(); return 0; default: break; } } } SDL_Quit(); return 0; }
void tick_game(struct GameMemory *memory, struct Input *input, uint32 screen_width, uint32 screen_height, float dt) { struct GameState *game_state = (struct GameState *)memory->game_memory; struct RenderBuffer *render_buffer = (struct RenderBuffer *)memory->render_memory; clear_render_buffer(render_buffer); for (uint32 i = 0; i < game_state->visibility_graph.vertex_count; ++i) { vec2 vertex = game_state->visibility_graph.vertices[i]; draw_world_quad_buffered(render_buffer, vertex, vec2_scalar(0.1f), vec4_zero(), vec3_new(0, 1, 1)); } for (uint32 i = 0; i < game_state->visibility_graph.edge_count; ++i) { uint32 *edge = &game_state->visibility_graph.edges[i][0]; vec2 p0 = game_state->visibility_graph.vertices[edge[0]]; vec2 p1 = game_state->visibility_graph.vertices[edge[1]]; draw_world_line_buffered(render_buffer, p0, p1, vec3_new(1, 1, 0)); } if (mouse_down(MOUSE_LEFT, input)) { struct AABB box = calc_mouse_selection_box(input, MOUSE_LEFT); vec2 size = vec2_sub(box.max, box.min); vec2 bottom_left = vec2_new(box.min.x, box.max.y); vec2 bottom_right = vec2_new(box.max.x, box.max.y); vec2 top_left = vec2_new(box.min.x, box.min.y); vec2 top_right = vec2_new(box.max.x, box.min.y); const uint32 outline_thickness = 1; draw_screen_quad_buffered(render_buffer, top_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0)); draw_screen_quad_buffered(render_buffer, bottom_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0)); draw_screen_quad_buffered(render_buffer, top_left, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0)); draw_screen_quad_buffered(render_buffer, top_right, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0)); } if (mouse_released(MOUSE_LEFT, input)) { // Clear previous selection. game_state->selected_ship_count = 0; struct AABB screen_selection_box = calc_mouse_selection_box(input, MOUSE_LEFT); // Because screen space y-values are inverted, these two results have conflicting // y-values, i.e. screen_to_world_min.y is actually the maximum y. These values // are then properly min/maxed and stored correctly in world_selection_box. vec2 screen_to_world_min = screen_to_world_coords(screen_selection_box.min, &game_state->camera, screen_width, screen_height); vec2 screen_to_world_max = screen_to_world_coords(screen_selection_box.max, &game_state->camera, screen_width, screen_height); struct AABB world_selection_box; world_selection_box.min = min_vec2(screen_to_world_min, screen_to_world_max); world_selection_box.max = max_vec2(screen_to_world_min, screen_to_world_max); // Add colliding ships to the selection list. // TODO: optimize, spatial grid hash? for (uint32 i = 0; i < game_state->ship_count; ++i) { struct Ship *ship = &game_state->ships[i]; struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size); vec2 center = vec2_div(vec2_add(ship_aabb.min, ship_aabb.max), 2.0f); if (aabb_aabb_intersection(world_selection_box, ship_aabb)) game_state->selected_ships[game_state->selected_ship_count++] = ship->id; } if (game_state->selected_ship_count > 0) fprintf(stderr, "selected %u ships\n", game_state->selected_ship_count); } if (mouse_down(MOUSE_RIGHT, input)) { vec2 target_position = screen_to_world_coords(input->mouse_position, &game_state->camera, screen_width, screen_height); for (uint32 i = 0; i < game_state->selected_ship_count; ++i) { uint32 id = game_state->selected_ships[i]; struct Ship *ship = get_ship_by_id(game_state, id); ship->target_position = target_position; ship->move_order = true; } } // Outline selected ships. for (uint32 i = 0; i < game_state->selected_ship_count; ++i) { uint32 id = game_state->selected_ships[i]; struct Ship *ship = get_ship_by_id(game_state, id); draw_world_quad_buffered(render_buffer, ship->position, vec2_mul(ship->size, 1.1f), vec4_zero(), vec3_new(0, 1, 0)); if (ship->move_order) draw_world_quad_buffered(render_buffer, ship->target_position, vec2_new(0.5f, 0.5f), vec4_zero(), vec3_new(0, 1, 0)); } // Handle move orders. for (uint32 i = 0; i < game_state->ship_count; ++i) { struct Ship *ship = &game_state->ships[i]; if (ship->move_order) { vec2 direction = vec2_zero(); /* if (vec2_length2(direction) < FLOAT_EPSILON) direction = vec2_normalize(vec2_sub(ship->target_position, ship->position)); */ ship->move_velocity = vec2_mul(direction, 2.0f); /* vec2 direction = vec2_normalize(vec2_sub(ship->target_position, ship->position)); ship->move_velocity = vec2_mul(direction, 2.0f); */ if (vec2_distance2(ship->position, ship->target_position) < 0.1f) { ship->move_velocity = vec2_zero(); ship->move_order = false; } } } tick_camera(input, &game_state->camera, dt); tick_combat(game_state, dt); tick_physics(game_state, dt); }