Reference the w from inside the PGE to fix perspective

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent 6862923a50
commit 8f9cb3d107
  1. 1
      C++/scripts/filelist
  2. 1
      C++/scripts/md5
  3. 7
      C++/scripts/release.sh
  4. BIN
      C++ProjectTemplate
  5. 26
      cube.obj
  6. 111
      main.cpp
  7. 22
      pixelGameEngine.h
  8. 2
      sig

@ -1,5 +1,6 @@
build.sh
commit.sh
lines.sh
release.sh
temp
web.sh

@ -1,5 +1,6 @@
build.sh:530634457ea9041267c05d4ced95eee1 -
commit.sh:d03a46e721060c22ccb146e19d27e70a -
lines.sh:3b907786f7fc9204025993016c9080de -
release.sh:a54e2002be80814cc1293a11dff4d116 -
temp:d41d8cd98f00b204e9800998ecf8427e -
web.sh:3dcc2fe7e036359eedd257a864e9a1e1 -

@ -0,0 +1,7 @@
#Creates a release build that focuses on high runtime performance.
#C++
printf "Running program...\n\n\n"
if g++ $(find . -type f -name "*.cpp") ${CUSTOM_PARAMS} -O3 -s -DNDEBUG -o ${PROJECT_NAME}; then
./${PROJECT_NAME} "$@"
fi
printf "\n\n"

Binary file not shown.

@ -0,0 +1,26 @@
v 0 0 0
v 0 0 1
v 0 1 0
v 0 1 1
v 1 0 0
v 1 0 1
v 1 1 0
v 1 1 1
vt 0 0 #1
vt 0 1 #2
vt 1 0 #3
vt 1 1 #4
f 1/2 3/1 7/3 #South/0
f 1/2 7/3 5/4 #1
f 5/2 7/1 8/3 #East/2
f 5/2 8/3 6/4 #3
f 6/2 8/1 4/3 #North/4
f 6/2 4/3 2/4 #5
f 2/2 4/1 3/3 #West/6
f 2/2 3/3 1/4 #7
f 3/2 4/1 8/3 #Top/8
f 3/2 8/3 7/4 #9
f 6/2 2/1 1/3 #Bottom/10
f 6/2 1/3 5/4 #11

