|
|
|
@ -169,32 +169,40 @@ void FaceBall::LoadLevel(int level) |
|
|
|
|
if (vi2d{ x,y } == vi2d{exitCoords.x, exitCoords.y + 1}) { |
|
|
|
|
exitWallTex = exit_wall_tex; |
|
|
|
|
} |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{0,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,0,(float)y},{(float)x + 1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,1},{1,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
if (vi2d{x,y} != exitCoords) { |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{0,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,0,(float)y},{(float)x + 1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,1},{1,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallS != NULL) { |
|
|
|
|
Decal* exitWallTex = wall_tex; |
|
|
|
|
if (vi2d{ x,y } == vi2d{ exitCoords.x, exitCoords.y - 1 }) { |
|
|
|
|
exitWallTex = exit_wall_tex; |
|
|
|
|
} |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x,0,(float)y + 1},{(float)x,1,(float)y + 1}},{{0,0},{1,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x + 1,0,(float)y + 1},{(float)x,0,(float)y + 1}},{{0,0},{0,1},{1,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
if (vi2d{ x,y } != exitCoords) { |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x,0,(float)y + 1},{(float)x,1,(float)y + 1}},{{0,0},{1,1},{1,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x + 1,0,(float)y + 1},{(float)x,0,(float)y + 1}},{{0,0},{0,1},{1,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallW != NULL) { |
|
|
|
|
Decal* exitWallTex = wall_tex; |
|
|
|
|
if (vi2d{ x,y } == vi2d{ exitCoords.x+1, exitCoords.y }) { |
|
|
|
|
exitWallTex = exit_wall_tex; |
|
|
|
|
} |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y + 1}, {(float)x,0,(float)y + 1}},{{1,0},{0,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{1,1},{1,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
if (vi2d{ x,y } != exitCoords) { |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y + 1}, {(float)x,0,(float)y + 1}},{{1,0},{0,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{1,1},{1,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallE != NULL) { |
|
|
|
|
Decal* exitWallTex = wall_tex; |
|
|
|
|
if (vi2d{ x,y } == vi2d{ exitCoords.x - 1, exitCoords.y }) { |
|
|
|
|
exitWallTex = exit_wall_tex; |
|
|
|
|
} |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x + 1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{1,1},{1,0},{0,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x + 1,1,(float)y},{(float)x + 1,0,(float)y}},{{1,1},{0,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
if (vi2d{ x,y } != exitCoords) { |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x + 1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{1,1},{1,0},{0,0}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
mapWalls.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x + 1,1,(float)y},{(float)x + 1,0,(float)y}},{{1,1},{0,0},{0,1}},{WHITE,WHITE,WHITE}, exitWallTex }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -589,17 +597,18 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::RenderBulletMesh(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Bullet& b) { |
|
|
|
|
void FaceBall::RenderBulletMesh(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Bullet& b,bool translucent) { |
|
|
|
|
for (auto& tri : b.mesh.tris) { |
|
|
|
|
tri.col[0] = b.col; |
|
|
|
|
tri.col[1] = b.col; |
|
|
|
|
tri.col[2] = b.col; |
|
|
|
|
} |
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, b); |
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, b,translucent); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::RenderMesh(mat4x4&matView,std::vector<Triangle>&vecTrianglesToRaster, Object&o) { |
|
|
|
|
void FaceBall::RenderMesh(mat4x4&matView,std::vector<Triangle>&vecTrianglesToRaster, Object&o,bool translucent) { |
|
|
|
|
for (auto& tri : o.mesh.tris) { |
|
|
|
|
if (translucent&&tri.tex != exit_wall_tex && tri.tex != bullet_tex ||!translucent&&(tri.tex==exit_wall_tex || tri.tex == bullet_tex)) { continue; } |
|
|
|
|
Triangle triProjected, triTransformed, triViewed; |
|
|
|
|
mat4x4 localMat = Matrix_MakeIdentity(); |
|
|
|
|
mat4x4 rotMat = Matrix_MakeRotationY(o.rot); |
|
|
|
@ -876,6 +885,7 @@ void FaceBall::RenderWorld() { |
|
|
|
|
mat4x4 matView = Matrix_QuickInverse(matCamera); |
|
|
|
|
|
|
|
|
|
std::vector<Triangle>vecTrianglesToRaster; |
|
|
|
|
std::vector<Triangle>vecTrianglesToRasterTranslucent; |
|
|
|
|
|
|
|
|
|
// Draw Triangles
|
|
|
|
|
for (auto& obj : objects) { |
|
|
|
@ -885,13 +895,14 @@ void FaceBall::RenderWorld() { |
|
|
|
|
for (Triangle& t : exit.mesh.tris) { |
|
|
|
|
t.col[0] = t.col[1] = t.col[2] = {0,(uint8_t)(std::abs(std::sinf(2*PI*gameTimer)) * 255),0}; |
|
|
|
|
} |
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, walls); |
|
|
|
|
for (auto& enemy : enemies) { |
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, enemy); |
|
|
|
|
} |
|
|
|
|
for (auto& bullet : bullets) { |
|
|
|
|
RenderBulletMesh(matView, vecTrianglesToRaster, bullet); |
|
|
|
|
RenderBulletMesh(matView, vecTrianglesToRasterTranslucent, bullet); |
|
|
|
|
} |
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, walls); |
|
|
|
|
RenderMesh(matView, vecTrianglesToRasterTranslucent, walls, true); |
|
|
|
|
|
|
|
|
|
//std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;});
|
|
|
|
|
ClearBuffer(BLACK, true); |
|
|
|
@ -961,6 +972,72 @@ void FaceBall::RenderWorld() { |
|
|
|
|
triRenderCount++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
std::sort(vecTrianglesToRasterTranslucent.begin(), vecTrianglesToRasterTranslucent.end(), [](Triangle& t1, Triangle& t2) {return (t1.p[0].z + t1.p[1].z + t1.p[2].z) / 3.0f > (t2.p[0].z + t2.p[1].z + t2.p[2].z) / 3.0f; }); |
|
|
|
|
for (auto& triToRaster : vecTrianglesToRasterTranslucent) { |
|
|
|
|
Triangle clipped[2]; |
|
|
|
|
std::list<Triangle>listTriangles; |
|
|
|
|
listTriangles.push_back(triToRaster); |
|
|
|
|
int nNewTriangles = 1; |
|
|
|
|
|
|
|
|
|
for (int p = 0; p < 4; p++) |
|
|
|
|
{ |
|
|
|
|
int nTrisToAdd = 0; |
|
|
|
|
while (nNewTriangles > 0) |
|
|
|
|
{ |
|
|
|
|
// Take triangle from front of queue
|
|
|
|
|
Triangle test = listTriangles.front(); |
|
|
|
|
listTriangles.pop_front(); |
|
|
|
|
nNewTriangles--; |
|
|
|
|
|
|
|
|
|
// Clip it against a plane. We only need to test each
|
|
|
|
|
// subsequent plane, against subsequent new triangles
|
|
|
|
|
// as all triangles after a plane clip are guaranteed
|
|
|
|
|
// to lie on the inside of the plane. I like how this
|
|
|
|
|
// comment is almost completely and utterly justified
|
|
|
|
|
switch (p) |
|
|
|
|
{ |
|
|
|
|
case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Clipping may yield a variable number of triangles, so
|
|
|
|
|
// add these new ones to the back of the queue for subsequent
|
|
|
|
|
// clipping against next planes
|
|
|
|
|
for (int w = 0; w < nTrisToAdd; w++) |
|
|
|
|
listTriangles.push_back(clipped[w]); |
|
|
|
|
} |
|
|
|
|
nNewTriangles = listTriangles.size(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (auto& t : listTriangles) { |
|
|
|
|
// Rasterize triangle
|
|
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
|
DrawPolygonDecal(t.tex, { |
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
}, { |
|
|
|
|
{t.uv[0].u,t.uv[0].v}, |
|
|
|
|
{t.uv[1].u,t.uv[1].v}, |
|
|
|
|
{t.uv[2].u,t.uv[2].v}, |
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col[0],t.col[1],t.col[2] }); |
|
|
|
|
/*SetDecalMode(DecalMode::WIREFRAME);
|
|
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
},{ |
|
|
|
|
{0,0}, |
|
|
|
|
{0,0}, |
|
|
|
|
{0,0}, |
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/ |
|
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
|
triRenderCount++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::HandleKeys(float fElapsedTime) { |
|
|
|
|