33 olcPixelGameEngine.h
44
55 +-------------------------------------------------------------+
6- | OneLoneCoder Pixel Game Engine v2.24 |
6+ | OneLoneCoder Pixel Game Engine v2.25 |
77 | "What do you need? Pixels... Lots of Pixels..." - javidx9 |
88 +-------------------------------------------------------------+
99
319319 2.23: Fixed Emscripten host sizing errors - Thanks Moros
320320 Fixed v2d_generic.clamp() function
321321 2.24: Fix FillTexturedTriangle() to remove const-ref
322+ 2.25: +DrawPolygonDecal(pos, tex, w, col)
322323
323324 !! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !!
324325 !! Volunteers willing to help appreciated, though PRs are manually integrated with credit !!
@@ -398,7 +399,7 @@ int main()
398399#include < cstring>
399400#pragma endregion
400401
401- #define PGE_VER 224
402+ #define PGE_VER 225
402403
403404// O------------------------------------------------------------------------------O
404405// | COMPILER CONFIGURATION ODDITIES |
@@ -579,6 +580,7 @@ namespace olc
579580 // O------------------------------------------------------------------------------O
580581 // | olc::Pixel - Represents a 32-Bit RGBA colour |
581582 // O------------------------------------------------------------------------------O
583+ #if !defined(OLC_IGNORE_PIXEL)
582584 struct Pixel
583585 {
584586 union
@@ -624,7 +626,7 @@ namespace olc
624626 BLUE(0 , 0 , 255 ), DARK_BLUE(0 , 0 , 128 ), VERY_DARK_BLUE(0 , 0 , 64 ),
625627 MAGENTA(255 , 0 , 255 ), DARK_MAGENTA(128 , 0 , 128 ), VERY_DARK_MAGENTA(64 , 0 , 64 ),
626628 WHITE(255 , 255 , 255 ), BLACK(0 , 0 , 0 ), BLANK(0 , 0 , 0 , 0 );
627-
629+ # endif
628630 // Thanks to scripticuk and others for updating the key maps
629631 // NOTE: The GLUT platform will need updating, open to contributions ;)
630632 enum Key
@@ -850,7 +852,6 @@ namespace olc
850852 STENCIL,
851853 ILLUMINATE,
852854 WIREFRAME,
853- MODEL3D,
854855 };
855856
856857 enum class DecalStructure
@@ -891,10 +892,12 @@ namespace olc
891892 std::vector<olc::vf2d> pos;
892893 std::vector<olc::vf2d> uv;
893894 std::vector<float > w;
895+ std::vector<float > z;
894896 std::vector<olc::Pixel> tint;
895897 olc::DecalMode mode = olc::DecalMode::NORMAL;
896898 olc::DecalStructure structure = olc::DecalStructure::FAN;
897899 uint32_t points = 0 ;
900+ bool depth = false ;
898901 };
899902
900903 struct LayerDesc
@@ -1139,6 +1142,8 @@ namespace olc
11391142 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);
11401143 void DrawPolygonDecal (olc::Decal* decal, const std::vector<olc::vf2d>& pos, const std::vector<olc::vf2d>& uv, const std::vector<olc::Pixel>& tint);
11411144 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);
1145+ 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);
1146+
11421147 // Draws a line in Decal Space
11431148 void DrawLineDecal (const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE);
11441149 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 });
@@ -1188,6 +1193,7 @@ namespace olc
11881193
11891194 // Draws a vector of vertices, interprted as individual triangles
11901195 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);
1196+ void LW3D_DrawWarpedDecal (olc::Decal* decal, const std::vector<std::array<float , 3 >>& pos, const olc::Pixel& tint);
11911197
11921198 void LW3D_ModelTranslate (const float x, const float y, const float z);
11931199
@@ -1457,6 +1463,7 @@ namespace olc
14571463 // O------------------------------------------------------------------------------O
14581464 // | olc::Pixel IMPLEMENTATION |
14591465 // O------------------------------------------------------------------------------O
1466+ #if !defined(OLC_IGNORE_PIXEL)
14601467 Pixel::Pixel ()
14611468 { r = 0 ; g = 0 ; b = 0 ; a = nDefaultAlpha; }
14621469
@@ -1567,7 +1574,7 @@ namespace olc
15671574
15681575 Pixel PixelLerp (const olc::Pixel& p1, const olc::Pixel& p2, float t)
15691576 { return (p2 * t) + p1 * (1 .0f - t); }
1570-
1577+ # endif
15711578 // O------------------------------------------------------------------------------O
15721579 // | olc::Sprite IMPLEMENTATION |
15731580 // O------------------------------------------------------------------------------O
@@ -3004,6 +3011,27 @@ namespace olc
30043011 vLayers[nTargetLayer].vecDecalInstance .push_back (di);
30053012 }
30063013
3014+ 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)
3015+ {
3016+ DecalInstance di;
3017+ di.decal = decal;
3018+ di.points = uint32_t (pos.size ());
3019+ di.pos .resize (di.points );
3020+ di.uv .resize (di.points );
3021+ di.w .resize (di.points );
3022+ di.tint .resize (di.points );
3023+ for (uint32_t i = 0 ; i < di.points ; i++)
3024+ {
3025+ di.pos [i] = { (pos[i].x * vInvScreenSize.x ) * 2 .0f - 1 .0f , ((pos[i].y * vInvScreenSize.y ) * 2 .0f - 1 .0f ) * -1 .0f };
3026+ di.uv [i] = uv[i];
3027+ di.tint [i] = colours[i] * tint;
3028+ di.w [i] = depth[i];
3029+ }
3030+ di.mode = nDecalMode;
3031+ di.structure = nDecalStructure;
3032+ vLayers[nTargetLayer].vecDecalInstance .push_back (di);
3033+ }
3034+
30073035#ifdef OLC_ENABLE_EXPERIMENTAL
30083036 // Lightweight 3D
30093037 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)
@@ -3014,17 +3042,64 @@ namespace olc
30143042 di.pos .resize (di.points );
30153043 di.uv .resize (di.points );
30163044 di.w .resize (di.points );
3045+ di.z .resize (di.points );
30173046 di.tint .resize (di.points );
30183047 for (uint32_t i = 0 ; i < di.points ; i++)
30193048 {
30203049 di.pos [i] = { pos[i][0 ], pos[i][1 ] };
30213050 di.w [i] = pos[i][2 ];
3051+ di.z [i] = pos[i][2 ];
30223052 di.uv [i] = tex[i];
30233053 di.tint [i] = col[i];
30243054 }
3025- di.mode = DecalMode::MODEL3D;
3055+ di.mode = nDecalMode;
3056+ di.structure = DecalStructure::LIST;
3057+ di.depth = true ;
30263058 vLayers[nTargetLayer].vecDecalInstance .push_back (di);
30273059 }
3060+
3061+ void PixelGameEngine::LW3D_DrawWarpedDecal (olc::Decal* decal, const std::vector<std::array<float , 3 >>& pos, const olc::Pixel& tint)
3062+ {
3063+ // Thanks Nathan Reed, a brilliant article explaining whats going on here
3064+ // http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/
3065+ DecalInstance di;
3066+ di.points = 4 ;
3067+ di.decal = decal;
3068+ di.tint = { tint, tint, tint, tint };
3069+ di.w = { 1 , 1 , 1 , 1 };
3070+ di.z = { 1 , 1 , 1 , 1 };
3071+ di.pos .resize (4 );
3072+ di.uv = { { 0 .0f , 0 .0f }, {0 .0f , 1 .0f }, {1 .0f , 1 .0f }, {1 .0f , 0 .0f } };
3073+ olc::vf2d center;
3074+ 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 ]));
3075+ if (rd != 0 )
3076+ {
3077+ rd = 1 .0f / rd;
3078+ 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;
3079+ 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;
3080+ if (!(rn < 0 .f || rn > 1 .f || sn < 0 .f || sn > 1 .f ))
3081+ {
3082+ center.x = pos[0 ][0 ] + rn * (pos[2 ][0 ] - pos[0 ][0 ]);
3083+ center.y = pos[0 ][1 ] + rn * (pos[2 ][1 ] - pos[0 ][1 ]);
3084+ }
3085+ float d[4 ];
3086+ for (int i = 0 ; i < 4 ; i++)
3087+ d[i] = std::sqrt ((pos[i][0 ] - center.x ) * (pos[i][0 ] - center.x ) + (pos[i][1 ] - center.y ) * (pos[i][1 ] - center.y ));
3088+
3089+ for (int i = 0 ; i < 4 ; i++)
3090+ {
3091+ float q = d[i] == 0 .0f ? 1 .0f : (d[i] + d[(i + 2 ) & 3 ]) / d[(i + 2 ) & 3 ];
3092+ di.uv [i] *= q;
3093+ di.w [i] *= q;
3094+ di.z [i] = pos[i][2 ];
3095+ di.pos [i] = { (pos[i][0 ] * vInvScreenSize.x ) * 2 .0f - 1 .0f , ((pos[i][1 ] * vInvScreenSize.y ) * 2 .0f - 1 .0f ) * -1 .0f };
3096+ }
3097+ di.mode = nDecalMode;
3098+ di.structure = nDecalStructure;
3099+ di.depth = true ;
3100+ vLayers[nTargetLayer].vecDecalInstance .push_back (di);
3101+ }
3102+ }
30283103#endif
30293104
30303105 void PixelGameEngine::DrawLineDecal (const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p)
@@ -4367,7 +4442,6 @@ namespace olc
43674442 switch (mode)
43684443 {
43694444 case olc::DecalMode::NORMAL:
4370- case olc::DecalMode::MODEL3D:
43714445 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
43724446 break ;
43734447 case olc::DecalMode::ADDITIVE:
@@ -4415,72 +4489,52 @@ namespace olc
44154489 else
44164490 glBindTexture (GL_TEXTURE_2D, decal.decal ->id );
44174491
4418- if (nDecalMode == DecalMode::MODEL3D )
4492+ if (decal. depth )
44194493 {
4420- #ifdef OLC_ENABLE_EXPERIMENTAL
4421- glMatrixMode (GL_PROJECTION); glPushMatrix ();
4422- glMatrixMode (GL_MODELVIEW); glPushMatrix ();
4423-
44244494 glEnable (GL_DEPTH_TEST);
4425- glMatrixMode (GL_PROJECTION);
4426- glLoadIdentity ();
4427- glFrustum (-1 .0f , 1 .0f , -1 .0f , 1 .0f , 1 , 1000 );
4428-
4429- #pragma comment (lib, "winmm.lib")
4495+ }
44304496
4431- glMatrixMode (GL_MODELVIEW);
4432- glLoadIdentity ();
4433- glTranslatef (0 , -40 , -200 );
4434- glRotatef (float (clock ()) * 0 .1f , 1 , 0 , 0 );
4435- glRotatef (float (clock ()) * 0 .1f * 2 , 0 , 1 , 0 );
4436- glEnable (GL_BLEND);
4437- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4497+ if (nDecalMode == DecalMode::WIREFRAME)
4498+ glBegin (GL_LINE_LOOP);
4499+ else
4500+ {
4501+ if (decal.structure == olc::DecalStructure::FAN)
4502+ glBegin (GL_TRIANGLE_FAN);
4503+ else if (decal.structure == olc::DecalStructure::STRIP)
4504+ glBegin (GL_TRIANGLE_STRIP);
4505+ else if (decal.structure == olc::DecalStructure::LIST)
4506+ glBegin (GL_TRIANGLES);
4507+ }
44384508
4439- glBegin (GL_TRIANGLES);
4440-
4509+ if (decal. depth )
4510+ {
44414511
44424512 // Render as 3D Spatial Entity
44434513 for (uint32_t n = 0 ; n < decal.points ; n++)
44444514 {
44454515 glColor4ub (decal.tint [n].r , decal.tint [n].g , decal.tint [n].b , decal.tint [n].a );
4446- glTexCoord2f (decal.uv [n].x , decal.uv [n].y );
4447- glVertex3f (decal.pos [n].x , decal.pos [n].y , decal.w [n]);
4516+ glTexCoord4f (decal.uv [n].x , decal.uv [n].y , 0 . 0f , decal. w [n] );
4517+ glVertex3f (decal.pos [n].x , decal.pos [n].y , decal.z [n]);
44484518 }
4449-
4450- glEnd ();
4451-
4452- glMatrixMode (GL_PROJECTION); glPopMatrix ();
4453- glMatrixMode (GL_MODELVIEW); glPopMatrix ();
4454- glDisable (GL_DEPTH_TEST);
4455- #endif
44564519 }
44574520 else
44584521 {
4459- if (nDecalMode == DecalMode::WIREFRAME)
4460- glBegin (GL_LINE_LOOP);
4461- else
4462- {
4463- if (decal.structure == olc::DecalStructure::FAN)
4464- glBegin (GL_TRIANGLE_FAN);
4465- else if (decal.structure == olc::DecalStructure::STRIP)
4466- glBegin (GL_TRIANGLE_STRIP);
4467- else if (decal.structure == olc::DecalStructure::LIST)
4468- glBegin (GL_TRIANGLES);
4469- }
4470-
44714522 // Render as 2D Spatial entity
44724523 for (uint32_t n = 0 ; n < decal.points ; n++)
44734524 {
44744525 glColor4ub (decal.tint [n].r , decal.tint [n].g , decal.tint [n].b , decal.tint [n].a );
44754526 glTexCoord4f (decal.uv [n].x , decal.uv [n].y , 0 .0f , decal.w [n]);
44764527 glVertex2f (decal.pos [n].x , decal.pos [n].y );
44774528 }
4478-
4479- glEnd ();
44804529 }
4481-
44824530
4483- // glDisable(GL_DEPTH_TEST);
4531+ glEnd ();
4532+
4533+ if (decal.depth )
4534+ {
4535+ glDisable (GL_DEPTH_TEST);
4536+ }
4537+
44844538 }
44854539
44864540 uint32_t CreateTexture (const uint32_t width, const uint32_t height, const bool filtered, const bool clamp) override
0 commit comments