|
|
@ -30,6 +30,13 @@ struct triangle |
|
|
|
Pixel col; |
|
|
|
Pixel col; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct MapSquare { |
|
|
|
|
|
|
|
Decal*wallN=NULL; |
|
|
|
|
|
|
|
Decal* wallE=NULL; |
|
|
|
|
|
|
|
Decal* wallS=NULL; |
|
|
|
|
|
|
|
Decal* wallW=NULL; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct mesh |
|
|
|
struct mesh |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::vector<triangle> tris; |
|
|
|
std::vector<triangle> tris; |
|
|
@ -96,23 +103,23 @@ struct mat4x4 |
|
|
|
float m[4][4] = { 0 }; |
|
|
|
float m[4][4] = { 0 }; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class olcEngine3D : public PixelGameEngine |
|
|
|
class FaceBall : public PixelGameEngine |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
Decal* texture; |
|
|
|
bool freeRoam=false; |
|
|
|
olcEngine3D() |
|
|
|
FaceBall() |
|
|
|
{ |
|
|
|
{ |
|
|
|
sAppName = "3D Demo"; |
|
|
|
sAppName = "3D Demo"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
mesh meshCube; |
|
|
|
mesh mapMesh; |
|
|
|
mat4x4 matProj; |
|
|
|
mat4x4 matProj; |
|
|
|
|
|
|
|
|
|
|
|
vec3d vCamera = { 0,0,0 }; |
|
|
|
vec3d vCamera = { 5,5,5 }; |
|
|
|
vec3d vLookDir; |
|
|
|
vec3d vLookDir; |
|
|
|
|
|
|
|
|
|
|
|
float zOffset = 2; |
|
|
|
float zOffset = 2; |
|
|
@ -438,47 +445,14 @@ private: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RenderWorld() { |
|
|
|
public: |
|
|
|
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
texture = new Decal(new Sprite("High.png")); |
|
|
|
|
|
|
|
meshCube.LoadFromObjectFile("Artisans Hub.obj"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matProj = Matrix_MakeProjection(90.0f, (float)ScreenHeight() / (float)ScreenWidth(), 0.1f, 1000.0f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (GetKey(olc::DOWN).bHeld) { |
|
|
|
|
|
|
|
pitch -= 1 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::UP).bHeld) { |
|
|
|
|
|
|
|
pitch += 1 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
vec3d vForward = Vector_Mul(vLookDir, 20 * fElapsedTime); |
|
|
|
|
|
|
|
if (GetKey(olc::W).bHeld) { |
|
|
|
|
|
|
|
vCamera = Vector_Add(vCamera, vForward); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::S).bHeld) { |
|
|
|
|
|
|
|
vCamera = Vector_Sub(vCamera, vForward); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::A).bHeld) { |
|
|
|
|
|
|
|
fYaw -= 2 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::D).bHeld) { |
|
|
|
|
|
|
|
fYaw += 2 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set up rotation matrices
|
|
|
|
// Set up rotation matrices
|
|
|
|
mat4x4 matRotZ, matRotX, matTrans, matWorld; |
|
|
|
mat4x4 matRotZ, matRotX, matTrans, matWorld; |
|
|
|
|
|
|
|
|
|
|
|
matRotZ = Matrix_MakeRotationZ(fTheta * 0.5f); |
|
|
|
matRotZ = Matrix_MakeRotationZ(fTheta * 0.5f); |
|
|
|
matRotX = Matrix_MakeRotationX(fTheta); |
|
|
|
matRotX = Matrix_MakeRotationX(fTheta); |
|
|
|
|
|
|
|
|
|
|
|
matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 5.0f); |
|
|
|
matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f); |
|
|
|
matWorld = Matrix_MakeIdentity(); |
|
|
|
matWorld = Matrix_MakeIdentity(); |
|
|
|
matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX); |
|
|
|
matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX); |
|
|
|
matWorld = Matrix_MultiplyMatrix(matWorld, matTrans); |
|
|
|
matWorld = Matrix_MultiplyMatrix(matWorld, matTrans); |
|
|
@ -494,7 +468,7 @@ public: |
|
|
|
std::vector<triangle>vecTrianglesToRaster; |
|
|
|
std::vector<triangle>vecTrianglesToRaster; |
|
|
|
|
|
|
|
|
|
|
|
// Draw Triangles
|
|
|
|
// Draw Triangles
|
|
|
|
for (auto& tri : meshCube.tris) |
|
|
|
for (auto& tri : mapMesh.tris) |
|
|
|
{ |
|
|
|
{ |
|
|
|
triangle triProjected, triTransformed, triViewed; |
|
|
|
triangle triProjected, triTransformed, triViewed; |
|
|
|
|
|
|
|
|
|
|
@ -504,6 +478,7 @@ public: |
|
|
|
triTransformed.uv[0] = tri.uv[0]; |
|
|
|
triTransformed.uv[0] = tri.uv[0]; |
|
|
|
triTransformed.uv[1] = tri.uv[1]; |
|
|
|
triTransformed.uv[1] = tri.uv[1]; |
|
|
|
triTransformed.uv[2] = tri.uv[2]; |
|
|
|
triTransformed.uv[2] = tri.uv[2]; |
|
|
|
|
|
|
|
triTransformed.col = tri.col; |
|
|
|
|
|
|
|
|
|
|
|
vec3d normal, line1, line2; |
|
|
|
vec3d normal, line1, line2; |
|
|
|
line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); |
|
|
|
line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); |
|
|
@ -526,7 +501,7 @@ public: |
|
|
|
triViewed.uv[0] = triTransformed.uv[0]; |
|
|
|
triViewed.uv[0] = triTransformed.uv[0]; |
|
|
|
triViewed.uv[1] = triTransformed.uv[1]; |
|
|
|
triViewed.uv[1] = triTransformed.uv[1]; |
|
|
|
triViewed.uv[2] = triTransformed.uv[2]; |
|
|
|
triViewed.uv[2] = triTransformed.uv[2]; |
|
|
|
triViewed.col = Pixel(255 * dp * dp, 255 * dp * dp, 255 * dp * dp); |
|
|
|
triViewed.col = Pixel(triTransformed.col.r * dp * dp, triTransformed.col.g * dp * dp, triTransformed.col.b * dp * dp); |
|
|
|
|
|
|
|
|
|
|
|
int nClippedTriangles = 0; |
|
|
|
int nClippedTriangles = 0; |
|
|
|
triangle clipped[2]; |
|
|
|
triangle clipped[2]; |
|
|
@ -628,7 +603,7 @@ public: |
|
|
|
// Rasterize triangle
|
|
|
|
// Rasterize triangle
|
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
DrawPolygonDecal(texture, { |
|
|
|
DrawPolygonDecal(mapMesh.texture, { |
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
@ -637,7 +612,7 @@ public: |
|
|
|
{t.uv[1].u,t.uv[1].v}, |
|
|
|
{t.uv[1].u,t.uv[1].v}, |
|
|
|
{t.uv[2].u,t.uv[2].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,t.col,t.col }); |
|
|
|
}, { 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,t.col,t.col }); |
|
|
|
/*SetDecalMode(DecalMode::WIREFRAME);
|
|
|
|
SetDecalMode(DecalMode::WIREFRAME); |
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
@ -646,7 +621,7 @@ public: |
|
|
|
{0,0}, |
|
|
|
{0,0}, |
|
|
|
{0,0}, |
|
|
|
{0,0}, |
|
|
|
{0,0}, |
|
|
|
{0,0}, |
|
|
|
},WHITE);*/ |
|
|
|
},WHITE); |
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
triRenderCount++; |
|
|
|
triRenderCount++; |
|
|
|
} |
|
|
|
} |
|
|
@ -654,8 +629,66 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
DrawStringDecal({ 0,0 }, "Triangles: " + std::to_string(triRenderCount), WHITE, { 2,2 }); |
|
|
|
DrawStringDecal({ 0,0 }, "Triangles: " + std::to_string(triRenderCount), WHITE, { 2,2 }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HandleKeys(float fElapsedTime) { |
|
|
|
|
|
|
|
vec3d vForward = Vector_Mul(vLookDir, 20 * fElapsedTime); |
|
|
|
|
|
|
|
if (freeRoam) { |
|
|
|
|
|
|
|
if (GetKey(olc::DOWN).bHeld) { |
|
|
|
|
|
|
|
pitch -= 1 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::UP).bHeld) { |
|
|
|
|
|
|
|
pitch += 1 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
pitch = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::W).bHeld) { |
|
|
|
|
|
|
|
vCamera = Vector_Add(vCamera, vForward); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::S).bHeld) { |
|
|
|
|
|
|
|
vCamera = Vector_Sub(vCamera, vForward); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::A).bHeld) { |
|
|
|
|
|
|
|
fYaw -= 2 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::D).bHeld) { |
|
|
|
|
|
|
|
fYaw += 2 * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::F1).bPressed) { |
|
|
|
|
|
|
|
freeRoam = !freeRoam; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vi2d MAP_SIZE = { 10,2 }; |
|
|
|
|
|
|
|
std::vector<std::vector<MapSquare>>map; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
matProj = Matrix_MakeProjection(90.0f, (float)ScreenHeight() / (float)ScreenWidth(), 0.1f, 1000.0f); |
|
|
|
|
|
|
|
Decal* dot = new Decal(new Sprite("dot.png")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapMesh.texture = dot; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MAP_SIZE.y; i++) { |
|
|
|
|
|
|
|
std::vector<MapSquare>row; |
|
|
|
|
|
|
|
for (int j = 0; j < MAP_SIZE.x; j++) { |
|
|
|
|
|
|
|
row.push_back({}); |
|
|
|
|
|
|
|
mapMesh.tris.push_back({ {{(float)j * 10,0,(float)i * 10},{(float)j * 10,0,(float)i * 10 + 10},{(float)j * 10 + 10,0,(float)i * 10}},{{0,0},{1,0},{0,1}},Pixel{uint8_t(rand() * 255),uint8_t(rand() * 255),uint8_t(rand() * 255)} }); |
|
|
|
|
|
|
|
mapMesh.tris.push_back({ {{(float)j * 10+10,0,(float)i * 10},{(float)j * 10,0,(float)i * 10 + 10},{(float)j * 10 + 10,0,(float)i * 10+10}},{{0,0},{1,0},{0,1}},Pixel{uint8_t(rand() * 255),uint8_t(rand() * 255),uint8_t(rand() * 255)} }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
map.push_back(row); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
HandleKeys(fElapsedTime); |
|
|
|
|
|
|
|
RenderWorld(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -666,7 +699,7 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
int main() |
|
|
|
{ |
|
|
|
{ |
|
|
|
olcEngine3D demo; |
|
|
|
FaceBall demo; |
|
|
|
if (demo.Construct(1280, 720, 1, 1)) |
|
|
|
if (demo.Construct(1280, 720, 1, 1)) |
|
|
|
demo.Start(); |
|
|
|
demo.Start(); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|