Include sorting of triangles

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent b9bb57d67a
commit 16c7a314dc
  1. BIN
      Body.png
  2. BIN
      C++ProjectTemplate
  3. BIN
      Image_6.png
  4. 20099
      Nia.obj
  5. 177
      main.cpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 KiB

20099
Nia.obj

File diff suppressed because it is too large Load Diff

@ -1,8 +1,15 @@
#define OLC_PGE_APPLICATION
#include "pixelGameEngine.h"
#include <strstream>
#include <algorithm>
using namespace olc;
struct vec2d
{
float u,v;
};
struct vec3d
{
@ -12,11 +19,80 @@ struct vec3d
struct triangle
{
vec3d p[3];
vec2d uv[3];
Pixel col;
};
struct mesh
{
std::vector<triangle> tris;
bool LoadFromObjectFile(std::string sFilename)
{
std::ifstream f(sFilename);
if (!f.is_open())
return false;
// Local cache of verts
std::vector<vec3d> verts;
std::vector<vec2d> uvs;
while (!f.eof())
{
char line[128];
f.getline(line, 128);
std::strstream s;
s << line;
char junk;
if (line[0] == 'v')
{
if (line[1]=='t') {
vec2d v;
s >> junk >> junk >> v.u >> v.v;
uvs.push_back(v);
//std::cout<<"Line: "<<line<<"\n";
//std::cout<<"Tex coords: "<<v.u<<","<<v.v<<"\n";
} else
if (line[1] != 'n')
{
vec3d v;
s >> junk >> v.x >> v.y >> v.z;
verts.push_back(v);
//std::cout<<"Line: "<<line<<"\n";
//std::cout<<"Vertex: "<<v.x<<","<<v.y<<","<<v.z<<"\n";
}
}
if (line[0] == 'f')
{
s >> junk;
std::string tokens[9];
int nTokenCount = -1;
while (!s.eof())
{
char c = s.get();
if (c == ' ' || c == '/')
nTokenCount++;
else
tokens[nTokenCount].append(1, c);
}
tokens[nTokenCount].pop_back();
tris.push_back({ verts[stoi(tokens[0]) - 1], verts[stoi(tokens[3]) - 1], verts[stoi(tokens[6]) - 1],
0,0,0
/*uvs[stoi(tokens[1]) - 1], uvs[stoi(tokens[4]) - 1], uvs[stoi(tokens[7]) - 1]*/});
}
}
return true;
}
};
struct mat4x4
@ -26,7 +102,10 @@ struct mat4x4
class olcEngine3D : public PixelGameEngine
{
public:
Decal*texture;
olcEngine3D()
{
sAppName = "3D Demo";
@ -39,6 +118,8 @@ private:
vec3d vCamera={0,0,0};
float zOffset=2;
float fTheta=0;
void MultiplyMatrixVector(vec3d &i, vec3d &o, mat4x4 &m)
@ -57,33 +138,8 @@ private:
public:
bool OnUserCreate() override
{
meshCube.tris = {
// SOUTH
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f },
// EAST
{ 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f },
{ 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
// NORTH
{ 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f },
{ 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f },
// WEST
{ 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
// TOP
{ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
{ 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f },
// BOTTOM
{ 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
};
texture = new Decal(new Sprite("Body.png"));
meshCube.LoadFromObjectFile("Nia.obj");
// Projection Matrix
float fNear = 0.1f;
@ -104,9 +160,21 @@ public:
bool OnUserUpdate(float fElapsedTime) override
{
if (GetKey(olc::DOWN).bHeld) {
zOffset-=1*fElapsedTime;
}
if (GetKey(olc::UP).bHeld) {
zOffset+=1*fElapsedTime;
}
if (GetKey(olc::RIGHT).bHeld) {
fTheta-=1*fElapsedTime;
}
if (GetKey(olc::LEFT).bHeld) {
fTheta+=1*fElapsedTime;
}
// Set up rotation matrices
mat4x4 matRotZ, matRotX;
fTheta += 1.0f * fElapsedTime;
// Rotation Z
matRotZ.m[0][0] = cosf(fTheta);
@ -124,6 +192,8 @@ public:
matRotX.m[2][2] = cosf(fTheta * 0.5f);
matRotX.m[3][3] = 1;
std::vector<triangle>vecTrianglesToRaster;
// Draw Triangles
for (auto&tri : meshCube.tris)
{
@ -141,9 +211,9 @@ public:
// Offset into the screen
triTranslated = triRotatedZX;
triTranslated.p[0].z = triRotatedZX.p[0].z + 3.0f;
triTranslated.p[1].z = triRotatedZX.p[1].z + 3.0f;
triTranslated.p[2].z = triRotatedZX.p[2].z + 3.0f;
triTranslated.p[0].z = triRotatedZX.p[0].z + zOffset;
triTranslated.p[1].z = triRotatedZX.p[1].z + zOffset;
triTranslated.p[2].z = triRotatedZX.p[2].z + zOffset;
vec3d normal,line1,line2;
line1.x=triTranslated.p[1].x-triTranslated.p[0].x;
@ -188,22 +258,45 @@ public:
triProjected.p[1].y *= 0.5f * (float)ScreenHeight();
triProjected.p[2].x *= 0.5f * (float)ScreenWidth();
triProjected.p[2].y *= 0.5f * (float)ScreenHeight();
triProjected.col=Pixel(255*dp*dp,255*dp*dp,255*dp*dp);
vecTrianglesToRaster.push_back(triProjected);
// Rasterize triangle
//SetDecalMode(DecalMode::WIREFRAME);
DrawPolygonDecal(nullptr,{
{triProjected.p[0].x, triProjected.p[0].y},
{triProjected.p[1].x, triProjected.p[1].y},
{triProjected.p[2].x, triProjected.p[2].y}
},{
{0,0},
{0,0},
{0,0},
},Pixel(255*dp*dp,255*dp*dp,255*dp*dp));
}
}
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;});
for (auto&triProjected:vecTrianglesToRaster) {
// Rasterize triangle
SetDecalStructure(DecalStructure::LIST);
SetDecalMode(DecalMode::NORMAL);
DrawPolygonDecal(nullptr,{
{triProjected.p[0].x, triProjected.p[0].y},
{triProjected.p[1].x, triProjected.p[1].y},
{triProjected.p[2].x, triProjected.p[2].y}
},{
{triProjected.uv[0].u,triProjected.uv[0].v},
{triProjected.uv[1].u,triProjected.uv[1].v},
{triProjected.uv[2].u,triProjected.uv[2].v},
},triProjected.col);
/*SetDecalMode(DecalMode::WIREFRAME);
DrawPolygonDecal(nullptr,{
{triProjected.p[0].x, triProjected.p[0].y},
{triProjected.p[1].x, triProjected.p[1].y},
{triProjected.p[2].x, triProjected.p[2].y}
},{
{0,0},
{0,0},
{0,0},
},BLACK);*/
SetDecalStructure(DecalStructure::FAN);
}
SetDecalMode(DecalMode::NORMAL);
DrawStringDecal({0,0},"Triangles: "+std::to_string(meshCube.tris.size()));
return true;
}

Loading…
Cancel
Save