Skip to content

Commit

Permalink
Merge pull request #364 from OneLoneCoder/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
OneLoneCoder authored Mar 5, 2024
2 parents af4212c + 8cb32fe commit 11b2632
Showing 1 changed file with 105 additions and 51 deletions.
156 changes: 105 additions & 51 deletions olcPixelGameEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
olcPixelGameEngine.h
+-------------------------------------------------------------+
| OneLoneCoder Pixel Game Engine v2.24 |
| OneLoneCoder Pixel Game Engine v2.25 |
| "What do you need? Pixels... Lots of Pixels..." - javidx9 |
+-------------------------------------------------------------+
Expand Down Expand Up @@ -319,6 +319,7 @@
2.23: Fixed Emscripten host sizing errors - Thanks Moros
Fixed v2d_generic.clamp() function
2.24: Fix FillTexturedTriangle() to remove const-ref
2.25: +DrawPolygonDecal(pos, tex, w, col)
!! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !!
!! Volunteers willing to help appreciated, though PRs are manually integrated with credit !!
Expand Down Expand Up @@ -398,7 +399,7 @@ int main()
#include <cstring>
#pragma endregion

#define PGE_VER 224
#define PGE_VER 225

// O------------------------------------------------------------------------------O
// | COMPILER CONFIGURATION ODDITIES |
Expand Down Expand Up @@ -579,6 +580,7 @@ namespace olc
// O------------------------------------------------------------------------------O
// | olc::Pixel - Represents a 32-Bit RGBA colour |
// O------------------------------------------------------------------------------O
#if !defined(OLC_IGNORE_PIXEL)
struct Pixel
{
union
Expand Down Expand Up @@ -624,7 +626,7 @@ namespace olc
BLUE(0, 0, 255), DARK_BLUE(0, 0, 128), VERY_DARK_BLUE(0, 0, 64),
MAGENTA(255, 0, 255), DARK_MAGENTA(128, 0, 128), VERY_DARK_MAGENTA(64, 0, 64),
WHITE(255, 255, 255), BLACK(0, 0, 0), BLANK(0, 0, 0, 0);

#endif
// Thanks to scripticuk and others for updating the key maps
// NOTE: The GLUT platform will need updating, open to contributions ;)
enum Key
Expand Down Expand Up @@ -850,7 +852,6 @@ namespace olc
STENCIL,
ILLUMINATE,
WIREFRAME,
MODEL3D,
};

enum class DecalStructure
Expand Down Expand Up @@ -891,10 +892,12 @@ namespace olc
std::vector<olc::vf2d> pos;
std::vector<olc::vf2d> uv;
std::vector<float> w;
std::vector<float> z;
std::vector<olc::Pixel> tint;
olc::DecalMode mode = olc::DecalMode::NORMAL;
olc::DecalStructure structure = olc::DecalStructure::FAN;
uint32_t points = 0;
bool depth = false;
};

struct LayerDesc
Expand Down Expand Up @@ -1139,6 +1142,8 @@ namespace olc
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<olc::Pixel>& colours, const olc::Pixel tint);
void DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<float>& depth, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& colours, const olc::Pixel tint);

// Draws a line in Decal Space
void DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE);
void DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
Expand Down Expand Up @@ -1188,6 +1193,7 @@ namespace olc

// Draws a vector of vertices, interprted as individual triangles
void LW3D_DrawTriangles(olc::Decal* decal, const std::vector<std::array<float,3>>& pos, const std::vector<olc::vf2d>& tex, const std::vector<olc::Pixel>& col);
void LW3D_DrawWarpedDecal(olc::Decal* decal, const std::vector<std::array<float, 3>>& pos, const olc::Pixel& tint);

void LW3D_ModelTranslate(const float x, const float y, const float z);

Expand Down Expand Up @@ -1457,6 +1463,7 @@ namespace olc
// O------------------------------------------------------------------------------O
// | olc::Pixel IMPLEMENTATION |
// O------------------------------------------------------------------------------O
#if !defined(OLC_IGNORE_PIXEL)
Pixel::Pixel()
{ r = 0; g = 0; b = 0; a = nDefaultAlpha; }

Expand Down Expand Up @@ -1567,7 +1574,7 @@ namespace olc

Pixel PixelLerp(const olc::Pixel& p1, const olc::Pixel& p2, float t)
{ return (p2 * t) + p1 * (1.0f - t); }

#endif
// O------------------------------------------------------------------------------O
// | olc::Sprite IMPLEMENTATION |
// O------------------------------------------------------------------------------O
Expand Down Expand Up @@ -3004,6 +3011,27 @@ namespace olc
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}

void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<float>& depth, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& colours, const 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] = colours[i] * tint;
di.w[i] = depth[i];
}
di.mode = nDecalMode;
di.structure = nDecalStructure;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}

#ifdef OLC_ENABLE_EXPERIMENTAL
// Lightweight 3D
void PixelGameEngine::LW3D_DrawTriangles(olc::Decal* decal, const std::vector<std::array<float, 3>>& pos, const std::vector<olc::vf2d>& tex, const std::vector<olc::Pixel>& col)
Expand All @@ -3014,17 +3042,64 @@ namespace olc
di.pos.resize(di.points);
di.uv.resize(di.points);
di.w.resize(di.points);
di.z.resize(di.points);
di.tint.resize(di.points);
for (uint32_t i = 0; i < di.points; i++)
{
di.pos[i] = { pos[i][0], pos[i][1] };
di.w[i] = pos[i][2];
di.z[i] = pos[i][2];
di.uv[i] = tex[i];
di.tint[i] = col[i];
}
di.mode = DecalMode::MODEL3D;
di.mode = nDecalMode;
di.structure = DecalStructure::LIST;
di.depth = true;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}

