Start LOD
This commit is contained in:
parent
672c17eec1
commit
5d9592bcd6
3 changed files with 168 additions and 24 deletions
14
assets.h
14
assets.h
|
@ -26,11 +26,11 @@ static const uint8_t map1[] =
|
|||
10,
|
||||
0,
|
||||
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,4,4,0,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,2,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,40,1,0,0),
|
||||
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,40,34,33,LCR_BLOCK_MATERIAL_CONCRETE,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,4,3,2,0,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,4,4,4,0,0),
|
||||
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,50,20,20,LCR_BLOCK_MATERIAL_GRASS,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,5,5,5,0,0),
|
||||
|
@ -41,6 +41,12 @@ static const uint8_t map1[] =
|
|||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,25,50,LCR_BLOCK_MATERIAL_GRASS,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,3,3,3,0,0),
|
||||
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_GRASS,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,40,1,1,0,0),
|
||||
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,63,63,0,LCR_BLOCK_MATERIAL_GRASS,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,1,1,40,0,0),
|
||||
|
||||
/*
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,0,LCR_BLOCK_MATERIAL_GRASS,0),
|
||||
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_HOLLOW,7,4,8,0,0),
|
||||
|
|
171
renderer.h
171
renderer.h
|
@ -17,9 +17,10 @@
|
|||
#include "small3dlib.h"
|
||||
|
||||
/// Renderer specific unit, length of one map square.
|
||||
#define LCR_RENDERER_UNIT S3L_FRACTIONS_PER_UNIT
|
||||
#define LCR_RENDERER_UNIT (S3L_FRACTIONS_PER_UNIT / 2)
|
||||
// ^ just S3L_FRACTIONS_PER_UNIT leaves some tris bugging
|
||||
|
||||
#define LCR_RENDERER_CHUNK_RESOLUTION 4
|
||||
#define LCR_RENDERER_CHUNK_RESOLUTION 4 // do not change
|
||||
|
||||
#define LCR_RENDERER_CHUNK_SIZE_HORIZONTAL \
|
||||
((LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / LCR_RENDERER_CHUNK_RESOLUTION)
|
||||
|
@ -27,6 +28,8 @@
|
|||
#define LCR_RENDERER_CHUNKS_TOTAL (LCR_RENDERER_CHUNK_RESOLUTION * \
|
||||
LCR_RENDERER_CHUNK_RESOLUTION * LCR_RENDERER_CHUNK_RESOLUTION)
|
||||
|
||||
#define LCR_RENDERER_LOD_BLOCKS 64
|
||||
|
||||
struct
|
||||
{
|
||||
S3L_Scene scene;
|
||||
|
@ -42,7 +45,6 @@ struct
|
|||
S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3];
|
||||
S3L_Index mapTris[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
|
||||
|
||||
|
||||
S3L_Index chunkStarts[LCR_RENDERER_CHUNKS_TOTAL];
|
||||
|
||||
/**
|
||||
|
@ -52,6 +54,10 @@ struct
|
|||
*/
|
||||
uint8_t mapTriangleData[LCR_SETTING_MAX_MAP_TRIANGLES];
|
||||
|
||||
|
||||
uint8_t gridLOD[LCR_RENDERER_LOD_BLOCKS];
|
||||
|
||||
|
||||
// pixel function precomputed values:
|
||||
int previousTriID;
|
||||
int triUVs[6];
|
||||
|
@ -660,6 +666,27 @@ uint8_t _LCR_buildMapModel(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void _LCR_computeLOD(void)
|
||||
{
|
||||
LCR_log("computing LOD");
|
||||
|
||||
for (int i = 0; i < LCR_RENDERER_LOD_BLOCKS; ++i)
|
||||
LCR_renderer.gridLOD[i] = 0;
|
||||
|
||||
for (int i = 0; i < LCR_currentMap.blockCount; ++i)
|
||||
{
|
||||
uint8_t x, y, z;
|
||||
|
||||
LCR_mapBlockGetCoords(LCR_currentMap.blocks + i * LCR_BLOCK_SIZE,&x,&y,&z);
|
||||
|
||||
x /= 8;
|
||||
y /= 8;
|
||||
z /= 8;
|
||||
|
||||
LCR_renderer.gridLOD[z * 8 + y] |= (0x01 << x);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LCR_rendererInit(void)
|
||||
{
|
||||
LCR_log("initializing renderer");
|
||||
|
@ -671,6 +698,8 @@ uint8_t LCR_rendererInit(void)
|
|||
|
||||
_LCR_makeMapChunks();
|
||||
|
||||
_LCR_computeLOD();
|
||||
|
||||
S3L_sceneInit(
|
||||
LCR_renderer.models + 1,8,&LCR_renderer.scene);
|
||||
|
||||
|
@ -722,6 +751,80 @@ chk(>,z,LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT / 2)
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
Fast and safe rect drawing function (handles out of screen coords).
|
||||
*/
|
||||
void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h,
|
||||
uint16_t color)
|
||||
{
|
||||
if (x >= LCR_EFFECTIVE_RESOLUTION_X || y >= LCR_EFFECTIVE_RESOLUTION_Y)
|
||||
return;
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
if (-1 * x > ((int) w))
|
||||
return;
|
||||
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (x + w > LCR_EFFECTIVE_RESOLUTION_X)
|
||||
w = LCR_EFFECTIVE_RESOLUTION_X - x;
|
||||
|
||||
if (y < 0)
|
||||
{
|
||||
if (-1 * y > ((int) h))
|
||||
return;
|
||||
|
||||
y += h;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (y + h > LCR_EFFECTIVE_RESOLUTION_X)
|
||||
h = LCR_EFFECTIVE_RESOLUTION_Y - y;
|
||||
|
||||
unsigned long index = y * LCR_EFFECTIVE_RESOLUTION_X + x;
|
||||
|
||||
for (unsigned int i = 0; i < h; ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < w; ++j)
|
||||
{
|
||||
LCR_drawPixel(index,color);
|
||||
index++;
|
||||
}
|
||||
|
||||
index += LCR_EFFECTIVE_RESOLUTION_X - w;
|
||||
}
|
||||
}
|
||||
|
||||
void _LCR_drawLOD(int blockX, int blockY, int blockZ, unsigned int size,
|
||||
uint16_t color)
|
||||
{
|
||||
S3L_Vec4 p, r;
|
||||
|
||||
p.x = (blockX - LCR_MAP_SIZE_BLOCKS / 2) * LCR_RENDERER_UNIT
|
||||
+ LCR_RENDERER_UNIT / 2;
|
||||
|
||||
p.y = (blockY - LCR_MAP_SIZE_BLOCKS / 2) * (LCR_RENDERER_UNIT / 2)
|
||||
+ LCR_RENDERER_UNIT / 4;
|
||||
|
||||
p.z = (blockZ - LCR_MAP_SIZE_BLOCKS / 2) * LCR_RENDERER_UNIT
|
||||
+ LCR_RENDERER_UNIT / 2;
|
||||
|
||||
p.w = size;
|
||||
|
||||
S3L_project3DPointToScreen(p,LCR_renderer.scene.camera,&r);
|
||||
|
||||
if (r.w > 0 && r.z > LCR_SETTING_LOD_DISTANCE * LCR_RENDERER_UNIT &&
|
||||
r.w < LCR_EFFECTIVE_RESOLUTION_X)
|
||||
{
|
||||
LCR_rendererDrawRect(r.x - r.w / 2,r.y - r.w / 2,
|
||||
r.w,r.w,color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Draws background sky, offsets are in multiples of screen dimensions
|
||||
(e.g. S3L_FRACTIONS_PER_UNIT / 2 for offsetH means half the screen width).
|
||||
|
@ -887,29 +990,31 @@ void _LCR_loadMapChunks(void)
|
|||
{
|
||||
int8_t camChunk[3], chunkOffsets[3];
|
||||
S3L_Vec4 cp = LCR_renderer.scene.camera.transform.translation;
|
||||
S3L_Vec4 cf;
|
||||
|
||||
S3L_rotationToDirections(LCR_renderer.scene.camera.transform.rotation,
|
||||
LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2,&cf,0,0);
|
||||
|
||||
camChunk[0] = (cp.x + (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 2)
|
||||
/ LCR_RENDERER_CHUNK_SIZE_HORIZONTAL;
|
||||
cp.x += (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 2;
|
||||
cp.y += (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 4;
|
||||
cp.z += (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 2;
|
||||
|
||||
camChunk[1] = (cp.y + (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 4)
|
||||
/ (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2);
|
||||
cf.x += cp.x % LCR_RENDERER_CHUNK_SIZE_HORIZONTAL;
|
||||
cf.y += cp.y % (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2);
|
||||
cf.z += cp.z % LCR_RENDERER_CHUNK_SIZE_HORIZONTAL;
|
||||
|
||||
camChunk[2] = ((cp.z + (LCR_MAP_SIZE_BLOCKS * LCR_RENDERER_UNIT) / 2)
|
||||
/ LCR_RENDERER_CHUNK_SIZE_HORIZONTAL);
|
||||
camChunk[0] = cp.x / LCR_RENDERER_CHUNK_SIZE_HORIZONTAL;
|
||||
camChunk[1] = cp.y / (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2);
|
||||
camChunk[2] = cp.z / LCR_RENDERER_CHUNK_SIZE_HORIZONTAL;
|
||||
|
||||
uint8_t camRot = S3L_wrap(LCR_renderer.scene.camera.transform.rotation.y
|
||||
+ S3L_FRACTIONS_PER_UNIT / 8,S3L_FRACTIONS_PER_UNIT) /
|
||||
(S3L_FRACTIONS_PER_UNIT / 4);
|
||||
|
||||
uint8_t camSide = (((camRot % 2) ? cp.x : cp.z) %
|
||||
LCR_RENDERER_CHUNK_SIZE_HORIZONTAL) >=
|
||||
LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2;
|
||||
|
||||
chunkOffsets[(camRot % 2) ? 0 : 2] = (camRot == 1 || camRot == 2) ? -1 : 1;
|
||||
chunkOffsets[(camRot % 2) ? 2 : 0] = (camSide == (camRot < 2)) ? 1 : -1;
|
||||
chunkOffsets[0] =
|
||||
(cf.x >= (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2)) ? 1 : -1;
|
||||
|
||||
chunkOffsets[1] =
|
||||
LCR_renderer.scene.camera.transform.rotation.x <= 0 ? -1 : 1;
|
||||
(cf.y >= (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 4)) ? 1 : -1;
|
||||
|
||||
chunkOffsets[2] =
|
||||
(cf.z >= (LCR_RENDERER_CHUNK_SIZE_HORIZONTAL / 2)) ? 1 : -1;
|
||||
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
_LCR_loadMapChunk(i,
|
||||
|
@ -918,6 +1023,30 @@ void _LCR_loadMapChunks(void)
|
|||
camChunk[2] + ((i & 0x04) ? chunkOffsets[2] : 0));
|
||||
}
|
||||
|
||||
void LCR_rendererDrawLOD(void)
|
||||
{
|
||||
for (unsigned int i = 0; i < LCR_RENDERER_LOD_BLOCKS; ++i)
|
||||
if (LCR_renderer.gridLOD[i])
|
||||
{
|
||||
uint8_t byte = LCR_renderer.gridLOD[i];
|
||||
unsigned int bx, by, bz;
|
||||
|
||||
bz = (i / 8) * 8 + 4;
|
||||
by = (i % 8) * 8 + 4;
|
||||
|
||||
for (unsigned int j = 0; j < 8; ++j)
|
||||
{
|
||||
if (byte & 0x01)
|
||||
{
|
||||
bx = j * 8 + 4;
|
||||
_LCR_drawLOD(bx,by,bz,LCR_EFFECTIVE_RESOLUTION_X,0);
|
||||
} // TODO: this ^
|
||||
|
||||
byte >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LCR_rendererDraw(void)
|
||||
{
|
||||
LCR_renderer.previousTriID = -1;
|
||||
|
@ -929,6 +1058,8 @@ void LCR_rendererDraw(void)
|
|||
LCR_renderer.scene.camera.transform.rotation.y,
|
||||
-4 * LCR_renderer.scene.camera.transform.rotation.x);
|
||||
|
||||
LCR_rendererDrawLOD();
|
||||
|
||||
S3L_drawScene(LCR_renderer.scene);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,4 +70,11 @@
|
|||
#define LCR_SETTING_TEXTURE_SUBSAMPLE 4
|
||||
#endif
|
||||
|
||||
#ifndef LCR_SETTING_LOD_DISTANCE
|
||||
/** Distance in game squares from which LOD will be drawn. Value 64 or higher
|
||||
turns off LOD completely. Note that this doesn't affect rendering distance
|
||||
of 3D models. */
|
||||
#define LCR_SETTING_LOD_DISTANCE 25
|
||||
#endif
|
||||
|
||||
#endif // guard
|
||||
|
|
Loading…
Reference in a new issue