BosonX/src/render.cpp

87 lines
2.1 KiB
C++
Raw Normal View History

#define __BSD_VISIBLE 1
#include "level.h"
#include "render.h"
#include <math.h>
#include <azur/gint/render.h>
/* Angle span for a platform in the level cylinder */
static float get_alpha(void)
{
return 2 * 3.14159 / PLATFORM_COUNT;
}
/* Get enlargement factor from FOV */
float get_near_plane(void)
{
float fov_radians = RENDER_FOV * 3.14159 / 180;
return 2 * atanf(1 / fov_radians);
}
vec3 vec_rotate_around_z(vec3 v, float angle)
{
float sin_f, cos_f;
sincosf(angle, &sin_f, &cos_f);
num s=sin_f, c=cos_f;
vec3 u;
u.x = c * v.x - s * v.y;
u.y = c * v.y + s * v.x;
u.z = v.z;
return u;
}
struct prect render_platform_position(int platform_id, num z)
{
struct prect r;
float alpha = get_alpha();
vec3 radius(0, RENDER_RADIUS, 0);
/* +/- rather than -/+ because right-handed system */
float angle_l = alpha * platform_id + (alpha / 2);
float angle_r = alpha * platform_id - (alpha / 2);
r.nl = r.fl = vec_rotate_around_z(radius, angle_l);
r.nr = r.fr = vec_rotate_around_z(radius, angle_r);
r.nl.z += z;
r.nr.z += z;
r.fl.z += z + RENDER_SECTION_LENGTH;
r.fr.z += z + RENDER_SECTION_LENGTH;
return r;
}
vec3 camera_project(struct camera *camera, vec3 u, vec2 screen_size)
{
u -= camera->pos;
if(u.z <= 0)
return u;
static float near_plane = get_near_plane();
int screen = screen_size.x < screen_size.y
? (int)screen_size.x / 2
: (int)screen_size.y / 2;
u.x = u.x * num(near_plane) * screen / u.z + screen_size.x / 2;
u.y = u.y * num(near_plane) * screen / u.z + screen_size.y / 2;
return u;
}
void camera_project_prect(struct camera *camera, struct prect *p,
vec2 screen_size)
{
p->nl = camera_project(camera, p->nl, screen_size);
p->nr = camera_project(camera, p->nr, screen_size);
p->fl = camera_project(camera, p->fl, screen_size);
p->fr = camera_project(camera, p->fr, screen_size);
}
void render_triangle(vec3 *p1, vec3 *p2, vec3 *p3, int color)
{
azrp_triangle(
(int)p1->x, (int)p1->y,
(int)p2->x, (int)p2->y,
(int)p3->x, (int)p3->y,
color);
}