dreamcast/scene.cpp
Zack Buhman 6cebd0ce90 ta_parameter: TA parameter initialization experiment
This also includes an example for generating a quad primitive. In
flycast, this is very obviously rendered as two triangles. On real
hardware, this appears to be a "native" quad.
2023-12-07 00:46:43 +08:00

123 lines
3.1 KiB
C++

#include <cstdint>
#include <cstddef>
#include "holly/ta_parameter.h"
#include "holly/texture_memory_alloc.h"
/*
-0.5,-0.5 0.5,-0.5
|
---
-0.5,0.5 | 0.5,0.5
*/
struct vertex0 {
float x;
float y;
float z;
float u;
float v;
uint32_t color;
};
const struct vertex0 scene_triangle[4] = {
{ -0.5f, 0.5f, 0.f, 0.f , 128.f/128.f, 0x00000000}, // the first two base colors in a
{ -0.5f, -0.5f, 0.f, 0.f , 0.f , 0x00000000}, // triangle strip are ignored
{ 0.5f, 0.5f, 0.f, 128.f/128.f, 128.f/128.f, 0xffff00ff},
{ 0.5f, -0.5f, 0.f, 128.f/128.f, 0.f , 0xffffff00},
};
struct vertex1 {
float x;
float y;
float z;
};
const struct vertex1 scene_quad[4] = {
{ -0.5f, 0.5f, 0.f },
{ -0.5f, -0.5f, 0.f },
{ 0.5f, -0.5f, 0.f },
{ 0.5f, 0.5f, 0.f },
};
struct scene_quad_ta_parameters {
global_sprite sprite;
vertex_sprite_type_0 vertex;
global_end_of_list end_of_list;
};
static_assert((sizeof (scene_quad_ta_parameters)) == 32 * 4);
uint32_t scene_transform_quad(uint32_t * _scene)
{
auto scene = reinterpret_cast<scene_quad_ta_parameters *>(&_scene[0]);
uint32_t base_color = 0xffffff00;
scene->sprite = global_sprite(base_color);
scene->vertex = vertex_sprite_type_0(scene_quad[0].x * 240 + 320,
scene_quad[0].y * 240 + 240,
1 / (scene_quad[0].z + 10),
scene_quad[1].x * 240 + 320,
scene_quad[1].y * 240 + 240,
1 / (scene_quad[1].z + 10),
scene_quad[2].x * 240 + 320,
scene_quad[2].y * 240 + 240,
1 / (scene_quad[2].z + 10),
scene_quad[3].x * 240 + 320,
scene_quad[3].y * 240 + 240);
scene->end_of_list = global_end_of_list();
return (sizeof (scene_quad_ta_parameters));
}
static float theta = 0;
constexpr float half_degree = 0.01745329f / 2.f;
union ta_parameter {
struct global_polygon_type_0 global_polygon_type_0;
struct vertex_polygon_type_3 vertex_polygon_type_3;
struct global_end_of_list global_end_of_list;
};
extern void serial_string(const char * s);
uint32_t scene_transform(uint32_t * _scene)
{
ta_parameter * scene = reinterpret_cast<ta_parameter *>(&_scene[0]);
int ix = 0;
uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
scene[ix++].global_polygon_type_0 = global_polygon_type_0(texture_address);
for (uint32_t i = 0; i < 4; i++) {
bool end_of_strip = i == 3;
float x = scene_triangle[i].x;
float y = scene_triangle[i].y;
float z = scene_triangle[i].z;
float x1;
x1 = x * __builtin_cosf(theta) - z * __builtin_sinf(theta);
z = x * __builtin_sinf(theta) + z * __builtin_cosf(theta);
x = x1;
x *= 240.f;
y *= 240.f;
x += 320.f;
y += 240.f;
scene[ix++].vertex_polygon_type_3 = vertex_polygon_type_3(x, // x
y, // y
1.f / (z + 10.f), // z
scene_triangle[i].u, // u
scene_triangle[i].v, // v
scene_triangle[i].color, // base_color
end_of_strip);
}
scene[ix++].global_end_of_list = global_end_of_list();
theta += half_degree;
return ix * 32;
}