Start drawing sky

This commit is contained in:
Miloslav Ciz 2024-07-30 02:47:42 +02:00
parent d02b8b4ec3
commit 681bcf2712
4 changed files with 3113 additions and 147 deletions

2932
assets.h

File diff suppressed because it is too large Load diff

1
game.h
View file

@ -130,7 +130,6 @@ uint8_t LCR_gameStep(uint32_t time)
if (time >= LCR_nextRenderFrameTime) if (time >= LCR_nextRenderFrameTime)
{ {
LCR_drawBackground(0);
LCR_rendererDraw(); LCR_rendererDraw();
LCR_nextRenderFrameTime += 1000 / LCR_SETTING_FPS; LCR_nextRenderFrameTime += 1000 / LCR_SETTING_FPS;

View file

@ -12,43 +12,38 @@
#define S3L_PERSPECTIVE_CORRECTION 2 #define S3L_PERSPECTIVE_CORRECTION 2
#define S3L_NEAR_CROSS_STRATEGY 0 #define S3L_NEAR_CROSS_STRATEGY 0
#define S3L_Z_BUFFER 2 #define S3L_Z_BUFFER 1
#include "small3dlib.h" #include "small3dlib.h"
/// Renderer specific unit, length of one map square. /// Renderer specific unit, length of one map square.
#define LCR_RENDERER_UNIT S3L_FRACTIONS_PER_UNIT #define LCR_RENDERER_UNIT S3L_FRACTIONS_PER_UNIT
struct LCR_Renderer struct
{ {
// TODO S3L_Scene scene3D;
}; S3L_Model3D models3D[3]; // TODO
S3L_Scene LCR_scene3D; S3L_Model3D *mapModel;
S3L_Model3D LCR_models3D[3]; // TODO S3L_Unit mapVertices[LCR_SETTING_MAX_MAP_VERTICES * 3];
S3L_Index mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
S3L_Model3D *LCR_mapModel; // pixel function precomputed values:
S3L_Unit LCR_mapVertices[LCR_SETTING_MAX_MAP_VERTICES * 3]; int previousTriangleID;
S3L_Index LCR_mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3]; int triangleUVs[6];
} LCR_renderer;
int _LCR_rendererPreviousTriangleID;
int _LCR_rendererTriangleUVs[6];
uint16_t _LCR_triangleShadingMask;
void LCR_pixelFunc3D(S3L_PixelInfo *pixel) void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{ {
// once we get a new triangle, we precompute things for it: // once we get a new triangle, we precompute things for it:
if (pixel->triangleIndex != _LCR_rendererPreviousTriangleID) if (pixel->triangleIndex != LCR_renderer.previousTriangleID)
{ {
S3L_Index *t = LCR_mapTriangles + 3 * pixel->triangleIndex; S3L_Index *t = LCR_renderer.mapTriangles + 3 * pixel->triangleIndex;
S3L_Unit *v[3]; S3L_Unit *v[3];
v[0] = LCR_mapVertices + 3 * t[0]; for (int i = 0; i < 3; ++i)
v[1] = LCR_mapVertices + 3 * t[1]; v[i] = LCR_renderer.mapVertices + 3 * t[i];
v[2] = LCR_mapVertices + 3 * t[2];
uint8_t type = // 0: floor, 1: wall, 2: wall 90 degrees uint8_t type = // 0: floor, 1: wall, 2: wall 90 degrees
(v[0][0] == v[1][0] && v[1][0] == v[2][0]) + (v[0][0] == v[1][0] && v[1][0] == v[2][0]) +
@ -56,33 +51,35 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
if (type == 0) if (type == 0)
{ {
LCR_loadImage(1); LCR_loadImage(3);
_LCR_triangleShadingMask = 0xffff;
if (v[0][1] != v[1][1] || v[1][1] != v[2][1])
LCR_imageChangeBrightness(1);
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
_LCR_rendererTriangleUVs[i] = (( LCR_renderer.triangleUVs[i] = ((
(v[i / 2][(i % 2) * 2]) * (v[i / 2][(i % 2) * 2]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT); LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
} }
else else
{ {
LCR_loadImage(0); LCR_loadImage(1);
if (type == 1)
LCR_imageChangeBrightness(0);
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
{ {
_LCR_rendererTriangleUVs[i] = (( LCR_renderer.triangleUVs[i] = ((
(v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) * (v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT); LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
if (i % 2) if (i % 2)
_LCR_rendererTriangleUVs[i] = LCR_IMAGE_SIZE - LCR_renderer.triangleUVs[i] = LCR_IMAGE_SIZE -
_LCR_rendererTriangleUVs[i]; LCR_renderer.triangleUVs[i];
} }
_LCR_triangleShadingMask = type == 1 ? 0xf7de : 0xe79c;
} }
_LCR_rendererPreviousTriangleID = pixel->triangleIndex; LCR_renderer.previousTriangleID = pixel->triangleIndex;
} }
int barycentric[3]; int barycentric[3];
@ -92,15 +89,15 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
barycentric[2] = pixel->barycentric[2] / 8; barycentric[2] = pixel->barycentric[2] / 8;
uint16_t color = LCR_sampleImage( uint16_t color = LCR_sampleImage(
(barycentric[0] * _LCR_rendererTriangleUVs[0] + (barycentric[0] * LCR_renderer.triangleUVs[0] +
barycentric[1] * _LCR_rendererTriangleUVs[2] + barycentric[1] * LCR_renderer.triangleUVs[2] +
barycentric[2] * _LCR_rendererTriangleUVs[4]) barycentric[2] * LCR_renderer.triangleUVs[4])
/ (S3L_FRACTIONS_PER_UNIT / 8), / (S3L_FRACTIONS_PER_UNIT / 8),
(barycentric[0] * _LCR_rendererTriangleUVs[1] + (barycentric[0] * LCR_renderer.triangleUVs[1] +
barycentric[1] * _LCR_rendererTriangleUVs[3] + barycentric[1] * LCR_renderer.triangleUVs[3] +
barycentric[2] * _LCR_rendererTriangleUVs[5]) barycentric[2] * LCR_renderer.triangleUVs[5])
/ (S3L_FRACTIONS_PER_UNIT / 8) / (S3L_FRACTIONS_PER_UNIT / 8)
) & _LCR_triangleShadingMask; );
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color); LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color);
} }
@ -108,9 +105,9 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z) S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
{ {
S3L_Index index = 0; S3L_Index index = 0;
S3L_Unit *vertices = LCR_mapVertices; S3L_Unit *vertices = LCR_renderer.mapVertices;
while (index < LCR_mapModel->vertexCount) // if exists, return vertex index while (index < LCR_renderer.mapModel->vertexCount) // if exists, return vertex index
{ {
if (vertices[0] == x && vertices[1] == y && vertices[2] == z) if (vertices[0] == x && vertices[1] == y && vertices[2] == z)
return index; return index;
@ -120,15 +117,15 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
} }
// if it doesn't exist, add it // if it doesn't exist, add it
if (LCR_mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES) if (LCR_renderer.mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES)
{ {
*vertices = x; *vertices = x;
vertices++; vertices++;
*vertices = y; *vertices = y;
vertices++; vertices++;
*vertices = z; *vertices = z;
LCR_mapModel->vertexCount++; LCR_renderer.mapModel->vertexCount++;
return LCR_mapModel->vertexCount - 1; return LCR_renderer.mapModel->vertexCount - 1;
} }
// TODO: error print // TODO: error print
@ -137,9 +134,9 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c) void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c)
{ {
if (LCR_mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES) if (LCR_renderer.mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES)
{ {
S3L_Index *t = &(LCR_mapTriangles[LCR_mapModel->triangleCount * 3]); S3L_Index *t = &(LCR_renderer.mapTriangles[LCR_renderer.mapModel->triangleCount * 3]);
*t = a; *t = a;
t++; t++;
@ -147,7 +144,7 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c)
t++; t++;
*t = c; *t = c;
LCR_mapModel->triangleCount++; LCR_renderer.mapModel->triangleCount++;
} }
} }
@ -219,11 +216,11 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
int plane = -1; int plane = -1;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (LCR_mapVertices[3 * t1[0] + i] == LCR_mapVertices[3 * t1[1] + i] && if (LCR_renderer.mapVertices[3 * t1[0] + i] == LCR_renderer.mapVertices[3 * t1[1] + i] &&
LCR_mapVertices[3 * t1[1] + i] == LCR_mapVertices[3 * t1[2] + i] && LCR_renderer.mapVertices[3 * t1[1] + i] == LCR_renderer.mapVertices[3 * t1[2] + i] &&
LCR_mapVertices[3 * t1[2] + i] == LCR_mapVertices[3 * t2[0] + i] && LCR_renderer.mapVertices[3 * t1[2] + i] == LCR_renderer.mapVertices[3 * t2[0] + i] &&
LCR_mapVertices[3 * t2[0] + i] == LCR_mapVertices[3 * t2[1] + i] && LCR_renderer.mapVertices[3 * t2[0] + i] == LCR_renderer.mapVertices[3 * t2[1] + i] &&
LCR_mapVertices[3 * t2[1] + i] == LCR_mapVertices[3 * t2[2] + i]) LCR_renderer.mapVertices[3 * t2[1] + i] == LCR_renderer.mapVertices[3 * t2[2] + i])
{ {
plane = i; plane = i;
break; break;
@ -240,10 +237,10 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
{ {
points2D[i * 2] = LCR_mapVertices[3 * t1[i] + coordX]; points2D[i * 2] = LCR_renderer.mapVertices[3 * t1[i] + coordX];
points2D[i * 2 + 1] = LCR_mapVertices[3 * t1[i] + coordY]; points2D[i * 2 + 1] = LCR_renderer.mapVertices[3 * t1[i] + coordY];
points2D[6 + i * 2] = LCR_mapVertices[3 * t2[i] + coordX]; points2D[6 + i * 2] = LCR_renderer.mapVertices[3 * t2[i] + coordX];
points2D[6 + i * 2 + 1] = LCR_mapVertices[3 * t2[i] + coordY]; points2D[6 + i * 2 + 1] = LCR_renderer.mapVertices[3 * t2[i] + coordY];
} }
points2D[12] = (4 * points2D[6] + 3 * points2D[8] + points2D[10]) / 8; points2D[12] = (4 * points2D[6] + 3 * points2D[8] + points2D[10]) / 8;
@ -256,9 +253,9 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
{ {
// now check if this triangle along with a neighbor cover the other one // now check if this triangle along with a neighbor cover the other one
S3L_Index *t3 = LCR_mapTriangles; S3L_Index *t3 = LCR_renderer.mapTriangles;
for (int i = 0; i < LCR_mapModel->triangleCount; ++i) for (int i = 0; i < LCR_renderer.mapModel->triangleCount; ++i)
{ {
uint8_t sharedVerts = uint8_t sharedVerts =
(t3[0] == t2[0] || t3[0] == t2[1] || t3[0] == t2[2]) | (t3[0] == t2[0] || t3[0] == t2[1] || t3[0] == t2[2]) |
@ -268,12 +265,12 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
if ( if (
t3 != t1 && t3 != t2 && t3 != t1 && t3 != t2 &&
(sharedVerts == 3 || sharedVerts == 5 || sharedVerts == 6) && (sharedVerts == 3 || sharedVerts == 5 || sharedVerts == 6) &&
LCR_mapVertices[3 * t3[0] + plane] == LCR_renderer.mapVertices[3 * t3[0] + plane] ==
LCR_mapVertices[3 * t3[1] + plane] && LCR_renderer.mapVertices[3 * t3[1] + plane] &&
LCR_mapVertices[3 * t3[1] + plane] == LCR_renderer.mapVertices[3 * t3[1] + plane] ==
LCR_mapVertices[3 * t3[2] + plane] && LCR_renderer.mapVertices[3 * t3[2] + plane] &&
LCR_mapVertices[3 * t3[0] + plane] == LCR_renderer.mapVertices[3 * t3[0] + plane] ==
LCR_mapVertices[3 * t1[0] + plane] LCR_renderer.mapVertices[3 * t1[0] + plane]
) )
{ {
// here shares exactly two vertices and is in the same plane // here shares exactly two vertices and is in the same plane
@ -281,8 +278,8 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
uint8_t freeVert = uint8_t freeVert =
sharedVerts == 3 ? 2 : (sharedVerts == 5 ? 1 : 0); sharedVerts == 3 ? 2 : (sharedVerts == 5 ? 1 : 0);
points2D[12] = LCR_mapVertices[3 * t3[freeVert] + coordX]; points2D[12] = LCR_renderer.mapVertices[3 * t3[freeVert] + coordX];
points2D[13] = LCR_mapVertices[3 * t3[freeVert] + coordY]; points2D[13] = LCR_renderer.mapVertices[3 * t3[freeVert] + coordY];
if (_LCR_quadCoversTriangle(points2D + 6,points2D)) if (_LCR_quadCoversTriangle(points2D + 6,points2D))
{ {
@ -315,19 +312,19 @@ void _LCR_rendererPruneHiddenMapTriangles(void)
int n = 0; // number of removed elements int n = 0; // number of removed elements
int i = 0; int i = 0;
S3L_Index *t1 = LCR_mapTriangles, *t2; S3L_Index *t1 = LCR_renderer.mapTriangles, *t2;
/* /*
We'll be moving the covered triangles to the end of the array, then at the We'll be moving the covered triangles to the end of the array, then at the
end we'll just shorten the array. end we'll just shorten the array.
*/ */
while (i < LCR_mapModel->triangleCount - n) while (i < LCR_renderer.mapModel->triangleCount - n)
{ {
t2 = t1 + 3; t2 = t1 + 3;
int t1Covered = 0; int t1Covered = 0;
for (int j = i + 1; j < LCR_mapModel->triangleCount; ++j) for (int j = i + 1; j < LCR_renderer.mapModel->triangleCount; ++j)
{ {
uint8_t cover = _LCR_rendererCheckMapTriangleCover(t1,t2); uint8_t cover = _LCR_rendererCheckMapTriangleCover(t1,t2);
@ -335,10 +332,10 @@ void _LCR_rendererPruneHiddenMapTriangles(void)
if (cover & 0x02) if (cover & 0x02)
{ {
if (j < LCR_mapModel->triangleCount - n) if (j < LCR_renderer.mapModel->triangleCount - n)
{ {
_LCR_rendererSwapTriangles(t2, _LCR_rendererSwapTriangles(t2,
LCR_mapTriangles + (LCR_mapModel->triangleCount - 1 - n) * 3); LCR_renderer.mapTriangles + (LCR_renderer.mapModel->triangleCount - 1 - n) * 3);
n++; n++;
} }
@ -350,7 +347,7 @@ void _LCR_rendererPruneHiddenMapTriangles(void)
if (t1Covered) if (t1Covered)
{ {
_LCR_rendererSwapTriangles(t1, _LCR_rendererSwapTriangles(t1,
LCR_mapTriangles + (LCR_mapModel->triangleCount - 1 - n) * 3); LCR_renderer.mapTriangles + (LCR_renderer.mapModel->triangleCount - 1 - n) * 3);
n++; n++;
} }
else else
@ -360,18 +357,18 @@ void _LCR_rendererPruneHiddenMapTriangles(void)
} }
} }
LCR_mapModel->triangleCount -= n; LCR_renderer.mapModel->triangleCount -= n;
// remove unused vertices: // remove unused vertices:
i = 0; i = 0;
while (i < LCR_mapModel->vertexCount) while (i < LCR_renderer.mapModel->vertexCount)
{ {
int used = 0; int used = 0;
for (int j = 0; j < LCR_mapModel->triangleCount * 3; ++j) for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
if (LCR_mapTriangles[j] == i) if (LCR_renderer.mapTriangles[j] == i)
{ {
used = 1; used = 1;
break; break;
@ -382,28 +379,28 @@ void _LCR_rendererPruneHiddenMapTriangles(void)
else else
{ {
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
LCR_mapVertices[3 * i + j] = LCR_renderer.mapVertices[3 * i + j] =
LCR_mapVertices[(LCR_mapModel->vertexCount - 1) * 3 + j]; LCR_renderer.mapVertices[(LCR_renderer.mapModel->vertexCount - 1) * 3 + j];
for (int j = 0; j < LCR_mapModel->triangleCount * 3; ++j) for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
if (LCR_mapTriangles[j] == LCR_mapModel->vertexCount - 1) if (LCR_renderer.mapTriangles[j] == LCR_renderer.mapModel->vertexCount - 1)
LCR_mapTriangles[j] = i; LCR_renderer.mapTriangles[j] = i;
LCR_mapModel->vertexCount--; LCR_renderer.mapModel->vertexCount--;
} }
} }
} }
/** /**
Builds an internal 3D model of the currently loaded map. Returns 1 on success, Builds the internal 3D model of the currently loaded map. Returns 1 on
otherwise 0 (e.g. not enough space). success, 0 otherwise (e.g. not enough space).
*/ */
uint8_t _LCR_rendererBuildMapModel(void) uint8_t _LCR_rendererBuildMapModel(void)
{ {
uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES];
uint8_t blockShapeByteCount; uint8_t blockShapeByteCount;
S3L_model3DInit(LCR_mapVertices,0,LCR_mapTriangles,0,LCR_mapModel); S3L_model3DInit(LCR_renderer.mapVertices,0,LCR_renderer.mapTriangles,0,LCR_renderer.mapModel);
for (int j = 0; j < LCR_currentMap.blockCount; ++j) for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{ {
@ -440,19 +437,19 @@ uint8_t _LCR_rendererBuildMapModel(void)
} }
} }
_LCR_rendererPruneHiddenMapTriangles(); _LCR_rendererPruneHiddenMapTriangles();
return 1; return 1;
} }
uint8_t LCR_rendererInit(void) uint8_t LCR_rendererInit(void)
{ {
LCR_mapModel = LCR_models3D; LCR_renderer.mapModel = LCR_renderer.models3D;
if (!_LCR_rendererBuildMapModel()) if (!_LCR_rendererBuildMapModel())
return 0; return 0;
S3L_sceneInit(LCR_models3D,1,&LCR_scene3D); S3L_sceneInit(LCR_renderer.models3D,1,&LCR_renderer.scene3D);
return 1; return 1;
} }
@ -462,67 +459,148 @@ void LCR_rendererMoveCamera(LCR_SpaceUnit forwRightUpOffset[3],
{ {
S3L_Vec4 f, r, u; S3L_Vec4 f, r, u;
S3L_rotationToDirections(LCR_scene3D.camera.transform.rotation, S3L_rotationToDirections(LCR_renderer.scene3D.camera.transform.rotation,
S3L_FRACTIONS_PER_UNIT,&f,&r,&u); S3L_FRACTIONS_PER_UNIT,&f,&r,&u);
LCR_scene3D.camera.transform.translation.x += LCR_renderer.scene3D.camera.transform.translation.x +=
((f.x * forwRightUpOffset[0] + r.x * forwRightUpOffset[1] + ((f.x * forwRightUpOffset[0] + r.x * forwRightUpOffset[1] +
u.x * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.x * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_scene3D.camera.transform.translation.y += LCR_renderer.scene3D.camera.transform.translation.y +=
((f.y * forwRightUpOffset[0] + r.y * forwRightUpOffset[1] + ((f.y * forwRightUpOffset[0] + r.y * forwRightUpOffset[1] +
u.y * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.y * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_scene3D.camera.transform.translation.z += LCR_renderer.scene3D.camera.transform.translation.z +=
((f.z * forwRightUpOffset[0] + r.z * forwRightUpOffset[1] + ((f.z * forwRightUpOffset[0] + r.z * forwRightUpOffset[1] +
u.z * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; u.z * forwRightUpOffset[2]) * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_scene3D.camera.transform.rotation.y += LCR_renderer.scene3D.camera.transform.rotation.y +=
(yawPitchOffset[0] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; (yawPitchOffset[0] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
LCR_scene3D.camera.transform.rotation.x += LCR_renderer.scene3D.camera.transform.rotation.x +=
(yawPitchOffset[1] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN; (yawPitchOffset[1] * S3L_FRACTIONS_PER_UNIT) / LCR_SQUARE_SIDE_LEN;
if (LCR_scene3D.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4) if (LCR_renderer.scene3D.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4)
LCR_scene3D.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4; LCR_renderer.scene3D.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4;
if (LCR_scene3D.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4) if (LCR_renderer.scene3D.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4)
LCR_scene3D.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4; LCR_renderer.scene3D.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4;
}
/**
Draws background sky, offsets are in multiples of screen dimensions
(e.g. S3L_FRACTIONS_PER_UNIT / 2 for offsetH means half the screen width).
*/
void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
{
int anchorPoint[2], y;
unsigned long pixelIndex;
unsigned int topColor, bottomColor;
LCR_loadImage(8);
topColor = LCR_sampleImage(0,0);
LCR_loadImage(8 + 3);
bottomColor = LCR_sampleImage(LCR_IMAGE_SIZE - 1,LCR_IMAGE_SIZE - 1);
anchorPoint[0] = ((LCR_EFFECTIVE_RESOLUTION_X * offsetH)
/ S3L_FRACTIONS_PER_UNIT) %
(2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE);
if (anchorPoint[0] < 0)
anchorPoint[0] += 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
anchorPoint[1] =
(LCR_EFFECTIVE_RESOLUTION_Y) / 2 -
(LCR_EFFECTIVE_RESOLUTION_Y * offsetV) / S3L_FRACTIONS_PER_UNIT
- LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
pixelIndex = 0;
y = anchorPoint[1] < 0 ? anchorPoint[1] : 0;
while (y < anchorPoint[1] && y < LCR_EFFECTIVE_RESOLUTION_Y) // top strip
{
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{
LCR_drawPixel(pixelIndex,topColor);
pixelIndex++;
}
y++;
}
anchorPoint[1] += 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
int linesLeft = 0;
int skyPart = 0;
while (y < anchorPoint[1] && y < LCR_EFFECTIVE_RESOLUTION_Y) // image strip
{
if (!linesLeft)
{
LCR_loadImage(8 + skyPart);
linesLeft = LCR_IMAGE_SIZE / 2;
skyPart++;
}
if (y >= 0)
{
for (int ix = 0; ix < 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
ix += LCR_SETTING_SKY_SIZE)
{
unsigned int color = LCR_getNextImagePixel();
int x = anchorPoint[0] + ix;
if (x >= 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE)
x -= 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
while (x < LCR_EFFECTIVE_RESOLUTION_X)
{
LCR_drawPixel(pixelIndex + x,color);
x += 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
}
}
pixelIndex += LCR_EFFECTIVE_RESOLUTION_X * LCR_SETTING_SKY_SIZE;
}
else
for (int ix = 0; ix < 2 * LCR_IMAGE_SIZE; ++ix)
LCR_getNextImagePixel();
linesLeft--;
y += LCR_SETTING_SKY_SIZE;
}
while (y < 0) // can still be the case
y = 0;
while (y < LCR_EFFECTIVE_RESOLUTION_Y) // bottom strip
{
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{
LCR_drawPixel(pixelIndex,bottomColor);
pixelIndex++;
}
y++;
}
} }
void LCR_rendererDraw(void) void LCR_rendererDraw(void)
{ {
_LCR_rendererPreviousTriangleID = -1; LCR_renderer.previousTriangleID = -1;
S3L_newFrame(); S3L_newFrame();
S3L_drawScene(LCR_scene3D);
}
void LCR_drawBackground(int verticalOffset) // REMOVE LATER
{ for (int i = 0; i < LCR_EFFECTIVE_RESOLUTION_X * LCR_EFFECTIVE_RESOLUTION_Y; ++i)
LCR_drawPixel(i,0xffff);
LCR_rendererDrawSky(0,
LCR_renderer.scene3D.camera.transform.rotation.y / 8,
-4 * LCR_renderer.scene3D.camera.transform.rotation.x);
for (int y = 0; y < LCR_EFFECTIVE_RESOLUTION_Y; ++y) S3L_drawScene(LCR_renderer.scene3D);
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
LCR_drawPixelXYUnsafe(x,y,0xffff);
}
void LCR_drawSkyStrip(int verticalOffset, uint8_t horizontalOffset)
{
#if LCR_SETTING_SKY_SIZE != 0
#endif
}
LCR_SpaceUnit LCR_rendererGetCameraYaw(void)
{
return (LCR_scene3D.camera.transform.rotation.y * LCR_SQUARE_SIDE_LEN) /
S3L_FRACTIONS_PER_UNIT;
}
LCR_SpaceUnit LCR_rendererGetCameraPitch(void)
{
return (LCR_scene3D.camera.transform.rotation.x * LCR_SQUARE_SIDE_LEN) /
S3L_FRACTIONS_PER_UNIT;
} }
#endif // guard #endif // guard

View file

@ -48,8 +48,7 @@
#ifndef LCR_SETTING_SKY_SIZE #ifndef LCR_SETTING_SKY_SIZE
/** Size of sky texture pixel, 0 turns off sky rendering. */ /** Size of sky texture pixel, 0 turns off sky rendering. */
#define LCR_SETTING_SKY_SIZE \ #define LCR_SETTING_SKY_SIZE 2
(LCR_SETTING_RESOLUTION_X / 256 * LCR_SETTING_RESOLUTION_SUBDIVIDE)
#endif #endif
#ifndef LCR_SETTING_MAP_MAX_SIZE #ifndef LCR_SETTING_MAP_MAX_SIZE