@ -7,7 +7,9 @@ using namespace olc;
struct vec2d
{
float u,v;
float u=0;
float v=0;
float w=1;
};
@ -87,9 +89,8 @@ struct mesh
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]*/});
tris.push_back({ verts[stoi(tokens[0]) - 1], verts[stoi(tokens[2]) - 1], verts[stoi(tokens[4]) - 1],
uvs[stoi(tokens[1]) - 1], uvs[stoi(tokens[3]) - 1], uvs[stoi(tokens[5]) - 1]});
}
}
@ -127,7 +128,8 @@ private:
float fTheta=0;
float fYaw=0;
vec3d Matrix_MultiplyVector(mat4x4 &m, vec3d &i)
vec3d
Matrix_MultiplyVector(mat4x4 &m, vec3d &i)
{
vec3d v;
v.x = i.x * m.m[0][0] + i.y * m.m[1][0] + i.z * m.m[2][0] + i.w * m.m[3][0];
@ -300,18 +302,19 @@ private:
return v;
}
vec3d Vector_IntersectPlane(vec3d &plane_p, vec3d &plane_n, vec3d &lineStart, vec3d &lineEnd)
vec3d Vector_IntersectPlane(vec3d &plane_p, vec3d &plane_n, vec3d &lineStart, vec3d &lineEnd, float &t)
{
plane_n = Vector_Normalise(plane_n);
float plane_d = -Vector_DotProduct(plane_n, plane_p);
float ad = Vector_DotProduct(lineStart, plane_n);
float bd = Vector_DotProduct(lineEnd, plane_n);
float t = (-plane_d - ad) / (bd - ad);
t = (-plane_d - ad) / (bd - ad);
vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart);
vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t);
return Vector_Add(lineStart, lineToIntersect);
}
int Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, triangle &in_tri, triangle &out_tri1, triangle &out_tri2)
{
// Make sure plane normal is indeed normal
@ -328,18 +331,31 @@ private:
// If distance sign is positive, point lies on "inside" of plane
vec3d* inside_points[3]; int nInsidePointCount = 0;
vec3d* outside_points[3]; int nOutsidePointCount = 0;
vec2d* inside_tex[3]; int nInsideTexCount = 0;
vec2d* outside_tex[3]; int nOutsideTexCount = 0;
// Get signed distance of each point in triangle to plane
float d0 = dist(in_tri.p[0]);
float d1 = dist(in_tri.p[1]);
float d2 = dist(in_tri.p[2]);
if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; }
else { outside_points[nOutsidePointCount++] = &in_tri.p[0]; }
if (d1 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[1]; }
else { outside_points[nOutsidePointCount++] = &in_tri.p[1]; }
if (d2 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[2]; }
else { outside_points[nOutsidePointCount++] = &in_tri.p[2]; }
if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; inside_tex[nInsideTexCount++] = &in_tri.uv[0]; }
else {
outside_points[nOutsidePointCount++] = &in_tri.p[0]; outside_tex[nOutsideTexCount++] = &in_tri.uv[0];
}
if (d1 >= 0) {
inside_points[nInsidePointCount++] = &in_tri.p[1]; inside_tex[nInsideTexCount++] = &in_tri.uv[1];
}
else {
outside_points[nOutsidePointCount++] = &in_tri.p[1]; outside_tex[nOutsideTexCount++] = &in_tri.uv[1];
}
if (d2 >= 0) {
inside_points[nInsidePointCount++] = &in_tri.p[2]; inside_tex[nInsideTexCount++] = &in_tri.uv[2];
}
else {
outside_points[nOutsidePointCount++] = &in_tri.p[2]; outside_tex[nOutsideTexCount++] = &in_tri.uv[2];
}
// Now classify triangle points, and break the input triangle into
// smaller output triangles if required. There are four possible
@ -368,15 +384,24 @@ private:
// the plane, the triangle simply becomes a smaller triangle
// Copy appearance info to new triangle
out_tri1.col = {in_tri.col.r,in_tri.col.g,255}; //in_tri.col;
out_tri1.col = in_tri.col;
// The inside point is valid, so keep that...
out_tri1.p[0] = *inside_points[0];
out_tri1.uv[0] = *inside_tex[0];
// but the two new points are at the locations where the
// original sides of the triangle (lines) intersect with the plane
out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0]);
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1]);
float t;
out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
out_tri1.uv[1].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
out_tri1.uv[1].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
out_tri1.uv[1].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1], t);
out_tri1.uv[2].u = t * (outside_tex[1]->u - inside_tex[0]->u) + inside_tex[0]->u;
out_tri1.uv[2].v = t * (outside_tex[1]->v - inside_tex[0]->v) + inside_tex[0]->v;
out_tri1.uv[2].w = t * (outside_tex[1]->w - inside_tex[0]->w) + inside_tex[0]->w;
return 1; // Return the newly formed single triangle
}
@ -388,32 +413,44 @@ private:
// represent a quad with two new triangles
// Copy appearance info to new triangles
out_tri1.col = {in_tri.col.r,255,in_tri.col.b}; //in_tri.col;
out_tri2.col = {255,in_tri.col.g,in_tri.col.b};//in_tri.col;
out_tri1.col = in_tri.col;
out_tri2.col = in_tri.col;
// The first triangle consists of the two inside points and a new
// point determined by the location where one side of the triangle
// intersects with the plane
out_tri1.p[0] = *inside_points[0];
out_tri1.p[1] = *inside_points[1];
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0]);
out_tri1.uv[0] = *inside_tex[0];
out_tri1.uv[1] = *inside_tex[1];
float t;
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t);
out_tri1.uv[2].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u;
out_tri1.uv[2].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v;
out_tri1.uv[2].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w;
// The second triangle is composed of one of he inside points, a
// new point determined by the intersection of the other side of the
// triangle and the plane, and the newly created point above
out_tri2.p[0] = *inside_points[1];
out_tri2.uv[0] = *inside_tex[1];
out_tri2.p[1] = out_tri1.p[2];
out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0]);
out_tri2.uv[1] = out_tri1.uv[2];
out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0], t);
out_tri2.uv[2].u = t * (outside_tex[0]->u - inside_tex[1]->u) + inside_tex[1]->u;
out_tri2.uv[2].v = t * (outside_tex[0]->v - inside_tex[1]->v) + inside_tex[1]->v;
out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w;
return 2; // Return two newly formed triangles which form a quad
}
}
public:
bool OnUserCreate() override
{
texture = new Decal(new Sprite("Body.png"));
meshCube.LoadFromObjectFile("Nia.obj");
texture = new Decal(new Sprite("dirtblock.png"));
meshCube.LoadFromObjectFile("cube.obj");
matProj=Matrix_MakeProjection(90.0f,(float)ScreenHeight() / (float)ScreenWidth(),0.1f,1000.0f);
@ -477,6 +514,9 @@ public:
triTransformed.p[0]=Matrix_MultiplyVector(matWorld,tri.p[0]);
triTransformed.p[1]=Matrix_MultiplyVector(matWorld,tri.p[1]);
triTransformed.p[2]=Matrix_MultiplyVector(matWorld,tri.p[2]);
triTransformed.uv[0]=tri.uv[0];
triTransformed.uv[1]=tri.uv[1];
triTransformed.uv[2]=tri.uv[2];
vec3d normal,line1,line2;
line1=Vector_Sub(triTransformed.p[1],triTransformed.p[0]);
@ -496,7 +536,9 @@ public:
triViewed.p[0]=Matrix_MultiplyVector(matView,triTransformed.p[0]);
triViewed.p[1]=Matrix_MultiplyVector(matView,triTransformed.p[1]);
triViewed.p[2]=Matrix_MultiplyVector(matView,triTransformed.p[2]);
triViewed.uv[0]=triTransformed.uv[0];
triViewed.uv[1]=triTransformed.uv[1];
triViewed.uv[2]=triTransformed.uv[2];
triViewed.col=Pixel(255*dp*dp,255*dp*dp,255*dp*dp);
int nClippedTriangles = 0;
@ -509,6 +551,21 @@ public:
triProjected.p[1]=Matrix_MultiplyVector(matProj,clipped[n].p[1]);
triProjected.p[2]=Matrix_MultiplyVector(matProj,clipped[n].p[2]);
triProjected.col=clipped[n].col;
triProjected.uv[0]=clipped[n].uv[0];
triProjected.uv[1]=clipped[n].uv[1];
triProjected.uv[2]=clipped[n].uv[2];
triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w;
triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w;
triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w;
triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w;
triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w;
triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w;
triProjected.uv[0].w = 1.0f / triProjected.p[0].w;
triProjected.uv[1].w = 1.0f / triProjected.p[1].w;
triProjected.uv[2].w = 1.0f / triProjected.p[2].w;
triProjected.p[0]=Vector_Div(triProjected.p[0],triProjected.p[0].w);
triProjected.p[1]=Vector_Div(triProjected.p[1],triProjected.p[1].w);
@ -584,7 +641,7 @@ public:
// Rasterize triangle
SetDecalStructure(DecalStructure::LIST);
SetDecalMode(DecalMode::NORMAL);
DrawPolygonDecal(nullptr,{
DrawPolygonDecal(texture,{
{t.p[0].x, t.p[0].y},
{t.p[1].x, t.p[1].y},
{t.p[2].x, t.p[2].y}
@ -592,7 +649,7 @@ public:
{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.col);
},{{t.uv[0].w,t.uv[1].w,t.uv[2].w}},{{t.col,t.col,t.col}});
/*SetDecalMode(DecalMode::WIREFRAME);
DrawPolygonDecal(nullptr,{
{t.p[0].x, t.p[0].y},
@ -602,7 +659,7 @@ public:
{0,0},
{0,0},
{0,0},
},BLACK);*/
},WHITE);*/
SetDecalStructure(DecalStructure::FAN);
triRenderCount++;
}

