Refactor game into multiple files.

linux_template
sigonasr2 2 years ago
parent 89da6f65b1
commit 725853c0b2
  1. 0
      Faceball2030/Editor.cpp
  2. 11
      Faceball2030/Editor.h
  3. 3
      Faceball2030/Faceball2030.vcxproj
  4. 9
      Faceball2030/Faceball2030.vcxproj.filters
  5. 23
      Faceball2030/MapFormat.txt
  6. 0
      Faceball2030/assets/map/map1.map
  7. 359
      Faceball2030/main.cpp
  8. 185
      Faceball2030/main.h

@ -0,0 +1,11 @@
#pragma once
#include "pixelGameEngine.h"
using namespace olc;
class Editor {
std::string filename;
vi2d MAP_SIZE;
void Update(float fElapsedTime) {
}
};

@ -127,9 +127,12 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Editor.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Editor.h" />
<ClInclude Include="main.h" />
<ClInclude Include="pixelGameEngine.h" /> <ClInclude Include="pixelGameEngine.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

@ -18,10 +18,19 @@
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Editor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="pixelGameEngine.h"> <ClInclude Include="pixelGameEngine.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Editor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -0,0 +1,23 @@
Map Format:
Width
Height
Width*Height 16-bit values
16 bits
Dir
vv
0000 0000 0000 0000
^ ^ En ID^ ^^^^
| ^^^ NESW
| Wave 321
Blink
Armor
Speed
Shot
Camo
Stop
Shield
Map