void PixelGameEngine::LW3D_DrawWarpedDecal(olc::Decal* decal, const std::vector<std::array<float, 3>>& pos, const olc::Pixel& tint)
{
// Thanks Nathan Reed, a brilliant article explaining whats going on here
// http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/
DecalInstance di;
di.points = 4;
di.decal = decal;
di.tint = { tint, tint, tint, tint };
di.w = { 1, 1, 1, 1 };
di.z = { 1, 1, 1, 1 };
di.pos.resize(4);
di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
olc::vf2d center;
float rd = ((pos[2][0] - pos[0][0]) * (pos[3][1] - pos[1][1]) - (pos[3][0] - pos[1][0]) * (pos[2][1] - pos[0][1]));
if (rd != 0)
{
rd = 1.0f / rd;
float rn = ((pos[3][0] - pos[1][0]) * (pos[0][1] - pos[1][1]) - (pos[3][1] - pos[1][1]) * (pos[0][0] - pos[1][0])) * rd;
float sn = ((pos[2][0] - pos[0][0]) * (pos[0][1] - pos[1][1]) - (pos[2][1] - pos[0][1]) * (pos[0][0] - pos[1][0])) * rd;
if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f))
{
center.x = pos[0][0] + rn * (pos[2][0] - pos[0][0]);
center.y = pos[0][1] + rn * (pos[2][1] - pos[0][1]);
}
float d[4];
for (int i = 0; i < 4; i++)
d[i] = std::sqrt((pos[i][0] - center.x) * (pos[i][0] - center.x) + (pos[i][1] - center.y) * (pos[i][1] - center.y));

for (int i = 0; i < 4; i++)
{
float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
di.uv[i] *= q;
di.w[i] *= q;
di.z[i] = pos[i][2];
di.pos[i] = { (pos[i][0] * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i][1] * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f };
}
di.mode = nDecalMode;
di.structure = nDecalStructure;
di.depth = true;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}
}
#endif

void PixelGameEngine::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p)
Expand Down Expand Up @@ -4367,7 +4442,6 @@ namespace olc
switch (mode)
{
case olc::DecalMode::NORMAL:
case olc::DecalMode::MODEL3D:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case olc::DecalMode::ADDITIVE:
Expand Down Expand Up @@ -4415,72 +4489,52 @@ namespace olc
else
glBindTexture(GL_TEXTURE_2D, decal.decal->id);

if (nDecalMode == DecalMode::MODEL3D)
if (decal.depth)
{
#ifdef OLC_ENABLE_EXPERIMENTAL
glMatrixMode(GL_PROJECTION); glPushMatrix();
glMatrixMode(GL_MODELVIEW); glPushMatrix();

glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1, 1000);

#pragma comment (lib, "winmm.lib")
}

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, -40, -200);
glRotatef(float(clock()) * 0.1f, 1, 0, 0);
glRotatef(float(clock()) * 0.1f * 2, 0, 1, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (nDecalMode == DecalMode::WIREFRAME)
glBegin(GL_LINE_LOOP);
else
{
if(decal.structure == olc::DecalStructure::FAN)
glBegin(GL_TRIANGLE_FAN);
else if(decal.structure == olc::DecalStructure::STRIP)
glBegin(GL_TRIANGLE_STRIP);
else if(decal.structure == olc::DecalStructure::LIST)
glBegin(GL_TRIANGLES);
}

glBegin(GL_TRIANGLES);
if (decal.depth)
{

// Render as 3D Spatial Entity
for (uint32_t n = 0; n < decal.points; n++)
{
glColor4ub(decal.tint[n].r, decal.tint[n].g, decal.tint[n].b, decal.tint[n].a);
glTexCoord2f(decal.uv[n].x, decal.uv[n].y);
glVertex3f(decal.pos[n].x, decal.pos[n].y, decal.w[n]);
glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]);
glVertex3f(decal.pos[n].x, decal.pos[n].y, decal.z[n]);
}

glEnd();

glMatrixMode(GL_PROJECTION); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
glDisable(GL_DEPTH_TEST);
#endif
}
else
{
if (nDecalMode == DecalMode::WIREFRAME)
glBegin(GL_LINE_LOOP);
else
{
if(decal.structure == olc::DecalStructure::FAN)
glBegin(GL_TRIANGLE_FAN);
else if(decal.structure == olc::DecalStructure::STRIP)
glBegin(GL_TRIANGLE_STRIP);
else if(decal.structure == olc::DecalStructure::LIST)
glBegin(GL_TRIANGLES);
}

// Render as 2D Spatial entity
for (uint32_t n = 0; n < decal.points; n++)
{
glColor4ub(decal.tint[n].r, decal.tint[n].g, decal.tint[n].b, decal.tint[n].a);
glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]);
glVertex2f(decal.pos[n].x, decal.pos[n].y);
}

glEnd();
}


//glDisable(GL_DEPTH_TEST);
glEnd();

if (decal.depth)
{
glDisable(GL_DEPTH_TEST);
}

}

uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered, const bool clamp) override
Expand Down

0 comments on commit 11b2632

Please sign in to comment.