@ -1081,6 +1081,7 @@ namespace olc
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const olc::Pixel tint = olc::WHITE);
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<float>& depth, const std::vector<olc::vf2d>& uv, const olc::Pixel tint = olc::WHITE);
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& tint);
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<float>& w,const std::vector<olc::Pixel> &tint);
// Draws a line in Decal Space
void DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE);
@ -2600,6 +2601,27 @@ namespace olc
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}
void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<float>& w,const std::vector<olc::Pixel> &tint)
{
DecalInstance di;
di.decal = decal;
di.points = uint32_t(pos.size());
di.pos.resize(di.points);
di.uv.resize(di.points);
di.w.resize(di.points);
di.tint.resize(di.points);
for (uint32_t i = 0; i < di.points; i++)
{
di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f };
di.uv[i] = uv[i];
di.tint[i] = tint[i];
di.w[i] = w[i];
}
di.mode = nDecalMode;
di.structure = nDecalStructure;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}
void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel> &tint)
{
DecalInstance di;

2
sig

@ -3,7 +3,7 @@ export AUTO_UPDATE=true
source utils/define.sh
define PROJECT_NAME "C++ProjectTemplate"
define CUSTOM_PARAMS "-std=c++17 -lX11 -lGL -lpthread -lpng -lstdc++fs -lpulse -lpulse-simple -O3 -s -DNDEBUG"
define CUSTOM_PARAMS "-std=c++17 -lX11 -lGL -lpthread -lpng -lstdc++fs -lpulse -lpulse-simple"
define LANGUAGE "C++"
source utils/main.sh

Loading…
Cancel
Save