Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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