diff --git a/C++/scripts/filelist b/C++/scripts/filelist index faf6fb4..ca9afe2 100644 --- a/C++/scripts/filelist +++ b/C++/scripts/filelist @@ -1,5 +1,6 @@ build.sh commit.sh lines.sh +release.sh temp web.sh diff --git a/C++/scripts/md5 b/C++/scripts/md5 index b71151f..b57c2c4 100644 --- a/C++/scripts/md5 +++ b/C++/scripts/md5 @@ -1,5 +1,6 @@ build.sh:530634457ea9041267c05d4ced95eee1 - commit.sh:d03a46e721060c22ccb146e19d27e70a - lines.sh:3b907786f7fc9204025993016c9080de - +release.sh:a54e2002be80814cc1293a11dff4d116 - temp:d41d8cd98f00b204e9800998ecf8427e - web.sh:3dcc2fe7e036359eedd257a864e9a1e1 - diff --git a/C++/scripts/release.sh b/C++/scripts/release.sh new file mode 100755 index 0000000..b1620e8 --- /dev/null +++ b/C++/scripts/release.sh @@ -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" diff --git a/C++ProjectTemplate b/C++ProjectTemplate index 7b0696a..3a604e6 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/cube.obj b/cube.obj new file mode 100644 index 0000000..9413c49 --- /dev/null +++ b/cube.obj @@ -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 \ No newline at end of file diff --git a/main.cpp b/main.cpp index 2c27e7f..8027437 100644 --- a/main.cpp +++ b/main.cpp @@ -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++; } diff --git a/pixelGameEngine.h b/pixelGameEngine.h index f2a8ee2..24b63ee 100644 --- a/pixelGameEngine.h +++ b/pixelGameEngine.h @@ -1081,6 +1081,7 @@ namespace olc void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const olc::Pixel tint = olc::WHITE); void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& depth, const std::vector& uv, const olc::Pixel tint = olc::WHITE); void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector& tint); + void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector& w,const std::vector &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& pos, const std::vector& uv, const std::vector& w,const std::vector &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& pos, const std::vector& uv, const std::vector &tint) { DecalInstance di; diff --git a/sig b/sig index 5bd1ff3..65804b4 100755 --- a/sig +++ b/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