mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-23 20:59:58 +01:00
244 lines
4.9 KiB
C++
244 lines
4.9 KiB
C++
/*
|
|
Example program of small3dlib for Pokitto -- Quake-like level.
|
|
|
|
author: Miloslav Ciz
|
|
license: CC0 1.0
|
|
*/
|
|
|
|
#include "Pokitto.h"
|
|
|
|
#define SUBSAMPLE 3
|
|
|
|
#if 1 // This can switch between a textured and flat mode.
|
|
#define S3L_Z_BUFFER 2
|
|
#define S3L_SORT 0
|
|
#define S3L_STENCIL_BUFFER 0
|
|
#define S3L_FLAT 0
|
|
#define S3L_PERSPECTIVE_CORRECTION 2
|
|
#else
|
|
#define S3L_Z_BUFFER 2
|
|
#define S3L_SORT 0
|
|
#define S3L_STENCIL_BUFFER 0
|
|
#define S3L_FLAT 1
|
|
#define S3L_MAX_TRIANGES_DRAWN 200
|
|
#endif
|
|
|
|
#define S3L_PIXEL_FUNCTION pixelFunc
|
|
|
|
// Because we'll be writing pixels as 2x2, define the resolution one smaller.
|
|
#define BASE_W 109
|
|
#define BASE_H 87
|
|
|
|
#define S3L_RESOLUTION_X (BASE_W - BASE_W / SUBSAMPLE)
|
|
#define S3L_RESOLUTION_Y (BASE_H - BASE_H / SUBSAMPLE)
|
|
|
|
#define S3L_STRICT_NEAR_CULLING 0
|
|
|
|
#define S3L_COMPUTE_DEPTH 1 // for fog
|
|
|
|
#define S3L_REDUCED_Z_BUFFER_GRANULARITY 6
|
|
|
|
#include "small3dlib.h"
|
|
|
|
#include "levelTexture1Pal.h"
|
|
#include "levelModel.h"
|
|
|
|
Pokitto::Core pokitto;
|
|
|
|
#if S3L_FLAT
|
|
uint8_t triangleColors[LEVEL_TRIANGLE_COUNT];
|
|
#endif
|
|
|
|
static inline uint8_t texture(int32_t u, int32_t v)
|
|
{
|
|
u = S3L_wrap(u,LEVEL1_TEXTURE_WIDTH);
|
|
v = S3L_wrap(v,LEVEL1_TEXTURE_HEIGHT);
|
|
|
|
uint32_t index = v * LEVEL1_TEXTURE_WIDTH + u;
|
|
|
|
return level1Texture[index];
|
|
}
|
|
|
|
S3L_ScreenCoord subsampleMap[BASE_W + SUBSAMPLE];
|
|
|
|
uint32_t previousTriangle = 100;
|
|
|
|
static inline uint8_t addIntensity(uint8_t color, uint8_t intensity)
|
|
{
|
|
uint8_t newValue = color + intensity; // value as in HSV
|
|
|
|
if (color >> 4 == newValue >> 4)
|
|
return newValue;
|
|
|
|
return color | 0x0F;
|
|
}
|
|
|
|
static inline uint8_t substractIntensity(uint8_t color, uint8_t intensity)
|
|
{
|
|
uint8_t newValue = color - intensity; // value as in HSV
|
|
|
|
if (color >> 4 == newValue >> 4)
|
|
return newValue;
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint8_t c = 0;
|
|
|
|
S3L_Vec4 uv0, uv1, uv2;
|
|
|
|
S3L_Index material = 0;
|
|
|
|
void pixelFunc(S3L_PixelInfo *p)
|
|
{
|
|
uint8_t val;
|
|
uint8_t *buf = pokitto.display.screenbuffer;
|
|
|
|
#if S3L_FLAT
|
|
val = triangleColors[p->triangleIndex];
|
|
#else
|
|
if (p->triangleIndex != previousTriangle)
|
|
{
|
|
material = levelMaterials[p->triangleIndex];
|
|
|
|
if (material == 1)
|
|
c = 135;
|
|
else if (material == 2)
|
|
c = 213;
|
|
else
|
|
S3L_getIndexedTriangleValues(p->triangleIndex,levelUVIndices,levelUVs,2,&uv0,&uv1,&uv2);
|
|
|
|
previousTriangle = p->triangleID;
|
|
}
|
|
|
|
S3L_Unit fog = p->depth >> 9;
|
|
|
|
if (material == 0)
|
|
{
|
|
S3L_Unit uv[2];
|
|
uv[0] = S3L_interpolateBarycentric(uv0.x,uv1.x,uv2.x,p->barycentric);
|
|
uv[1] = S3L_interpolateBarycentric(uv0.y,uv1.y,uv2.y,p->barycentric);
|
|
|
|
c = texture(uv[0] / 32,uv[1] / 32);
|
|
}
|
|
|
|
val = substractIntensity(c,fog);
|
|
#endif
|
|
|
|
buf += subsampleMap[p->y] * 110;
|
|
buf += subsampleMap[p->x];
|
|
*buf = val;
|
|
|
|
buf++;
|
|
*buf = val;
|
|
buf += 109;
|
|
*buf = val;
|
|
buf++;
|
|
*buf = val;
|
|
}
|
|
|
|
S3L_Scene scene;
|
|
|
|
void draw()
|
|
{
|
|
S3L_newFrame();
|
|
S3L_drawScene(scene);
|
|
}
|
|
|
|
unsigned short palette[256];
|
|
|
|
int main()
|
|
{
|
|
for (uint16_t i = 0; i < BASE_W + SUBSAMPLE; ++i)
|
|
subsampleMap[i] = i + i / SUBSAMPLE;
|
|
|
|
#if S3L_FLAT
|
|
S3L_Vec4 toLight;
|
|
S3L_setVec4(&toLight,10,5,7,0);
|
|
S3L_normalizeVec3(&toLight);
|
|
|
|
for (uint16_t i = 0; i < LEVEL_TRIANGLE_COUNT; ++i)
|
|
{
|
|
uint8_t c;
|
|
|
|
S3L_Vec4 v0, v1, v2;
|
|
|
|
S3L_getIndexedTriangleValues(
|
|
i,
|
|
levelTriangleIndices,
|
|
levelVertices,3,&v0,&v1,&v2);
|
|
|
|
material = levelMaterials[i];
|
|
|
|
if (material == 1)
|
|
c = 38;
|
|
else if (material == 2)
|
|
c = 53;
|
|
else
|
|
c = 24;
|
|
|
|
S3L_Vec4 normal;
|
|
|
|
S3L_triangleNormal(v0,v1,v2,&normal);
|
|
|
|
triangleColors[i] = addIntensity(c,
|
|
S3L_max(0,(S3L_dotProductVec3(normal,toLight) + S3L_FRACTIONS_PER_UNIT) / 64));
|
|
}
|
|
|
|
#endif
|
|
|
|
pokitto.begin();
|
|
|
|
// pokitto.display.persistence = 1;
|
|
pokitto.setFrameRate(60);
|
|
|
|
pokitto.display.load565Palette(level1Palette);
|
|
|
|
S3L_initCamera(&scene.camera);
|
|
|
|
levelModelInit();
|
|
|
|
S3L_initScene(&levelModel,1,&scene);
|
|
|
|
while (pokitto.isRunning())
|
|
{
|
|
if (pokitto.update())
|
|
{
|
|
S3L_Vec4 camF, camR, camU;
|
|
int step = 300;
|
|
int step2 = 8;
|
|
|
|
S3L_rotationToDirections(
|
|
scene.camera.transform.rotation,
|
|
step,
|
|
&camF,
|
|
&camR,
|
|
&camU);
|
|
|
|
if (pokitto.aBtn())
|
|
{
|
|
if (pokitto.upBtn())
|
|
scene.camera.transform.rotation.x += 8;
|
|
else if (pokitto.downBtn())
|
|
scene.camera.transform.rotation.x -= 8;
|
|
else if (pokitto.rightBtn())
|
|
scene.camera.transform.rotation.y += 8;
|
|
else if (pokitto.leftBtn())
|
|
scene.camera.transform.rotation.y -= 8;
|
|
}
|
|
else
|
|
{
|
|
if (pokitto.upBtn())
|
|
S3L_vec3Add(&(scene.camera.transform.translation),camF);
|
|
else if (pokitto.downBtn())
|
|
S3L_vec3Sub(&scene.camera.transform.translation,camF);
|
|
else if (pokitto.rightBtn())
|
|
S3L_vec3Add(&scene.camera.transform.translation,camR);
|
|
else if (pokitto.leftBtn())
|
|
S3L_vec3Sub(&scene.camera.transform.translation,camR);
|
|
}
|
|
|
|
draw();
|
|
}
|
|
}
|
|
}
|