@ -2,177 +2,34 @@
#include "pixelGameEngine.h" #include "pixelGameEngine.h"
#include <strstream> #include <strstream>
#include <algorithm> #include <algorithm>
#include "main.h"
using namespace olc; using namespace olc;
const float PI = 3.14159f;
enum Direction { vec3d
NORTH=1, FaceBall::Matrix_MultiplyVector(mat4x4& m, vec3d& i)
EAST=2,
SOUTH=4,
WEST=8
};
struct vec2d
{
float u = 0;
float v = 0;
float w = 1;
};
struct vec3d
{ {
float x = 0;
float y = 0;
float z = 0;
float w = 1;
};
struct Triangle
{
vec3d p[3];
vec2d uv[3];
Pixel col;
Decal* tex;
};
struct MapSquare {
Decal*wallN=NULL;
Decal* wallE=NULL;
Decal* wallS=NULL;
Decal* wallW=NULL;
};
struct Mesh
{
std::vector<Triangle> tris;
Decal* texture=NULL;
Mesh() {}
Mesh(std::string filename,Decal*tex)
:texture(tex){
LoadFromObjectFile(filename);
}
private:
void Parse(std::string str, int& v, int& uv) {
std::cout << str << "\n";
std::stringstream s(str.substr(0, str.find("/") + 1));
s >> v;
str.erase(0, str.find("/") + 1);
std::stringstream s2(str.substr(0, str.find("/") + 1));
s2 >> uv;
//std::cout<<" "<<v<<"/"<<uv<<"\n";
}
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;
std::string data;
while (f.good()) {
f >> data;
if (data == "v") {
float x, y, z;
f >> x >> y >> z;
verts.push_back({ x,y,z });
std::cout<<x<<" "<<y<<" "<<z<<"\n";
}
else
if (data == "vt") {
float u, v;
f >> u >> v;
uvs.push_back({ u,1-v });
std::cout<<u<<" "<<v<<"\n";
}
else
if (data == "f") {
//std::cout<<"face\n";
std::string t1, t2, t3;
f >> t1 >> t2 >> t3;
int v1, v2, v3, uv1, uv2, uv3;
Parse(t1, v1, uv1);
Parse(t2, v2, uv2);
Parse(t3, v3, uv3);
tris.push_back({ verts[v1 - 1],verts[v2 - 1],verts[v3 - 1],
uvs[uv1 - 1],uvs[uv2 - 1],uvs[uv3 - 1],WHITE });
}
}
return true;
}
};
struct Object {
Mesh mesh;
vf2d pos = { 0,0 };
float rot = 0;
};
struct mat4x4
{
float m[4][4] = { 0 };
};
class FaceBall : public PixelGameEngine
{
public:
bool freeRoam=false;
FaceBall()
{
sAppName = "3D Demo";
}
private:
Mesh mapMesh;
mat4x4 matProj;
vec3d vCamera = { 5,0.5,5 };
vec3d vLookDir;
float zOffset = 2;
float fTheta = 0;
float fYaw = 0;
float pitch = -PI / 6;
vec3d
Matrix_MultiplyVector(mat4x4& m, vec3d& i)
{
vec3d v; 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]; 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];
v.y = i.x * m.m[0][1] + i.y * m.m[1][1] + i.z * m.m[2][1] + i.w * m.m[3][1]; v.y = i.x * m.m[0][1] + i.y * m.m[1][1] + i.z * m.m[2][1] + i.w * m.m[3][1];
v.z = i.x * m.m[0][2] + i.y * m.m[1][2] + i.z * m.m[2][2] + i.w * m.m[3][2]; v.z = i.x * m.m[0][2] + i.y * m.m[1][2] + i.z * m.m[2][2] + i.w * m.m[3][2];
v.w = i.x * m.m[0][3] + i.y * m.m[1][3] + i.z * m.m[2][3] + i.w * m.m[3][3]; v.w = i.x * m.m[0][3] + i.y * m.m[1][3] + i.z * m.m[2][3] + i.w * m.m[3][3];
return v; return v;
} };
mat4x4 Matrix_MakeIdentity() mat4x4 FaceBall::Matrix_MakeIdentity()
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = 1.0f; matrix.m[0][0] = 1.0f;
matrix.m[1][1] = 1.0f; matrix.m[1][1] = 1.0f;
matrix.m[2][2] = 1.0f; matrix.m[2][2] = 1.0f;
matrix.m[3][3] = 1.0f; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} };
mat4x4 Matrix_MakeRotationX(float fAngleRad) mat4x4 FaceBall::Matrix_MakeRotationX(float fAngleRad)
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = 1.0f; matrix.m[0][0] = 1.0f;
matrix.m[1][1] = cosf(fAngleRad); matrix.m[1][1] = cosf(fAngleRad);
@ -181,10 +38,10 @@ private:
matrix.m[2][2] = cosf(fAngleRad); matrix.m[2][2] = cosf(fAngleRad);
matrix.m[3][3] = 1.0f; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} }
mat4x4 Matrix_MakeRotationY(float fAngleRad) mat4x4 FaceBall::Matrix_MakeRotationY(float fAngleRad)
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = cosf(fAngleRad); matrix.m[0][0] = cosf(fAngleRad);
matrix.m[0][2] = sinf(fAngleRad); matrix.m[0][2] = sinf(fAngleRad);
@ -193,10 +50,10 @@ private:
matrix.m[2][2] = cosf(fAngleRad); matrix.m[2][2] = cosf(fAngleRad);
matrix.m[3][3] = 1.0f; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} }
mat4x4 Matrix_MakeRotationZ(float fAngleRad) mat4x4 FaceBall::Matrix_MakeRotationZ(float fAngleRad)
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = cosf(fAngleRad); matrix.m[0][0] = cosf(fAngleRad);
matrix.m[0][1] = sinf(fAngleRad); matrix.m[0][1] = sinf(fAngleRad);
@ -205,10 +62,10 @@ private:
matrix.m[2][2] = 1.0f; matrix.m[2][2] = 1.0f;
matrix.m[3][3] = 1.0f; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} }
mat4x4 Matrix_MakeTranslation(float x, float y, float z) mat4x4 FaceBall::Matrix_MakeTranslation(float x, float y, float z)
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = 1.0f; matrix.m[0][0] = 1.0f;
matrix.m[1][1] = 1.0f; matrix.m[1][1] = 1.0f;
@ -218,10 +75,10 @@ private:
matrix.m[3][1] = y; matrix.m[3][1] = y;
matrix.m[3][2] = z; matrix.m[3][2] = z;
return matrix; return matrix;
} }
mat4x4 Matrix_MakeProjection(float fFovDegrees, float fAspectRatio, float fNear, float fFar) mat4x4 FaceBall::Matrix_MakeProjection(float fFovDegrees, float fAspectRatio, float fNear, float fFar)
{ {
float fFovRad = 1.0f / tanf(fFovDegrees * 0.5f / 180.0f * 3.14159f); float fFovRad = 1.0f / tanf(fFovDegrees * 0.5f / 180.0f * 3.14159f);
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = fAspectRatio * fFovRad; matrix.m[0][0] = fAspectRatio * fFovRad;
@ -231,19 +88,19 @@ private:
matrix.m[2][3] = 1.0f; matrix.m[2][3] = 1.0f;
matrix.m[3][3] = 0.0f; matrix.m[3][3] = 0.0f;
return matrix; return matrix;
} }
mat4x4 Matrix_MultiplyMatrix(mat4x4& m1, mat4x4& m2) mat4x4 FaceBall::Matrix_MultiplyMatrix(mat4x4& m1, mat4x4& m2)
{ {
mat4x4 matrix; mat4x4 matrix;
for (int c = 0; c < 4; c++) for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++) for (int r = 0; r < 4; r++)
matrix.m[r][c] = m1.m[r][0] * m2.m[0][c] + m1.m[r][1] * m2.m[1][c] + m1.m[r][2] * m2.m[2][c] + m1.m[r][3] * m2.m[3][c]; matrix.m[r][c] = m1.m[r][0] * m2.m[0][c] + m1.m[r][1] * m2.m[1][c] + m1.m[r][2] * m2.m[2][c] + m1.m[r][3] * m2.m[3][c];
return matrix; return matrix;
} }
mat4x4 Matrix_PointAt(vec3d& pos, vec3d& target, vec3d& up) mat4x4 FaceBall::Matrix_PointAt(vec3d& pos, vec3d& target, vec3d& up)
{ {
// Calculate new forward direction // Calculate new forward direction
vec3d newForward = Vector_Sub(target, pos); vec3d newForward = Vector_Sub(target, pos);
newForward = Vector_Normalise(newForward); newForward = Vector_Normalise(newForward);
@ -264,10 +121,10 @@ private:
matrix.m[3][0] = pos.x; matrix.m[3][1] = pos.y; matrix.m[3][2] = pos.z; matrix.m[3][3] = 1.0f; matrix.m[3][0] = pos.x; matrix.m[3][1] = pos.y; matrix.m[3][2] = pos.z; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} }
mat4x4 Matrix_QuickInverse(mat4x4& m) // Only for Rotation/Translation Matrices mat4x4 FaceBall::Matrix_QuickInverse(mat4x4& m) // Only for Rotation/Translation Matrices
{ {
mat4x4 matrix; mat4x4 matrix;
matrix.m[0][0] = m.m[0][0]; matrix.m[0][1] = m.m[1][0]; matrix.m[0][2] = m.m[2][0]; matrix.m[0][3] = 0.0f; matrix.m[0][0] = m.m[0][0]; matrix.m[0][1] = m.m[1][0]; matrix.m[0][2] = m.m[2][0]; matrix.m[0][3] = 0.0f;
matrix.m[1][0] = m.m[0][1]; matrix.m[1][1] = m.m[1][1]; matrix.m[1][2] = m.m[2][1]; matrix.m[1][3] = 0.0f; matrix.m[1][0] = m.m[0][1]; matrix.m[1][1] = m.m[1][1]; matrix.m[1][2] = m.m[2][1]; matrix.m[1][3] = 0.0f;
@ -277,55 +134,55 @@ private:
matrix.m[3][2] = -(m.m[3][0] * matrix.m[0][2] + m.m[3][1] * matrix.m[1][2] + m.m[3][2] * matrix.m[2][2]); matrix.m[3][2] = -(m.m[3][0] * matrix.m[0][2] + m.m[3][1] * matrix.m[1][2] + m.m[3][2] * matrix.m[2][2]);
matrix.m[3][3] = 1.0f; matrix.m[3][3] = 1.0f;
return matrix; return matrix;
} }
vec3d Vector_Add(vec3d& v1, vec3d& v2) vec3d FaceBall::Vector_Add(vec3d& v1, vec3d& v2)
{ {
return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
} }
vec3d Vector_Sub(vec3d& v1, vec3d& v2) vec3d FaceBall::Vector_Sub(vec3d& v1, vec3d& v2)
{ {
return { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z }; return { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
} }
vec3d Vector_Mul(vec3d& v1, float k) vec3d FaceBall::Vector_Mul(vec3d& v1, float k)
{ {
return { v1.x * k, v1.y * k, v1.z * k }; return { v1.x * k, v1.y * k, v1.z * k };
} }
vec3d Vector_Div(vec3d& v1, float k) vec3d FaceBall::Vector_Div(vec3d& v1, float k)
{ {
return { v1.x / k, v1.y / k, v1.z / k }; return { v1.x / k, v1.y / k, v1.z / k };
} }
float Vector_DotProduct(vec3d& v1, vec3d& v2) float FaceBall::Vector_DotProduct(vec3d& v1, vec3d& v2)
{ {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
} }
float Vector_Length(vec3d& v) float FaceBall::Vector_Length(vec3d& v)
{ {
return sqrtf(Vector_DotProduct(v, v)); return sqrtf(Vector_DotProduct(v, v));
} }
vec3d Vector_Normalise(vec3d& v) vec3d FaceBall::Vector_Normalise(vec3d& v)
{ {
float l = Vector_Length(v); float l = Vector_Length(v);
return { v.x / l, v.y / l, v.z / l }; return { v.x / l, v.y / l, v.z / l };
} }
vec3d Vector_CrossProduct(vec3d& v1, vec3d& v2) vec3d FaceBall::Vector_CrossProduct(vec3d& v1, vec3d& v2)
{ {
vec3d v; vec3d v;
v.x = v1.y * v2.z - v1.z * v2.y; v.x = v1.y * v2.z - v1.z * v2.y;
v.y = v1.z * v2.x - v1.x * v2.z; v.y = v1.z * v2.x - v1.x * v2.z;
v.z = v1.x * v2.y - v1.y * v2.x; v.z = v1.x * v2.y - v1.y * v2.x;
return v; return v;
} }
vec3d Vector_IntersectPlane(vec3d& plane_p, vec3d& plane_n, vec3d& lineStart, vec3d& lineEnd, float& t) vec3d FaceBall::Vector_IntersectPlane(vec3d& plane_p, vec3d& plane_n, vec3d& lineStart, vec3d& lineEnd, float& t)
{ {
plane_n = Vector_Normalise(plane_n); plane_n = Vector_Normalise(plane_n);
float plane_d = -Vector_DotProduct(plane_n, plane_p); float plane_d = -Vector_DotProduct(plane_n, plane_p);
float ad = Vector_DotProduct(lineStart, plane_n); float ad = Vector_DotProduct(lineStart, plane_n);
@ -334,11 +191,11 @@ private:
vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart); vec3d lineStartToEnd = Vector_Sub(lineEnd, lineStart);
vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t); vec3d lineToIntersect = Vector_Mul(lineStartToEnd, t);
return Vector_Add(lineStart, lineToIntersect); return Vector_Add(lineStart, lineToIntersect);
} }
int Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& in_tri, Triangle& out_tri1, Triangle& out_tri2) int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& in_tri, Triangle& out_tri1, Triangle& out_tri2)
{ {
// Make sure plane normal is indeed normal // Make sure plane normal is indeed normal
plane_n = Vector_Normalise(plane_n); plane_n = Vector_Normalise(plane_n);
@ -468,9 +325,9 @@ private:
out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w; 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 return 2; // Return two newly formed triangles which form a quad
} }
} }
void RenderWorld() { void FaceBall::RenderWorld() {
// Set up rotation matrices // Set up rotation matrices
mat4x4 matRotZ, matRotX, matWorld; mat4x4 matRotZ, matRotX, matWorld;
@ -494,7 +351,7 @@ private:
// Draw Triangles // Draw Triangles
for (auto& obj : objects) { for (auto& obj : objects) {
for (auto& tri : obj.mesh.tris){ for (auto& tri : obj.mesh.tris) {
Triangle triProjected, triTransformed, triViewed; Triangle triProjected, triTransformed, triViewed;
//mat4x4 matTrans = Matrix_MakeTranslation(-mesh.size.x/2, 0, -mesh.size.x/2); //mat4x4 matTrans = Matrix_MakeTranslation(-mesh.size.x/2, 0, -mesh.size.x/2);
mat4x4 localMat = Matrix_MakeIdentity(); mat4x4 localMat = Matrix_MakeIdentity();
@ -633,7 +490,7 @@ private:
nNewTriangles = listTriangles.size(); nNewTriangles = listTriangles.size();
} }
std::map<vf2d,vf2d>coords; std::map<vf2d, vf2d>coords;
for (auto& t : listTriangles) { for (auto& t : listTriangles) {
// Rasterize triangle // Rasterize triangle
@ -662,7 +519,7 @@ private:
triRenderCount++; triRenderCount++;
} }
for (const auto&key:coords){ for (const auto& key : coords) {
vf2d coord = key.first; vf2d coord = key.first;
vf2d val = key.second; vf2d val = key.second;
DrawStringDecal({ coord.x,coord.y }, val.str()); DrawStringDecal({ coord.x,coord.y }, val.str());
@ -671,9 +528,9 @@ private:
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) { void FaceBall::HandleKeys(float fElapsedTime) {
vec3d vForward = Vector_Mul(vLookDir, 2 * fElapsedTime); vec3d vForward = Vector_Mul(vLookDir, 2 * fElapsedTime);
if (freeRoam) { if (freeRoam) {
if (GetKey(olc::DOWN).bHeld) { if (GetKey(olc::DOWN).bHeld) {
@ -701,9 +558,9 @@ private:
if (GetKey(olc::F1).bPressed) { if (GetKey(olc::F1).bPressed) {
freeRoam = !freeRoam; freeRoam = !freeRoam;
} }
} }
void AddWall(Direction dir,vi2d gridSquare) { void FaceBall::AddWall(Direction dir, vi2d gridSquare) {
if (dir & NORTH) { if (dir & NORTH) {
map[gridSquare.y][gridSquare.x].wallN = dot; map[gridSquare.y][gridSquare.x].wallN = dot;
if (gridSquare.y > 0) { if (gridSquare.y > 0) {
@ -713,31 +570,26 @@ private:
if (dir & WEST) { if (dir & WEST) {
map[gridSquare.y][gridSquare.x].wallW = dot; map[gridSquare.y][gridSquare.x].wallW = dot;
if (gridSquare.x > 0) { if (gridSquare.x > 0) {
map[gridSquare.y][gridSquare.x-1].wallE = dot; map[gridSquare.y][gridSquare.x - 1].wallE = dot;
} }
} }
if (dir & SOUTH) { if (dir & SOUTH) {
map[gridSquare.y][gridSquare.x].wallS = dot; map[gridSquare.y][gridSquare.x].wallS = dot;
if (gridSquare.y<map.size()-1) { if (gridSquare.y < map.size() - 1) {
map[gridSquare.y+1][gridSquare.x].wallN = dot; map[gridSquare.y + 1][gridSquare.x].wallN = dot;
} }
} }
if (dir & EAST) { if (dir & EAST) {
map[gridSquare.y][gridSquare.x].wallE = dot; map[gridSquare.y][gridSquare.x].wallE = dot;
if (gridSquare.x < map[0].size() - 1) { if (gridSquare.x < map[0].size() - 1) {
map[gridSquare.y][gridSquare.x+1].wallW = dot; map[gridSquare.y][gridSquare.x + 1].wallW = dot;
}
} }
} }
}
Decal* dot,*enemy_ShootMe_tex; bool FaceBall::OnUserCreate()
vi2d MAP_SIZE = { 10,10 }; {
std::vector<std::vector<MapSquare>>map; game = this;
std::vector<Object>objects;
public:
bool OnUserCreate() override
{
sAppName = "Faceball 2030"; sAppName = "Faceball 2030";
matProj = Matrix_MakeProjection(90.0f, (float)ScreenHeight() / (float)ScreenWidth(), 0.1f, 1000.0f); matProj = Matrix_MakeProjection(90.0f, (float)ScreenHeight() / (float)ScreenWidth(), 0.1f, 1000.0f);
dot = new Decal(new Sprite("assets/dot.png")); dot = new Decal(new Sprite("assets/dot.png"));
@ -755,7 +607,7 @@ public:
for (int x = 0; x < MAP_SIZE.x; x++) { for (int x = 0; x < MAP_SIZE.x; x++) {
row.push_back({}); row.push_back({});
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},BLUE }); mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},BLUE });
mapMesh.tris.push_back({ {{(float)x+1,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y+1}},{{0,0},{1,0},{0,1}},BLUE }); mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y + 1}},{{0,0},{1,0},{0,1}},BLUE });
} }
map.push_back(row); map.push_back(row);
} }
@ -767,7 +619,7 @@ public:
}break; }break;
case 1: {//North Wall. case 1: {//North Wall.
AddWall(NORTH,{x,y}); AddWall(NORTH, { x,y });
}break; }break;
case 2: {//East Wall. case 2: {//East Wall.
AddWall(EAST, { x,y }); AddWall(EAST, { x,y });
@ -779,37 +631,37 @@ public:
AddWall(WEST, { x,y }); AddWall(WEST, { x,y });
}break; }break;
case 5: {//NE Wall. case 5: {//NE Wall.
AddWall(Direction(NORTH|EAST), { x,y }); AddWall(Direction(NORTH | EAST), { x,y });
}break; }break;
case 6: { case 6: {
AddWall(Direction(NORTH|WEST), { x,y }); AddWall(Direction(NORTH | WEST), { x,y });
}break; }break;
case 7: { case 7: {
AddWall(Direction(SOUTH|EAST), { x,y }); AddWall(Direction(SOUTH | EAST), { x,y });
}break; }break;
case 8: { case 8: {
AddWall(Direction(SOUTH|WEST), { x,y }); AddWall(Direction(SOUTH | WEST), { x,y });
}break; }break;
case 9: { case 9: {
AddWall(Direction(NORTH|SOUTH), { x,y }); AddWall(Direction(NORTH | SOUTH), { x,y });
}break; }break;
case 10: { case 10: {
AddWall(Direction(EAST|WEST), { x,y }); AddWall(Direction(EAST | WEST), { x,y });
}break; }break;
case 11: { case 11: {
AddWall(Direction(NORTH|WEST|EAST), { x,y }); AddWall(Direction(NORTH | WEST | EAST), { x,y });
}break; }break;
case 12: { case 12: {
AddWall(Direction(NORTH|WEST|SOUTH), { x,y }); AddWall(Direction(NORTH | WEST | SOUTH), { x,y });
}break; }break;
case 13: { case 13: {
AddWall(Direction(WEST|SOUTH|EAST), { x,y }); AddWall(Direction(WEST | SOUTH | EAST), { x,y });
}break; }break;
case 14: { case 14: {
AddWall(Direction(SOUTH|EAST|NORTH), { x,y }); AddWall(Direction(SOUTH | EAST | NORTH), { x,y });
}break; }break;
case 15: { case 15: {
AddWall(Direction(SOUTH | EAST | NORTH|WEST), { x,y }); AddWall(Direction(SOUTH | EAST | NORTH | WEST), { x,y });
}break; }break;
} }
} }
@ -818,21 +670,21 @@ public:
for (int y = 0; y < MAP_SIZE.y; y++) { for (int y = 0; y < MAP_SIZE.y; y++) {
for (int x = 0; x < MAP_SIZE.x; x++) { for (int x = 0; x < MAP_SIZE.x; x++) {
if (map[y][x].wallN!=NULL) { if (map[y][x].wallN != NULL) {
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW });
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x+1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x + 1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW });
} }
if (map[y][x].wallS != NULL) { if (map[y][x].wallS != NULL) {
mapMesh.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,0},{0,1}},DARK_RED }); mapMesh.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,0},{0,1}},DARK_RED });
mapMesh.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},{1,0},{0,1}},DARK_RED }); mapMesh.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},{1,0},{0,1}},DARK_RED });
} }
if (map[y][x].wallW != NULL) { if (map[y][x].wallW != NULL) {
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y+1}, {(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},MAGENTA }); mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y + 1}, {(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},MAGENTA });
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{0,0},{1,0},{0,1}},MAGENTA }); mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{0,0},{1,0},{0,1}},MAGENTA });
} }
if (map[y][x].wallE != NULL) { if (map[y][x].wallE != NULL) {
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x+1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x + 1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},CYAN });
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x+1,1,(float)y},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x + 1,1,(float)y},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},CYAN });
} }
} }
} }
@ -840,19 +692,24 @@ public:
//objects.push_back(mapMesh); //objects.push_back(mapMesh);
return true; return true;
} }
bool OnUserUpdate(float fElapsedTime) override bool FaceBall::OnUserUpdate(float fElapsedTime)
{ {
switch (mode) {
case GAME: {
for (Object& o : objects) { for (Object& o : objects) {
o.rot += PI / 8 * fElapsedTime; o.rot += PI / 8 * fElapsedTime;
} }
HandleKeys(fElapsedTime); HandleKeys(fElapsedTime);
RenderWorld(); RenderWorld();
return true; }break;
} case EDITOR: {
}; }break;
}
return true;
}

