render: render a single section as an example

This commit is contained in:
Lephenixnoir 2022-08-20 16:31:49 +02:00
parent e69c51268a
commit 96da3421d7
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 185 additions and 51 deletions

View File

@ -13,7 +13,8 @@ set(SOURCES
src/generator/gen1.cpp
src/generator/gen2.cpp
src/generator/gen3.cpp
src/level.cpp)
src/level.cpp
src/render.cpp)
set(ASSETS)
fxconv_declare_assets(${ASSETS} WITH_METADATA)

View File

@ -1,69 +1,67 @@
#include "level.h"
#include "generator.h"
#include <gint/keyboard.h>
#include <gint/display.h>
int main(void)
{
level_t level = level_create(1);
while (1) {
level_update(&level);
//TODO: display
dclear(C_WHITE);
level_display(&level);
dupdate();
clearevents();
if(keydown(KEY_EXIT) || keydown(KEY_MENU)) break;
if(keydown(KEY_EXE)) {
level_advance(&level);
}
if (keydown(KEY_F1)) level = level_create(1);
if (keydown(KEY_F2)) level = level_create(2);
if (keydown(KEY_F3)) level = level_create(3);
}
return 0;
}
#if 0
#include "render.h"
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/timer.h>
#include <azur/gint/render.h>
#include <gint/drivers/r61524.h>
#include <math.h>
#include <fxlibc/printf.h>
int main(void)
{
__printf_enable_fp();
prof_init();
azrp_config_scale(1);
azrp_shader_clear_configure();
/* azrp_shader_image_rgb16_configure();
azrp_shader_image_p8_configure();
azrp_shader_image_p4_configure(); */
// azrp_shader_image_rgb16_configure();
// azrp_shader_image_p8_configure();
// azrp_shader_image_p4_configure();
azrp_shader_triangle_configure();
int volatile need_frame = 1;
level_t level = level_create(1);
/* int volatile need_frame = 1;
int timer = timer_configure(TIMER_ANY, 33000, GINT_CALL_SET(&need_frame));
timer_start(timer);
float t = 0.0; */
float t = 0.0;
bool game_run = true;
while(game_run) {
/* float dt = 1.0 / 30;
t += dt; */
while(1) {
float dt = 1.0 / 30;
t += dt;
int y1 = (int)(90 * sin(t + 0.05)) + 100;
int y2 = (int)(90 * sin(t + 1.05)) + 100;
int y3 = (int)(90 * sin(t + 2.05)) + 100;
level_update(&level);
// TODO: display
azrp_perf_clear();
azrp_clear(C_WHITE);
azrp_triangle(10, y1, 128, y2, 380, y3, C_RED);
// dclear(C_WHITE);
struct camera camera;
camera.pos = vec3(0, RENDER_CAMERA_DEPTH, 0);
vec2 screen_size(DWIDTH, DHEIGHT);
for(int i = 0; i < PLATFORM_COUNT; i++) {
int gray = i * 31 / PLATFORM_COUNT;
int color = C_RGB(gray, gray, gray);
struct prect p = render_platform_position(i, num(3.0));
camera_project_prect(&camera, &p, screen_size);
render_triangle(&p.nl, &p.fr, &p.fl, color);
render_triangle(&p.fr, &p.nl, &p.nr, color);
/* dprint(4, i*14+4, C_BLACK,
"%d (%d): nl=%d/%d nr=%d/%d z=%d|%d",
i, gray,
(int)p.nl.x, (int)p.nl.y,
(int)p.nr.x, (int)p.nr.y,
(int)p.nl.z, (int)p.fl.z);
extern float get_near_plane(void);
dprint(4, 180, C_BLACK, "FOV=%g", get_near_plane()); */
}
azrp_update();
// dupdate();
drect(0, DHEIGHT-20, DWIDTH-1, DHEIGHT-1, C_WHITE);
dprint(1, 210, C_BLACK, "cmdgen:%03dus sort:%03dus render:%4d+%4dus",
@ -73,13 +71,26 @@ int main(void)
prof_time(azrp_perf_r61524));
r61524_display(gint_vram, DHEIGHT-20, 20, R61524_DMA_WAIT);
//---
// level_display(&level);
clearevents();
if(keydown(KEY_EXIT) || keydown(KEY_MENU)) break;
key_event_t ev;
while((ev = pollevent()).type != KEYEV_NONE) {
if(ev.type == KEYEV_UP)
continue;
if(ev.key == KEY_EXIT || ev.key == KEY_MENU)
game_run = false;
if(ev.key == KEY_EXE)
level_advance(&level);
if(ev.key == KEY_F1)
level = level_create(1);
if(ev.key == KEY_F2)
level = level_create(2);
if(ev.key == KEY_F3)
level = level_create(3);
}
}
timer_stop(timer);
return 1;
// timer_stop(timer);
return 0;
}
#endif

86
src/render.cpp Normal file
View File

@ -0,0 +1,86 @@
#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);
}

36
src/render.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef __RENDERH__
# define __RENDERH__
#include <num/num.h>
#include <num/vec.h>
using namespace libnum;
/* Vertical FOV, in degrees */
#define RENDER_FOV 120.0
/* Radius of the level cylinder, in world units */
#define RENDER_RADIUS num(4.0)
/* Camera depth in the level cylinder, in world units */
#define RENDER_CAMERA_DEPTH (RENDER_RADIUS / 2)
/* Section lengths, in world units */
#define RENDER_SECTION_LENGTH num(4.0)
struct prect {
vec3 nl, nr; /* Near left and near right points */
vec3 fl, fr; /* Far left and far right points */
};
struct prect render_platform_position(int platform_id, num z);
/* We assume the camera is looking towards (0,0,z) */
struct camera {
vec3 pos;
};
vec3 camera_project(struct camera *camera, vec3 u, vec2 screen_size);
void camera_project_prect(struct camera *camera, struct prect *p,
vec2 screen_size);
void render_triangle(vec3 *p1, vec3 *p2, vec3 *p3, int color);
#endif /* __RENDERH__ */