example/q3bsp: first person demo
This commit is contained in:
parent
0156721a6b
commit
3543f57c06
@ -133,6 +133,8 @@ struct position_normal {
|
||||
vec3 normal;
|
||||
};
|
||||
|
||||
static uint8_t face_cache[16384];
|
||||
|
||||
static position_normal vertex_cache[16384];
|
||||
|
||||
static inline vec3 normal_transform(const mat4x4& trans, vec3 normal)
|
||||
@ -253,7 +255,7 @@ void transform_vertices(uint8_t * buf, int length, const mat4x4& trans)
|
||||
|
||||
//printf("%f %f %f\n", v.x, v.y, v.z);
|
||||
|
||||
vertex_cache[i].position = screen_transform(trans * v);
|
||||
vertex_cache[i].position = trans * v;
|
||||
vertex_cache[i].normal = normal_transform(trans, n);
|
||||
}
|
||||
}
|
||||
@ -282,6 +284,10 @@ static inline void render_tri_type_2(ta_parameter_writer& writer,
|
||||
ci);
|
||||
}
|
||||
|
||||
static int type7_tri_count = 0;
|
||||
static int vis_tri_count = 0;
|
||||
static int total_tri_count = 0;
|
||||
|
||||
static inline void render_tri_type_7(ta_parameter_writer& writer,
|
||||
vec3 ap,
|
||||
vec3 bp,
|
||||
@ -293,6 +299,8 @@ static inline void render_tri_type_7(ta_parameter_writer& writer,
|
||||
float bi,
|
||||
float ci)
|
||||
{
|
||||
type7_tri_count += 1;
|
||||
|
||||
writer.append<ta_vertex_parameter::polygon_type_7>() =
|
||||
ta_vertex_parameter::polygon_type_7(polygon_vertex_parameter_control_word(false),
|
||||
ap.x, ap.y, ap.z,
|
||||
@ -315,6 +323,74 @@ static inline void render_tri_type_7(ta_parameter_writer& writer,
|
||||
0);
|
||||
}
|
||||
|
||||
static inline void render_clip_tri_type_7(ta_parameter_writer& writer,
|
||||
vec3 ap,
|
||||
vec3 bp,
|
||||
vec3 cp,
|
||||
vec2 at,
|
||||
vec2 bt,
|
||||
vec2 ct,
|
||||
float li)
|
||||
{
|
||||
//return;
|
||||
const vec3 plane_point = {0.f, 0.f, 1.f};
|
||||
const vec3 plane_normal = {0.f, 0.f, 1.f};
|
||||
|
||||
vec3 preclip_position[] = {ap, bp, cp};
|
||||
vec2 preclip_texture[] = {at, bt, ct};
|
||||
|
||||
vec3 clip_position[4];
|
||||
vec2 clip_texture[4];
|
||||
int output_length = geometry::clip_polygon_uv<3>(clip_position,
|
||||
clip_texture,
|
||||
plane_point,
|
||||
plane_normal,
|
||||
preclip_position,
|
||||
preclip_texture);
|
||||
|
||||
{
|
||||
vec3 ap;
|
||||
vec3 bp;
|
||||
vec3 cp;
|
||||
vec3 dp;
|
||||
|
||||
const vec2& at = clip_texture[0];
|
||||
const vec2& bt = clip_texture[1];
|
||||
const vec2& ct = clip_texture[2];
|
||||
const vec2& dt = clip_texture[3];
|
||||
if (output_length >= 3) {
|
||||
ap = screen_transform(clip_position[0]);
|
||||
bp = screen_transform(clip_position[1]);
|
||||
cp = screen_transform(clip_position[2]);
|
||||
|
||||
render_tri_type_7(writer,
|
||||
ap,
|
||||
bp,
|
||||
cp,
|
||||
at,
|
||||
bt,
|
||||
ct,
|
||||
li,
|
||||
li,
|
||||
li);
|
||||
}
|
||||
if (output_length >= 4) {
|
||||
dp = screen_transform(clip_position[3]);
|
||||
|
||||
render_tri_type_7(writer,
|
||||
ap,
|
||||
cp,
|
||||
dp,
|
||||
at,
|
||||
ct,
|
||||
dt,
|
||||
li,
|
||||
li,
|
||||
li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline float inverse_length(vec3 v)
|
||||
{
|
||||
float f = dot(v, v);
|
||||
@ -378,48 +454,53 @@ static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * fac
|
||||
vec3 bp = vertex_cache[bix].position;
|
||||
vec3 cp = vertex_cache[cix].position;
|
||||
|
||||
if (ap.z < 0 || bp.z < 0 || cp.z < 0) {
|
||||
vis_tri_count += 1;
|
||||
|
||||
if (ap.z < 0 && bp.z < 0 && cp.z < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3 n = vertex_cache[aix].normal;
|
||||
float li = light_intensity(light_vec, n);
|
||||
|
||||
/*
|
||||
printf("{%f %f %f} {%f %f %f} {%f %f %f}\n",
|
||||
ap.x, ap.y, ap.z,
|
||||
bp.x, bp.y, bp.z,
|
||||
cp.x, cp.y, cp.z);
|
||||
*/
|
||||
|
||||
|
||||
if (has_texture) {
|
||||
float v_mul = textures[face->texture].v_mul;
|
||||
vec2 at = {vert[aix].texcoord[0], vert[aix].texcoord[1] * v_mul};
|
||||
vec2 bt = {vert[bix].texcoord[0], vert[bix].texcoord[1] * v_mul};
|
||||
vec2 ct = {vert[cix].texcoord[0], vert[cix].texcoord[1] * v_mul};
|
||||
//printf("{%f %f} {%f %f} {%f %f}\n", at.x, at.y, bt.x, bt.y, ct.x, ct.y);
|
||||
|
||||
if (ap.z < 0 || bp.z < 0 || cp.z < 0) {
|
||||
render_clip_tri_type_7(writer,
|
||||
ap,
|
||||
bp,
|
||||
cp,
|
||||
at,
|
||||
bt,
|
||||
ct,
|
||||
li);
|
||||
|
||||
render_tri_type_7(writer,
|
||||
ap,
|
||||
bp,
|
||||
cp,
|
||||
at,
|
||||
bt,
|
||||
ct,
|
||||
} else {
|
||||
render_tri_type_7(writer,
|
||||
screen_transform(ap),
|
||||
screen_transform(bp),
|
||||
screen_transform(cp),
|
||||
at,
|
||||
bt,
|
||||
ct,
|
||||
li,
|
||||
li,
|
||||
li);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
render_tri_type_2(writer,
|
||||
screen_transform(ap),
|
||||
screen_transform(bp),
|
||||
screen_transform(cp),
|
||||
li,
|
||||
li,
|
||||
li);
|
||||
} else {
|
||||
/*
|
||||
render_tri_type_2(writer,
|
||||
ap,
|
||||
bp,
|
||||
cp,
|
||||
li,
|
||||
li,
|
||||
li);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -442,6 +523,26 @@ void transfer_faces(ta_parameter_writer& writer)
|
||||
}
|
||||
}
|
||||
|
||||
int count_face_triangles()
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
|
||||
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
|
||||
q3bsp_face_t * faces = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
|
||||
|
||||
int face_count = fe->length / (sizeof (struct q3bsp_face));
|
||||
|
||||
int sum = 0;
|
||||
|
||||
for (int i = 0; i < face_count; i++) {
|
||||
int triangles = faces[i].n_meshverts / 3;
|
||||
sum += triangles;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void transfer_icosphere(ta_parameter_writer& writer, const mat4x4& screen_trans)
|
||||
{
|
||||
const struct model * model = &icosphere_model;
|
||||
@ -731,6 +832,39 @@ void render_leaf_ix(ta_parameter_writer& writer)
|
||||
}
|
||||
}
|
||||
|
||||
void render_num(ta_parameter_writer& writer, int row, char * s, int num, int offset)
|
||||
{
|
||||
offset += unparse_base10_unsigned(&s[offset], num, 5, ' ');
|
||||
|
||||
font_bitmap::transform_string(writer,
|
||||
8, 16, // texture
|
||||
8, 16, // glyph
|
||||
16 + 50 * 8, // position x
|
||||
16 + row * 16, // position y
|
||||
s, offset,
|
||||
para_control::list_type::opaque);
|
||||
}
|
||||
|
||||
void render_tris_count(ta_parameter_writer& writer)
|
||||
{
|
||||
int offset = 18;
|
||||
{
|
||||
char s[32] = "total tris: ";
|
||||
int row = 0;
|
||||
render_num(writer, row, s, total_tri_count, offset);
|
||||
}
|
||||
{
|
||||
char s[32] = "bsp-visible tris: ";
|
||||
int row = 1;
|
||||
render_num(writer, row, s, vis_tri_count, offset);
|
||||
}
|
||||
{
|
||||
char s[32] = "rendered tris: ";
|
||||
int row = 2;
|
||||
render_num(writer, row, s, type7_tri_count, offset);
|
||||
}
|
||||
}
|
||||
|
||||
void render_bounding_box_mm(ta_parameter_writer& writer, const mat4x4& trans, int mins[3], int maxs[3], uint32_t color)
|
||||
{
|
||||
vec3 max = {(float)maxs[0], (float)maxs[1], (float)maxs[2]};
|
||||
@ -806,11 +940,14 @@ void render_leaf_faces(ta_parameter_writer& writer, const mat4x4& trans, q3bsp_l
|
||||
|
||||
for (int i = 0; i < leaf->n_leaffaces; i++) {
|
||||
int face_ix = lf[i].face;
|
||||
if (face_cache[face_ix] != 0)
|
||||
continue;
|
||||
face_cache[face_ix] = 1;
|
||||
transfer_face(writer, &faces[face_ix], &last_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void render_sphere_bounding_box(ta_parameter_writer& writer, const mat4x4& trans)
|
||||
void render_visible_faces(ta_parameter_writer& writer, const mat4x4& trans, const vec3 pos)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
@ -833,14 +970,14 @@ void render_sphere_bounding_box(ta_parameter_writer& writer, const mat4x4& trans
|
||||
q3bsp_node_t * new_root = NULL;
|
||||
if (root->children[0] >= 0) {
|
||||
q3bsp_node_t * node = &nodes[root->children[0]];
|
||||
a_inside = vec3_in_bb(sphere_position, node->mins, node->maxs);
|
||||
a_inside = vec3_in_bb(pos, node->mins, node->maxs);
|
||||
if (a_inside) {
|
||||
new_root = node;
|
||||
}
|
||||
} else {
|
||||
int leaf_ix = -(root->children[0] + 1);
|
||||
q3bsp_leaf_t * leaf = &leafs[leaf_ix];
|
||||
a_inside = vec3_in_bb(sphere_position, leaf->mins, leaf->maxs);
|
||||
a_inside = vec3_in_bb(pos, leaf->mins, leaf->maxs);
|
||||
if (a_inside) {
|
||||
bb_leaf = leaf;
|
||||
break;
|
||||
@ -848,14 +985,14 @@ void render_sphere_bounding_box(ta_parameter_writer& writer, const mat4x4& trans
|
||||
}
|
||||
if (root->children[1] >= 0) {
|
||||
q3bsp_node_t * node = &nodes[root->children[1]];
|
||||
b_inside = vec3_in_bb(sphere_position, node->mins, node->maxs);
|
||||
b_inside = vec3_in_bb(pos, node->mins, node->maxs);
|
||||
if (b_inside) {
|
||||
new_root = node;
|
||||
}
|
||||
} else {
|
||||
int leaf_ix = -(root->children[1] + 1);
|
||||
q3bsp_leaf_t * leaf = &leafs[leaf_ix];
|
||||
b_inside = vec3_in_bb(sphere_position, leaf->mins, leaf->maxs);
|
||||
b_inside = vec3_in_bb(pos, leaf->mins, leaf->maxs);
|
||||
if (b_inside) {
|
||||
bb_leaf = leaf;
|
||||
break;
|
||||
@ -883,8 +1020,10 @@ void render_sphere_bounding_box(ta_parameter_writer& writer, const mat4x4& trans
|
||||
q3bsp_leaf_t * leaf = &leafs[i];
|
||||
|
||||
// Cluster x is visible from cluster y if the (1 << y % 8) bit of vecs[x * sz_vecs + y / 8] is set.
|
||||
/*
|
||||
if (leaf->mins[2] > 450 && leaf->maxs[2] > 450)
|
||||
continue;
|
||||
*/
|
||||
|
||||
int y = bb_leaf->cluster;
|
||||
int x = leaf->cluster;
|
||||
@ -907,15 +1046,23 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans, con
|
||||
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
|
||||
transform_vertices(&buf[ve->offset], ve->length, trans);
|
||||
|
||||
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
|
||||
int face_count = fe->length / (sizeof (struct q3bsp_face));
|
||||
|
||||
//transfer_faces(writer);
|
||||
transfer_icosphere(writer, trans);
|
||||
|
||||
render_matrix(writer, screen_trans_inv);
|
||||
render_leaf_ix(writer);
|
||||
render_matrix(writer, screen_trans);
|
||||
//render_leaf_ix(writer);
|
||||
render_sphere_position(writer);
|
||||
render_zero_position(writer, screen_trans_inv);
|
||||
//render_zero_position(writer, screen_trans_inv);
|
||||
|
||||
render_sphere_bounding_box(writer, trans);
|
||||
vec3 pos = screen_trans_inv * (vec3){0, 0, 0};
|
||||
type7_tri_count = 0;
|
||||
vis_tri_count = 0;
|
||||
for (int i = 0; i < face_count; i++) face_cache[i] = 0;
|
||||
render_visible_faces(writer, trans, pos);
|
||||
render_tris_count(writer);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
@ -1035,13 +1182,15 @@ mat4x4 update_analog(const mat4x4& screen)
|
||||
if (ra && !la) x = -10;
|
||||
if (la && !ra) x = 10;
|
||||
|
||||
float y = -7 * y_;
|
||||
|
||||
float z = 0;
|
||||
if (ua && !da) z = -10;
|
||||
if (da && !ua) z = 10;
|
||||
|
||||
mat4x4 t = {
|
||||
1, 0, 0, x,
|
||||
0, 1, 0, 0,
|
||||
0, 1, 0, y,
|
||||
0, 0, 1, z,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
@ -1049,12 +1198,14 @@ mat4x4 update_analog(const mat4x4& screen)
|
||||
float yt = 0.05f * x_;
|
||||
float xt = 0.05f * y_;
|
||||
|
||||
/*
|
||||
mat4x4 rx = {
|
||||
1, 0, 0, 0,
|
||||
0, cos(xt), -sin(xt), 0,
|
||||
0, sin(xt), cos(xt), 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
*/
|
||||
|
||||
mat4x4 ry = {
|
||||
cos(yt), 0, sin(yt), 0,
|
||||
@ -1106,7 +1257,7 @@ mat4x4 update_analog(const mat4x4& screen)
|
||||
}
|
||||
}
|
||||
|
||||
return rx * ry * t * screen;
|
||||
return ry * t * screen;
|
||||
}
|
||||
|
||||
void transfer_font()
|
||||
@ -1125,6 +1276,8 @@ int main()
|
||||
{
|
||||
serial::init(0);
|
||||
|
||||
total_tri_count = count_face_triangles();
|
||||
|
||||
interrupt_init();
|
||||
transfer_textures();
|
||||
transfer_font();
|
||||
@ -1180,12 +1333,20 @@ int main()
|
||||
int ta = 0;
|
||||
int core = 0;
|
||||
|
||||
mat4x4 trans = {
|
||||
/*
|
||||
mat4x4 trans1 = {
|
||||
1.0, 0.0, 0.000, -1123.0,
|
||||
0.0, -0.888, -0.458, 859.0,
|
||||
0.0, 0.458, -0.888, 791.0,
|
||||
0.0, 0.000, 0.000, 1.0,
|
||||
};
|
||||
*/
|
||||
mat4x4 trans = {
|
||||
1.0, 0.0, 0.0, -894.0,
|
||||
0.0, 0.0, -1.0, 451.0,
|
||||
0.0, 1.0, 0.0, -465.0,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
};
|
||||
|
||||
do_get_condition();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user