Optimize even more
This commit is contained in:
parent
880ae3c805
commit
5508d80944
1 changed files with 115 additions and 113 deletions
228
renderer.h
228
renderer.h
|
@ -21,12 +21,12 @@
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
S3L_Scene scene3D;
|
S3L_Scene scene;
|
||||||
S3L_Model3D models3D[3]; // TODO
|
S3L_Model3D models[3]; // TODO
|
||||||
|
|
||||||
S3L_Model3D *mapModel;
|
S3L_Model3D *mapModel;
|
||||||
S3L_Unit mapVertices[LCR_SETTING_MAX_MAP_VERTICES * 3];
|
S3L_Unit mapVerts[LCR_SETTING_MAX_MAP_VERTICES * 3];
|
||||||
S3L_Index mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
|
S3L_Index mapTris[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Additional data for triangles. 4 higher bits hold direction (for lighting):
|
Additional data for triangles. 4 higher bits hold direction (for lighting):
|
||||||
|
@ -36,21 +36,20 @@ struct
|
||||||
uint8_t mapTriangleData[LCR_SETTING_MAX_MAP_TRIANGLES];
|
uint8_t mapTriangleData[LCR_SETTING_MAX_MAP_TRIANGLES];
|
||||||
|
|
||||||
// pixel function precomputed values:
|
// pixel function precomputed values:
|
||||||
int previousTriangleID;
|
int previousTriID;
|
||||||
int triangleUVs[6];
|
int triUVs[6];
|
||||||
} LCR_renderer;
|
} LCR_renderer;
|
||||||
|
|
||||||
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_renderer.previousTriangleID)
|
if (pixel->triangleIndex != LCR_renderer.previousTriID)
|
||||||
{
|
{
|
||||||
S3L_Index *t = LCR_renderer.mapTriangles + 3 * pixel->triangleIndex;
|
S3L_Index *t = LCR_renderer.mapTris + 3 * pixel->triangleIndex;
|
||||||
|
|
||||||
S3L_Unit *v[3];
|
S3L_Unit *v[3];
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
v[i] = LCR_renderer.mapVertices + 3 * t[i];
|
v[i] = LCR_renderer.mapVerts + 3 * t[i];
|
||||||
|
|
||||||
uint8_t type = LCR_renderer.mapTriangleData[pixel->triangleID] >> 4;
|
uint8_t type = LCR_renderer.mapTriangleData[pixel->triangleID] >> 4;
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
|
||||||
LCR_imageChangeBrightness(1);
|
LCR_imageChangeBrightness(1);
|
||||||
|
|
||||||
for (int i = 0; i < 6; ++i)
|
for (int i = 0; i < 6; ++i)
|
||||||
LCR_renderer.triangleUVs[i] = ((
|
LCR_renderer.triUVs[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);
|
||||||
}
|
}
|
||||||
|
@ -73,38 +72,38 @@ void LCR_pixelFunc3D(S3L_PixelInfo *pixel)
|
||||||
|
|
||||||
for (int i = 0; i < 6; ++i)
|
for (int i = 0; i < 6; ++i)
|
||||||
{
|
{
|
||||||
LCR_renderer.triangleUVs[i] = ((
|
LCR_renderer.triUVs[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_renderer.triangleUVs[i] = LCR_IMAGE_SIZE -
|
LCR_renderer.triUVs[i] = LCR_IMAGE_SIZE -
|
||||||
LCR_renderer.triangleUVs[i];
|
LCR_renderer.triUVs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift the UVs to the origin (prevent high values of UV coords)
|
// shift the UVs to the origin (prevent high values of UV coords)
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
uint8_t minCoord = LCR_renderer.triangleUVs[i] <
|
uint8_t minCoord = LCR_renderer.triUVs[i] <
|
||||||
LCR_renderer.triangleUVs[2 + i] ? (0 + i) : (2 + i);
|
LCR_renderer.triUVs[2 + i] ? (0 + i) : (2 + i);
|
||||||
|
|
||||||
if (LCR_renderer.triangleUVs[4 + i] < LCR_renderer.triangleUVs[minCoord])
|
if (LCR_renderer.triUVs[4 + i] < LCR_renderer.triUVs[minCoord])
|
||||||
minCoord = 4 + i;
|
minCoord = 4 + i;
|
||||||
|
|
||||||
S3L_Unit shiftBy = LCR_renderer.triangleUVs[minCoord] % LCR_IMAGE_SIZE;
|
S3L_Unit shiftBy = LCR_renderer.triUVs[minCoord] % LCR_IMAGE_SIZE;
|
||||||
|
|
||||||
if (shiftBy < 0)
|
if (shiftBy < 0)
|
||||||
shiftBy += LCR_IMAGE_SIZE;
|
shiftBy += LCR_IMAGE_SIZE;
|
||||||
|
|
||||||
shiftBy -= LCR_renderer.triangleUVs[minCoord];
|
shiftBy -= LCR_renderer.triUVs[minCoord];
|
||||||
|
|
||||||
LCR_renderer.triangleUVs[i] += shiftBy;
|
LCR_renderer.triUVs[i] += shiftBy;
|
||||||
LCR_renderer.triangleUVs[2 + i] += shiftBy;
|
LCR_renderer.triUVs[2 + i] += shiftBy;
|
||||||
LCR_renderer.triangleUVs[4 + i] += shiftBy;
|
LCR_renderer.triUVs[4 + i] += shiftBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCR_renderer.previousTriangleID = pixel->triangleIndex;
|
LCR_renderer.previousTriID = pixel->triangleIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int barycentric[3];
|
int barycentric[3];
|
||||||
|
@ -114,39 +113,38 @@ 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_renderer.triangleUVs[0] +
|
(barycentric[0] * LCR_renderer.triUVs[0] +
|
||||||
barycentric[1] * LCR_renderer.triangleUVs[2] +
|
barycentric[1] * LCR_renderer.triUVs[2] +
|
||||||
barycentric[2] * LCR_renderer.triangleUVs[4])
|
barycentric[2] * LCR_renderer.triUVs[4])
|
||||||
/ (S3L_FRACTIONS_PER_UNIT / 8),
|
/ (S3L_FRACTIONS_PER_UNIT / 8),
|
||||||
(barycentric[0] * LCR_renderer.triangleUVs[1] +
|
(barycentric[0] * LCR_renderer.triUVs[1] +
|
||||||
barycentric[1] * LCR_renderer.triangleUVs[3] +
|
barycentric[1] * LCR_renderer.triUVs[3] +
|
||||||
barycentric[2] * LCR_renderer.triangleUVs[5])
|
barycentric[2] * LCR_renderer.triUVs[5])
|
||||||
/ (S3L_FRACTIONS_PER_UNIT / 8)
|
/ (S3L_FRACTIONS_PER_UNIT / 8));
|
||||||
);
|
|
||||||
|
|
||||||
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color);
|
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color);
|
||||||
}
|
}
|
||||||
|
|
||||||
S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
|
S3L_Index _LCR_addMapVert(S3L_Unit x, S3L_Unit y, S3L_Unit z)
|
||||||
{
|
{
|
||||||
S3L_Index index = 0;
|
S3L_Index index = 0;
|
||||||
S3L_Unit *vertices = LCR_renderer.mapVertices;
|
S3L_Unit *verts = LCR_renderer.mapVerts;
|
||||||
|
|
||||||
while (index < LCR_renderer.mapModel->vertexCount) // if exists, return vertex index
|
while (index < LCR_renderer.mapModel->vertexCount) // if exists, return index
|
||||||
{
|
{
|
||||||
if (vertices[0] == x && vertices[1] == y && vertices[2] == z)
|
if (verts[0] == x && verts[1] == y && verts[2] == z)
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
vertices += 3;
|
verts += 3;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it doesn't exist, add it
|
// if it doesn't exist, add it
|
||||||
if (LCR_renderer.mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES)
|
if (LCR_renderer.mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES)
|
||||||
{
|
{
|
||||||
*vertices = x; vertices++;
|
*verts = x; verts++;
|
||||||
*vertices = y; vertices++;
|
*verts = y; verts++;
|
||||||
*vertices = z;
|
*verts = z;
|
||||||
LCR_renderer.mapModel->vertexCount++;
|
LCR_renderer.mapModel->vertexCount++;
|
||||||
return LCR_renderer.mapModel->vertexCount - 1;
|
return LCR_renderer.mapModel->vertexCount - 1;
|
||||||
}
|
}
|
||||||
|
@ -156,12 +154,12 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat)
|
void _LCR_addMapTri(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat)
|
||||||
{
|
{
|
||||||
if (LCR_renderer.mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES)
|
if (LCR_renderer.mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES)
|
||||||
{
|
{
|
||||||
S3L_Index *t =
|
S3L_Index *t =
|
||||||
&(LCR_renderer.mapTriangles[LCR_renderer.mapModel->triangleCount * 3]);
|
&(LCR_renderer.mapTris[LCR_renderer.mapModel->triangleCount * 3]);
|
||||||
|
|
||||||
*t = a; t++;
|
*t = a; t++;
|
||||||
*t = b; t++;
|
*t = b; t++;
|
||||||
|
@ -174,12 +172,12 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c, uint8_t mat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _LCR_rendererSwapMapTriangles(unsigned int index1, unsigned int index2)
|
void _LCR_swapMapTris(unsigned int index1, unsigned int index2)
|
||||||
{
|
{
|
||||||
uint8_t tmpMat;
|
uint8_t tmpMat;
|
||||||
S3L_Index tmpIndex,
|
S3L_Index tmpIndex,
|
||||||
*t1 = LCR_renderer.mapTriangles + index1 * 3,
|
*t1 = LCR_renderer.mapTris + index1 * 3,
|
||||||
*t2 = LCR_renderer.mapTriangles + index2 * 3;
|
*t2 = LCR_renderer.mapTris + index2 * 3;
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
|
@ -189,12 +187,11 @@ void _LCR_rendererSwapMapTriangles(unsigned int index1, unsigned int index2)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpMat = LCR_renderer.mapTriangleData[index1];
|
tmpMat = LCR_renderer.mapTriangleData[index1];
|
||||||
LCR_renderer.mapTriangleData[index1] =
|
LCR_renderer.mapTriangleData[index1] = LCR_renderer.mapTriangleData[index2];
|
||||||
LCR_renderer.mapTriangleData[index2];
|
|
||||||
LCR_renderer.mapTriangleData[index2] = tmpMat;
|
LCR_renderer.mapTriangleData[index2] = tmpMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _LCR_quadCoversTriangle(const S3L_Unit quad[8], const S3L_Unit tri[6])
|
int _LCR_quadCoversTri(const S3L_Unit quad[8], const S3L_Unit tri[6])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; ++i) // for each triangle point
|
for (int i = 0; i < 3; ++i) // for each triangle point
|
||||||
{
|
{
|
||||||
|
@ -238,7 +235,7 @@ int _LCR_quadCoversTriangle(const S3L_Unit quad[8], const S3L_Unit tri[6])
|
||||||
other, in return values lowest bit means whether t1 is covered and the second
|
other, in return values lowest bit means whether t1 is covered and the second
|
||||||
lowest bit means whether t2 is covered.
|
lowest bit means whether t2 is covered.
|
||||||
*/
|
*/
|
||||||
uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
|
uint8_t _LCR_checkMapTriCover(const S3L_Index *t1,
|
||||||
const S3L_Index *t2)
|
const S3L_Index *t2)
|
||||||
{
|
{
|
||||||
if ((t1[0] == t2[0] || t1[0] == t2[1] || t1[0] == t2[2]) &&
|
if ((t1[0] == t2[0] || t1[0] == t2[1] || t1[0] == t2[2]) &&
|
||||||
|
@ -252,8 +249,8 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
vertices[i] = LCR_renderer.mapVertices + 3 * t1[i];
|
vertices[i] = LCR_renderer.mapVerts + 3 * t1[i];
|
||||||
vertices[3 + i] = LCR_renderer.mapVertices + 3 * t2[i];
|
vertices[3 + i] = LCR_renderer.mapVerts + 3 * t2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
|
@ -267,6 +264,12 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
|
||||||
|
|
||||||
if (plane >= 0) // both triangles in the same plane => then do more checks
|
if (plane >= 0) // both triangles in the same plane => then do more checks
|
||||||
{
|
{
|
||||||
|
if (S3L_abs(vertices[0][0] - vertices[3][0]) +
|
||||||
|
S3L_abs(vertices[0][1] - vertices[3][1]) +
|
||||||
|
S3L_abs(vertices[0][2] - vertices[3][2]) >
|
||||||
|
2 * LCR_RENDERER_UNIT)
|
||||||
|
return 0; // quick manhattan distance bailout condition
|
||||||
|
|
||||||
for (int j = 0; j < 2; ++j)
|
for (int j = 0; j < 2; ++j)
|
||||||
{
|
{
|
||||||
S3L_Unit points2D[14]; // tri1, quad (tri2 + 1 extra vert)
|
S3L_Unit points2D[14]; // tri1, quad (tri2 + 1 extra vert)
|
||||||
|
@ -286,13 +289,13 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
|
||||||
points2D[13] = (4 * points2D[7] + 3 * points2D[9] + points2D[11]) / 8;
|
points2D[13] = (4 * points2D[7] + 3 * points2D[9] + points2D[11]) / 8;
|
||||||
|
|
||||||
// first: does the triangle alone cover the other one?
|
// first: does the triangle alone cover the other one?
|
||||||
if (_LCR_quadCoversTriangle(points2D + 6,points2D))
|
if (_LCR_quadCoversTri(points2D + 6,points2D))
|
||||||
result |= 1 << j;
|
result |= 1 << j;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 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_renderer.mapTriangles;
|
S3L_Index *t3 = LCR_renderer.mapTris;
|
||||||
|
|
||||||
for (int i = 0; i < LCR_renderer.mapModel->triangleCount; ++i)
|
for (int i = 0; i < LCR_renderer.mapModel->triangleCount; ++i)
|
||||||
{
|
{
|
||||||
|
@ -304,12 +307,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_renderer.mapVertices[3 * t3[0] + plane] ==
|
LCR_renderer.mapVerts[3 * t3[0] + plane] ==
|
||||||
LCR_renderer.mapVertices[3 * t3[1] + plane] &&
|
LCR_renderer.mapVerts[3 * t3[1] + plane] &&
|
||||||
LCR_renderer.mapVertices[3 * t3[1] + plane] ==
|
LCR_renderer.mapVerts[3 * t3[1] + plane] ==
|
||||||
LCR_renderer.mapVertices[3 * t3[2] + plane] &&
|
LCR_renderer.mapVerts[3 * t3[2] + plane] &&
|
||||||
LCR_renderer.mapVertices[3 * t3[0] + plane] ==
|
LCR_renderer.mapVerts[3 * t3[0] + plane] ==
|
||||||
LCR_renderer.mapVertices[3 * t1[0] + plane]
|
LCR_renderer.mapVerts[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
|
||||||
|
@ -317,10 +320,10 @@ 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_renderer.mapVertices[3 * t3[freeVert] + coordX];
|
points2D[12] = LCR_renderer.mapVerts[3 * t3[freeVert] + coordX];
|
||||||
points2D[13] = LCR_renderer.mapVertices[3 * t3[freeVert] + coordY];
|
points2D[13] = LCR_renderer.mapVerts[3 * t3[freeVert] + coordY];
|
||||||
|
|
||||||
if (_LCR_quadCoversTriangle(points2D + 6,points2D))
|
if (_LCR_quadCoversTri(points2D + 6,points2D))
|
||||||
{
|
{
|
||||||
result |= 1 << j;
|
result |= 1 << j;
|
||||||
break;
|
break;
|
||||||
|
@ -354,14 +357,14 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1,
|
||||||
that by this become unused). This makes the map model smaller, faster and
|
that by this become unused). This makes the map model smaller, faster and
|
||||||
prevents bleeding through due to z-bugger imprecisions.
|
prevents bleeding through due to z-bugger imprecisions.
|
||||||
*/
|
*/
|
||||||
void _LCR_rendererCullHiddenMapTriangles(void)
|
void _LCR_cullHiddenMapTris(void)
|
||||||
{
|
{
|
||||||
LCR_log("culling invisible triangles");
|
LCR_log("culling invisible triangles");
|
||||||
|
|
||||||
int n = 0; // number of removed elements
|
int n = 0; // number of removed elements
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
S3L_Index *t1 = LCR_renderer.mapTriangles, *t2;
|
S3L_Index *t1 = LCR_renderer.mapTris, *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
|
||||||
|
@ -375,7 +378,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
|
|
||||||
for (int j = i + 1; j < LCR_renderer.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_checkMapTriCover(t1,t2);
|
||||||
|
|
||||||
t1Covered |= cover & 0x01;
|
t1Covered |= cover & 0x01;
|
||||||
|
|
||||||
|
@ -383,8 +386,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
{
|
{
|
||||||
if (j < LCR_renderer.mapModel->triangleCount - n)
|
if (j < LCR_renderer.mapModel->triangleCount - n)
|
||||||
{
|
{
|
||||||
|
_LCR_swapMapTris(j,
|
||||||
_LCR_rendererSwapMapTriangles(j,
|
|
||||||
LCR_renderer.mapModel->triangleCount - 1 - n);
|
LCR_renderer.mapModel->triangleCount - 1 - n);
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
|
@ -396,7 +398,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
|
|
||||||
if (t1Covered)
|
if (t1Covered)
|
||||||
{
|
{
|
||||||
_LCR_rendererSwapMapTriangles(i,
|
_LCR_swapMapTris(i,
|
||||||
LCR_renderer.mapModel->triangleCount - 1 - n);
|
LCR_renderer.mapModel->triangleCount - 1 - n);
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
|
@ -420,7 +422,7 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
int used = 0;
|
int used = 0;
|
||||||
|
|
||||||
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
|
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
|
||||||
if (LCR_renderer.mapTriangles[j] == i)
|
if (LCR_renderer.mapTris[j] == i)
|
||||||
{
|
{
|
||||||
used = 1;
|
used = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -431,12 +433,12 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; ++j)
|
for (int j = 0; j < 3; ++j)
|
||||||
LCR_renderer.mapVertices[3 * i + j] =
|
LCR_renderer.mapVerts[3 * i + j] =
|
||||||
LCR_renderer.mapVertices[(LCR_renderer.mapModel->vertexCount - 1) * 3 + j];
|
LCR_renderer.mapVerts[(LCR_renderer.mapModel->vertexCount - 1) * 3 + j];
|
||||||
|
|
||||||
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
|
for (int j = 0; j < LCR_renderer.mapModel->triangleCount * 3; ++j)
|
||||||
if (LCR_renderer.mapTriangles[j] == LCR_renderer.mapModel->vertexCount - 1)
|
if (LCR_renderer.mapTris[j] == LCR_renderer.mapModel->vertexCount - 1)
|
||||||
LCR_renderer.mapTriangles[j] = i;
|
LCR_renderer.mapTris[j] = i;
|
||||||
|
|
||||||
LCR_renderer.mapModel->vertexCount--;
|
LCR_renderer.mapModel->vertexCount--;
|
||||||
}
|
}
|
||||||
|
@ -447,22 +449,22 @@ void _LCR_rendererCullHiddenMapTriangles(void)
|
||||||
Builds the internal 3D model of the currently loaded map. Returns 1 on
|
Builds the internal 3D model of the currently loaded map. Returns 1 on
|
||||||
success, 0 otherwise (e.g. not enough space).
|
success, 0 otherwise (e.g. not enough space).
|
||||||
*/
|
*/
|
||||||
uint8_t _LCR_rendererBuildMapModel(void)
|
uint8_t _LCR_buildMapModel(void)
|
||||||
{
|
{
|
||||||
LCR_log("building map model");
|
LCR_log("building map model");
|
||||||
|
|
||||||
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_renderer.mapVertices,0,LCR_renderer.mapTriangles,0,LCR_renderer.mapModel);
|
S3L_model3DInit(LCR_renderer.mapVerts,0,LCR_renderer.mapTris,0,LCR_renderer.mapModel);
|
||||||
|
|
||||||
for (int j = 0; j < LCR_currentMap.blockCount; ++j)
|
for (int j = 0; j < LCR_currentMap.blockCount; ++j)
|
||||||
{
|
{
|
||||||
if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0)
|
if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0)
|
||||||
_LCR_rendererCullHiddenMapTriangles();
|
_LCR_cullHiddenMapTris();
|
||||||
|
|
||||||
S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT;
|
S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT;
|
||||||
S3L_Index triangleIndices[3];
|
S3L_Index triIndices[3];
|
||||||
const uint8_t *block = LCR_currentMap.blocks + j * LCR_BLOCK_SIZE;
|
const uint8_t *block = LCR_currentMap.blocks + j * LCR_BLOCK_SIZE;
|
||||||
uint8_t
|
uint8_t
|
||||||
blockType = block[0],
|
blockType = block[0],
|
||||||
|
@ -492,7 +494,7 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
((vx == 0) << 2) | ((vx == LCR_BLOCK_SHAPE_COORD_MAX) << 3) |
|
((vx == 0) << 2) | ((vx == LCR_BLOCK_SHAPE_COORD_MAX) << 3) |
|
||||||
((vz == 0) << 4) | ((vz == LCR_BLOCK_SHAPE_COORD_MAX) << 5);
|
((vz == 0) << 4) | ((vz == LCR_BLOCK_SHAPE_COORD_MAX) << 5);
|
||||||
|
|
||||||
triangleIndices[vi] = _LCR_addMapVertex(
|
triIndices[vi] = _LCR_addMapVert(
|
||||||
originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) +
|
originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) +
|
||||||
(LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / LCR_BLOCK_SHAPE_COORD_MAX,
|
(LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / LCR_BLOCK_SHAPE_COORD_MAX,
|
||||||
(originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 +
|
(originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 +
|
||||||
|
@ -507,18 +509,18 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
// don't add triangles completely at the floor or ceiling of the map
|
// don't add triangles completely at the floor or ceiling of the map
|
||||||
if (!edgeBits)
|
if (!edgeBits)
|
||||||
{
|
{
|
||||||
#define VERT(n,c) LCR_renderer.mapVertices[3 * n + c]
|
#define VERT(n,c) LCR_renderer.mapVerts[3 * n + c]
|
||||||
uint8_t blockMat = LCR_mapBlockGetMaterial(block);
|
uint8_t blockMat = LCR_mapBlockGetMaterial(block);
|
||||||
uint8_t triangleData =
|
uint8_t triData =
|
||||||
(((VERT(triangleIndices[0],0) == VERT(triangleIndices[1],0)) &&
|
(((VERT(triIndices[0],0) == VERT(triIndices[1],0)) &&
|
||||||
(VERT(triangleIndices[1],0) == VERT(triangleIndices[2],0))) << 4) |
|
(VERT(triIndices[1],0) == VERT(triIndices[2],0))) << 4) |
|
||||||
(((VERT(triangleIndices[0],2) == VERT(triangleIndices[1],2)) &&
|
(((VERT(triIndices[0],2) == VERT(triIndices[1],2)) &&
|
||||||
(VERT(triangleIndices[1],2) == VERT(triangleIndices[2],2))) << 5);
|
(VERT(triIndices[1],2) == VERT(triIndices[2],2))) << 5);
|
||||||
#undef VERT
|
#undef VERT
|
||||||
|
|
||||||
if (triangleData & 0xf0) // wall?
|
if (triData & 0xf0) // wall?
|
||||||
{
|
{
|
||||||
triangleData |=
|
triData |=
|
||||||
((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) ||
|
((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) ||
|
||||||
(blockMat == LCR_BLOCK_MATERIAL_ICE) ||
|
(blockMat == LCR_BLOCK_MATERIAL_ICE) ||
|
||||||
(blockType == LCR_BLOCK_FULL_ACCEL) ||
|
(blockType == LCR_BLOCK_FULL_ACCEL) ||
|
||||||
|
@ -528,26 +530,26 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
else
|
else
|
||||||
{ // TODO: tidy this mess?
|
{ // TODO: tidy this mess?
|
||||||
if (blockType == LCR_BLOCK_FULL_ACCEL)
|
if (blockType == LCR_BLOCK_FULL_ACCEL)
|
||||||
triangleData |= LCR_IMAGE_GROUND_ACCEL;
|
triData |= LCR_IMAGE_GROUND_ACCEL;
|
||||||
else if (blockType == LCR_BLOCK_FULL_STICKER)
|
else if (blockType == LCR_BLOCK_FULL_STICKER)
|
||||||
triangleData |= LCR_IMAGE_GROUND_STICKER;
|
triData |= LCR_IMAGE_GROUND_STICKER;
|
||||||
else
|
else
|
||||||
switch (blockMat)
|
switch (blockMat)
|
||||||
{
|
{
|
||||||
case LCR_BLOCK_MATERIAL_CONCRETE:
|
case LCR_BLOCK_MATERIAL_CONCRETE:
|
||||||
triangleData |= LCR_IMAGE_GROUND_CONCRETE;
|
triData |= LCR_IMAGE_GROUND_CONCRETE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LCR_BLOCK_MATERIAL_GRASS:
|
case LCR_BLOCK_MATERIAL_GRASS:
|
||||||
triangleData |= LCR_IMAGE_GROUND_GRASS;
|
triData |= LCR_IMAGE_GROUND_GRASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LCR_BLOCK_MATERIAL_DIRT:
|
case LCR_BLOCK_MATERIAL_DIRT:
|
||||||
triangleData |= LCR_IMAGE_GROUND_DIRT;
|
triData |= LCR_IMAGE_GROUND_DIRT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LCR_BLOCK_MATERIAL_ICE:
|
case LCR_BLOCK_MATERIAL_ICE:
|
||||||
triangleData |= LCR_IMAGE_GROUND_ICE;
|
triData |= LCR_IMAGE_GROUND_ICE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -555,10 +557,8 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_LCR_addMapTriangle(
|
_LCR_addMapTri(triIndices[0],triIndices[1],triIndices[2],triData);
|
||||||
triangleIndices[0],triangleIndices[1],triangleIndices[2],
|
}
|
||||||
triangleData);
|
|
||||||
}
|
|
||||||
|
|
||||||
vi = 0;
|
vi = 0;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,9 @@ uint8_t _LCR_rendererBuildMapModel(void)
|
||||||
|
|
||||||
// TODO: also cull the triangles in the loop by some N steps
|
// TODO: also cull the triangles in the loop by some N steps
|
||||||
|
|
||||||
_LCR_rendererCullHiddenMapTriangles();
|
_LCR_cullHiddenMapTris();
|
||||||
|
|
||||||
|
LCR_log("map model built");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -576,12 +578,12 @@ uint8_t LCR_rendererInit(void)
|
||||||
{
|
{
|
||||||
LCR_log("initializing renderer");
|
LCR_log("initializing renderer");
|
||||||
|
|
||||||
LCR_renderer.mapModel = LCR_renderer.models3D;
|
LCR_renderer.mapModel = LCR_renderer.models;
|
||||||
|
|
||||||
if (!_LCR_rendererBuildMapModel())
|
if (!_LCR_buildMapModel())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
S3L_sceneInit(LCR_renderer.models3D,1,&LCR_renderer.scene3D);
|
S3L_sceneInit(LCR_renderer.models,1,&LCR_renderer.scene);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -591,32 +593,32 @@ void LCR_rendererMoveCamera(LCR_SpaceUnit forwRightUpOffset[3],
|
||||||
{
|
{
|
||||||
S3L_Vec4 f, r, u;
|
S3L_Vec4 f, r, u;
|
||||||
|
|
||||||
S3L_rotationToDirections(LCR_renderer.scene3D.camera.transform.rotation,
|
S3L_rotationToDirections(LCR_renderer.scene.camera.transform.rotation,
|
||||||
S3L_FRACTIONS_PER_UNIT,&f,&r,&u);
|
S3L_FRACTIONS_PER_UNIT,&f,&r,&u);
|
||||||
|
|
||||||
LCR_renderer.scene3D.camera.transform.translation.x +=
|
LCR_renderer.scene.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_renderer.scene3D.camera.transform.translation.y +=
|
LCR_renderer.scene.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_renderer.scene3D.camera.transform.translation.z +=
|
LCR_renderer.scene.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_renderer.scene3D.camera.transform.rotation.y +=
|
LCR_renderer.scene.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_renderer.scene3D.camera.transform.rotation.x +=
|
LCR_renderer.scene.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_renderer.scene3D.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4)
|
if (LCR_renderer.scene.camera.transform.rotation.x > S3L_FRACTIONS_PER_UNIT / 4)
|
||||||
LCR_renderer.scene3D.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4;
|
LCR_renderer.scene.camera.transform.rotation.x = S3L_FRACTIONS_PER_UNIT / 4;
|
||||||
|
|
||||||
if (LCR_renderer.scene3D.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4)
|
if (LCR_renderer.scene.camera.transform.rotation.x < -1 * S3L_FRACTIONS_PER_UNIT / 4)
|
||||||
LCR_renderer.scene3D.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4;
|
LCR_renderer.scene.camera.transform.rotation.x = -1 * S3L_FRACTIONS_PER_UNIT / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -749,14 +751,14 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
|
||||||
|
|
||||||
void LCR_rendererDraw(void)
|
void LCR_rendererDraw(void)
|
||||||
{
|
{
|
||||||
LCR_renderer.previousTriangleID = -1;
|
LCR_renderer.previousTriID = -1;
|
||||||
S3L_newFrame();
|
S3L_newFrame();
|
||||||
|
|
||||||
LCR_rendererDrawSky(2,
|
LCR_rendererDrawSky(2,
|
||||||
LCR_renderer.scene3D.camera.transform.rotation.y,
|
LCR_renderer.scene.camera.transform.rotation.y,
|
||||||
-4 * LCR_renderer.scene3D.camera.transform.rotation.x);
|
-4 * LCR_renderer.scene.camera.transform.rotation.x);
|
||||||
|
|
||||||
S3L_drawScene(LCR_renderer.scene3D);
|
S3L_drawScene(LCR_renderer.scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
Loading…
Reference in a new issue