@ -0,0 +1,185 @@
#pragma once
#include "pixelGameEngine.h"
using namespace olc;
const float PI = 3.14159f;
enum GAMEMODE {
GAME,
EDITOR
};
enum Direction {
NORTH = 1,
EAST = 2,
SOUTH = 4,
WEST = 8
};
struct vec2d
{
float u = 0;
float v = 0;
float w = 1;
};
struct vec3d
{
float x = 0;
float y = 0;
float z = 0;
float w = 1;
};
struct Triangle
{
vec3d p[3];
vec2d uv[3];
Pixel col;
Decal* tex;
};
struct MapSquare {
Decal* wallN = NULL;
Decal* wallE = NULL;
Decal* wallS = NULL;
Decal* wallW = NULL;
};
struct Mesh
{
std::vector<Triangle> tris;
Decal* texture = NULL;
Mesh() {}
Mesh(std::string filename, Decal* tex)
:texture(tex) {
LoadFromObjectFile(filename);
}
private:
void Parse(std::string str, int& v, int& uv) {
std::cout << str << "\n";
std::stringstream s(str.substr(0, str.find("/") + 1));
s >> v;
str.erase(0, str.find("/") + 1);
std::stringstream s2(str.substr(0, str.find("/") + 1));
s2 >> uv;
//std::cout<<" "<<v<<"/"<<uv<<"\n";
}
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;
std::string data;
while (f.good()) {
f >> data;
if (data == "v") {
float x, y, z;
f >> x >> y >> z;
verts.push_back({ x,y,z });
std::cout << x << " " << y << " " << z << "\n";
}
else
if (data == "vt") {
float u, v;
f >> u >> v;
uvs.push_back({ u,1 - v });
std::cout << u << " " << v << "\n";
}
else
if (data == "f") {
//std::cout<<"face\n";
std::string t1, t2, t3;
f >> t1 >> t2 >> t3;
int v1, v2, v3, uv1, uv2, uv3;
Parse(t1, v1, uv1);
Parse(t2, v2, uv2);
Parse(t3, v3, uv3);
tris.push_back({ verts[v1 - 1],verts[v2 - 1],verts[v3 - 1],
uvs[uv1 - 1],uvs[uv2 - 1],uvs[uv3 - 1],WHITE });
}
}
return true;
}
};
struct Object {
Mesh mesh;
vf2d pos = { 0,0 };
float rot = 0;
};
struct mat4x4
{
float m[4][4] = { 0 };
};
class FaceBall : public PixelGameEngine
{
bool freeRoam = false;
public:
FaceBall()
{
sAppName = "3D Demo";
}
private:
Mesh mapMesh;
Decal* dot, * enemy_ShootMe_tex;
vi2d MAP_SIZE = { 10,10 };
std::vector<std::vector<MapSquare>>map;
std::vector<Object>objects;
GAMEMODE mode=GAMEMODE::GAME;
mat4x4 matProj;
vec3d vCamera = { 5,0.5,5 };
vec3d vLookDir;
float zOffset = 2;
float fTheta = 0;
float fYaw = 0;
float pitch = -PI / 6;
vec3d Matrix_MultiplyVector(mat4x4& m, vec3d& i);
mat4x4 Matrix_MakeIdentity();
mat4x4 Matrix_MakeRotationX(float fAngleRad);
mat4x4 Matrix_MakeRotationY(float fAngleRad);
mat4x4 Matrix_MakeRotationZ(float fAngleRad);
mat4x4 Matrix_MakeTranslation(float x, float y, float z);
mat4x4 Matrix_MakeProjection(float fFovDegrees, float fAspectRatio, float fNear, float fFar);
mat4x4 Matrix_MultiplyMatrix(mat4x4& m1, mat4x4& m2);
mat4x4 Matrix_PointAt(vec3d& pos, vec3d& target, vec3d& up);
mat4x4 Matrix_QuickInverse(mat4x4& m);
vec3d Vector_Add(vec3d& v1, vec3d& v2);
vec3d Vector_Sub(vec3d& v1, vec3d& v2);
vec3d Vector_Mul(vec3d& v1, float k);
vec3d Vector_Div(vec3d& v1, float k);
float Vector_DotProduct(vec3d& v1, vec3d& v2);
float Vector_Length(vec3d& v);
vec3d Vector_Normalise(vec3d& v);
vec3d Vector_CrossProduct(vec3d& v1, vec3d& v2);
vec3d Vector_IntersectPlane(vec3d& plane_p, vec3d& plane_n, vec3d& lineStart, vec3d& lineEnd, float& t);
int Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& in_tri, Triangle& out_tri1, Triangle& out_tri2);
void RenderWorld();
void HandleKeys(float fElapsedTime);
void AddWall(Direction dir, vi2d gridSquare);
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
};
FaceBall* game;
Loading…
Cancel
Save