Skip to content

Commit

Permalink
25.1.17
Browse files Browse the repository at this point in the history
[Engine]
* Break out texture atlas related code into a new module 'atlas.hpp'.
* Remove unneeded 'close()' after 'dup2()' since the latter already does the prior.

[Assets]
* Rebuild API documentation.
  • Loading branch information
Mhatxotic committed Jan 17, 2025
1 parent fbcb69d commit dfd1fd6
Show file tree
Hide file tree
Showing 14 changed files with 445 additions and 284 deletions.
36 changes: 24 additions & 12 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<!-- Reference for the Mhatxotic Engine API version 24.12.5.21 -->
<!-- Automatically built at Fri Jan 03 23:49:51 2025 +0000 -->
<!-- With Mhatxotic Engine Project Management Utility version 24.12.5.21 -->
<!-- Reference for the Mhatxotic Engine API version 25.1.17.15 -->
<!-- Automatically built at Fri Jan 17 00:45:22 2025 +0000 -->
<!-- With Mhatxotic Engine Project Management Utility version 25.1.17.15 -->
<!-- Copyright (c) 2006-2025 Mhatxotic Design, All Rights Reserved Worldwide -->
<HTML lang="en-GB">
<HEAD>
Expand All @@ -11,18 +11,18 @@
<META name="apple-mobile-web-app-title" content="Mhatxotic Engine API">
<META name="author" content="Mhatxotic Design">
<META name="copyright" content="Copyright © 2006-2025 Mhatxotic Design, All Rights Reserved">
<META name="description" content="Reference for the Mhatxotic Engine API version 24.12.5.21">
<META name="description" content="Reference for the Mhatxotic Engine API version 25.1.17.15">
<META name="format-detection" content="telephone=no">
<META name="generator" content="Mhatxotic Engine Project Management Utility version 24.12.5.21">
<META name="generator" content="Mhatxotic Engine Project Management Utility version 25.1.17.15">
<META name="google-site-verification" content="BvWxrqmgaIxqe_W8AW3OGK0fdCI_JfB_-gcOOxCF9_4">
<META name="googlebot" content="index,follow">
<META name="og:description" content="Reference for the Mhatxotic Engine API version 24.12.5.21">
<META name="og:description" content="Reference for the Mhatxotic Engine API version 25.1.17.15">
<META name="og:image" content="https://repository-images.githubusercontent.com/611875607/ee7aa468-9797-4763-9a2d-ea3d782ef413">
<META name="og:title" content="Mhatxotic Engine 24.12.5.21 API reference">
<META name="og:title" content="Mhatxotic Engine 25.1.17.15 API reference">
<META name="og:url" content="https://mhatxotic.github.io/Engine/">
<META name="robots" content="index,follow">
<META name="viewport" content="width=device-width, initial-scale=1">
<TITLE>Mhatxotic Engine 24.12.5.21 API reference</TITLE>
<TITLE>Mhatxotic Engine 25.1.17.15 API reference</TITLE>
<STYLE media="screen">
* { margin:0; padding:0 }
BODY { background-color:#111; border:0; font-family:sans-serif; overflow-x:hidden; text-shadow: 1px 1px #111 }
Expand Down Expand Up @@ -60,7 +60,7 @@
</STYLE>
</HEAD>
<BODY id="idx.top">
<H1>Mhatxotic Engine 24.12.5.21 API reference</H1>
<H1>Mhatxotic Engine 25.1.17.15 API reference</H1>
<NOSCRIPT>
<H2>JavaScript is required to show and hide elements.</H2>
</NOSCRIPT>
Expand Down Expand Up @@ -99,18 +99,19 @@ <H2>JavaScript is required to show and hide elements.</H2>
</SCRIPT>
<DIV id="idx" style="display:none">
<H2>Table of contents:-</H2>
<P>This build of the Mhatxotic Engine API consists of 822 functions (387 members, 435 methods) and 27 consts in 29 namespaces with 83 commands and 207 cvars.</P>
<P>This build of the Mhatxotic Engine API consists of 822 functions (387 members, 435 methods) and 27 consts in 30 namespaces with 83 commands and 207 cvars.</P>
<OL id="toc">
<LI id="idx.ns">
<DIV>
<DIV>
<A href="#idx.ns">Namespaces</A> <I>(29 namespaces)</I>
<A href="#idx.ns">Namespaces</A> <I>(30 namespaces)</I>
<OL>
<LI><P>Categorised functions that interact with the engine.</P></LI>
<LI>
<OL>
<LI><A href="#idx:Archive">Archive</A></LI>
<LI><A href="#idx:Asset">Asset</A></LI>
<LI><A href="#idx:Atlas">Atlas</A></LI>
<LI><A href="#idx:Audio">Audio</A></LI>
<LI><A href="#idx:Bin">Bin</A></LI>
<LI><A href="#idx:Clip">Clip</A></LI>
Expand Down Expand Up @@ -258,6 +259,17 @@ <H2>Table of contents:-</H2>
</DIV>
</DIV>
</LI>
<LI id="idx:Atlas">
<DIV>
<DIV>
<A href="#idx:Atlas">Atlas namespace</A>
<OL>
<LI><P>The atlas class allows dynamic building of an OpenGL texture by collecting library.</P></LI>
<LI><A href="#idx:Atlas">&#x25B2; Return to summary</A> / <A href="#idx.top">top</A></LI>
</OL>
</DIV>
</DIV>
</LI>
<LI id="idx:Audio">
<DIV>
<DIV>
Expand Down Expand Up @@ -12244,6 +12256,6 @@ <H3>win_widthmin</H3>
<H4><A href="#idx.cv">&#x25B2; Return to table of contents</A></H4>
</DIV>
<ADDRESS>Copyright &copy; 2025 Mhatxotic Design, All Rights Reserved.<BR>
This document was generated at Fri Jan 03 23:49:51 2025 +0000</ADDRESS>
This document was generated at Fri Jan 17 00:45:22 2025 +0000</ADDRESS>
</BODY>
</HTML>
259 changes: 259 additions & 0 deletions src/atlas.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
/* == ATLAS.HPP ============================================================ **
** ######################################################################### **
** ## Mhatxotic Engine (c) Mhatxotic Design, All Rights Reserved ## **
** ######################################################################### **
** ## This module allows automatic and manual building of texture atlases ## **
** ######################################################################### **
** ========================================================================= */
#pragma once // Only one incursion allowed
/* ------------------------------------------------------------------------- */
namespace IAtlas { // Start of private namespace
/* -- Dependencies --------------------------------------------------------- */
using namespace IBin::P; using namespace ICollector::P;
using namespace IDim; using namespace IError::P;
using namespace IImageDef::P; using namespace ILog::P;
using namespace ILuaLib::P; using namespace IMemory::P;
using namespace IOgl::P; using namespace IStd::P;
using namespace ISysUtil::P; using namespace ITexture::P;
using namespace IUtil::P; using namespace Lib::OS::GlFW;
/* ------------------------------------------------------------------------- */
namespace P { // Start of public namespace
/* == Atlas collector class for collector data and custom variables ======== */
CTOR_BEGIN_NOBB(Atlases, Atlas, CLHelperUnsafe)
/* == Atlas Variables Class ================================================ */
// Only put vars used in the Atlas class in here. This is an optimisation so
// we do not have to initialise all these variables more than once as we have
// more than one constructor in the main Atlas class.
/* ------------------------------------------------------------------------- */
class AtlasBase : // Members initially private
/* -- Base classes ------------------------------------------------------- */
public Texture // Texture class
{ /* -- Protected typedefs -------------------------------------- */ protected:
typedef Rectangle<GLfloat> RectFloat;// Rectangle of GLfloats
/* -- Variables ---------------------------------------------------------- */
typedef Pack<GLint> IntPack; // Bin pack using GLint
typedef IntPack::Rect IntPackRect; // Bin pack rectangle
typedef Rectangle<GLuint> RectUint; // Reload glyph size
/* --------------------------------------------------------------- */ public:
OglFilterEnum ofeFilter; // Selected texture filter
GLuint uiPadding; // Padding after each glyph
IntPack ipData; // FT packed characters in image
/* -- Reload texture parameters ------------------------------------------ */
enum RTCmd { RT_NONE, RT_FULL, RT_PARTIAL } rtCmd; // Reload texture command
RectUint rRedraw; // Reload cordinates and dimensions
/* -- Default constructor ------------------------------------------------ */
AtlasBase(void) : // No parameters
/* --------------------------------------------------------------------- */
Texture{ true }, ofeFilter(OF_N_N),
uiPadding(0), rtCmd(RT_NONE),
rRedraw{
numeric_limits<GLuint>::max(),
numeric_limits<GLuint>::max(),
0, 0 }
/* --------------------------------------------------------------------- */
{ }
/* ----------------------------------------------------------------------- */
DELETECOPYCTORS(AtlasBase) // Suppress default functions for safety
};/* ----------------------------------------------------------------------- */
/* == Atlas Class (which inherits a Texture) =============================== */
CTOR_MEM_BEGIN(Atlases, Atlas, ICHelperUnsafe, /* n/a */),
/* -- Base classes ------------------------------------------------------- */
public AtlasBase // Atlas variables class
{ /* -- Convert co-ordinates to absolute position -------------- */ protected:
static size_t CoordsToAbsolute(const size_t stPosX,
const size_t stPosY,
const size_t stWidth,
const size_t stBytesPerColumn=1)
{ return ((stPosY * stWidth) + stPosX) * stBytesPerColumn; }
/* -- Check if texture reload required ------------------------ */ protected:
void AtlasCheckReloadTexture(void)
{ // Check reload command
switch(rtCmd)
{ // No reload so just return
case RT_NONE: return;
// Full reload
case RT_FULL:
{ // Reset reload command incase of error
rtCmd = RT_NONE;
// Full reload of texture
ReloadTexture();
// Log that we reuploaded the texture
cLog->LogDebugExSafe("Atlas '$' full texture reload (S:$,$).",
IdentGet(), DimGetWidth(), DimGetHeight());
// Done
return;
} // Partial reload
case RT_PARTIAL:
{ // Reset reload command incase of error
rtCmd = RT_NONE;
// Calculate position to read from in buffer
const size_t stRTPos = CoordsToAbsolute(rRedraw.RectGetX1(),
rRedraw.RectGetY1(), DimGetWidth(), 2);
// Calculate position in buffer to read from
const GLubyte*const ucpSrc =
GetSlots().front().MemRead<GLubyte>(stRTPos, DimGetWidth());
// Update partial texture
UpdateEx(GetSubName(),
rRedraw.RectGetX1<GLint>(), rRedraw.RectGetY1<GLint>(),
static_cast<GLsizei>(rRedraw.RectGetX2() - rRedraw.RectGetX1()),
static_cast<GLsizei>(rRedraw.RectGetY2() - rRedraw.RectGetY1()),
GetPixelType(), ucpSrc, DimGetWidth<GLsizei>());
// Log that we partially reuploaded the texture
cLog->LogDebugExSafe("Atlas '$' partial re-upload (B:$,$,$,$;P:$).",
IdentGet(), rRedraw.RectGetX1(), rRedraw.RectGetY1(),
rRedraw.RectGetX2(), rRedraw.RectGetY2(), stRTPos);
// Reset range parameters
rRedraw.RectSetTopLeft(numeric_limits<GLuint>::max());
rRedraw.RectSetBottomRight(0);
// Done
return;
}
}
}
/* -- Copy procedures ---------------------------------------------------- */
struct AtlasCopy
{ /* -- Copy gray alpha tile --------------------------------------------- */
struct GrayAlpha
{ /* -- Constructor ------------------------------------------------------ */
GrayAlpha(const size_t stSrcWidth,
const size_t stSrcHeight,
const MemConst &mcSrc,
const size_t stDstX,
const size_t stDstY,
const size_t stDstWidth,
Memory &mDst)
{ // For each pixel row of glyph image
for(size_t stPixPosY = 0; stPixPosY < stSrcHeight; ++stPixPosY)
{ // Calculate Y position co-ordinate in buffer.
const size_t stPosY = stDstY + stPixPosY;
// For each pixel column of glyph image
for(size_t stPixPosX = 0; stPixPosX < stSrcWidth; ++stPixPosX)
{ // Calculate X position co-ordinate in buffer.
const size_t stPosX = stDstX + stPixPosX;
// Set the character to write...
// * Step 1: 0xNN (8-bit colour pixel value) converts to...
// * Step 2: 0x00NN (16-bit integer) shift eight bits left...
// * Step 3: 0xNN00 (16-bit integer) set all first eight bits...
// * Step 4: 0xNNFF (16-bit colour alpha pixel value).
// This will obviously need to be revised if compiling on Big-End.
const size_t stSrcPos =
CoordsToAbsolute(stPixPosX, stPixPosY, stSrcWidth);
const uint16_t usPixel = static_cast<uint16_t>(
static_cast<int>(mcSrc.MemReadInt<uint8_t>(stSrcPos)) << 8 |
0xFF);
// ...and the final offset position value
const size_t stDstPos =
CoordsToAbsolute(stPosX, stPosY, stDstWidth, sizeof(usPixel));
// If the paint position is in the tile bounds?
// Copy pixels from source to destination.
mDst.MemWriteInt<uint16_t>(stDstPos, usPixel);
}
}
}
};
};
/* -- Render texture data to memory -------------------------------------- */
template<class CopyType>
void AtlasAddBitmap(const IntPackRect &iprRef,
const size_t stSrcWidth,
const size_t stSrcHeight,
CoordData &cdRef,
const void*const vpSrc,
Memory &mDst)
{ // Get source and destination sizes and return if they're different
const size_t
stDstWidth = iprRef.DimGetWidth<size_t>(),
stDstHeight = iprRef.DimGetHeight<size_t>();
if(stSrcWidth != stDstWidth || stSrcHeight != stDstHeight) return;
// Get destination X and Y position as size_t
const size_t stDstX = iprRef.CoordGetX<size_t>(),
stDstY = iprRef.CoordGetY<size_t>();
// Put glyph data and size in a managed class
const MemConst mcSrc{ stSrcWidth * stSrcHeight, vpSrc };
// Run the requested copy procedure
CopyType(stSrcWidth, stSrcHeight, mcSrc,
stDstX, stDstY, DimGetWidth<size_t>(), mDst);
// Calculate texture bounds
const GLfloat
fMinX = static_cast<GLfloat>(stDstX),
fMinY = static_cast<GLfloat>(stDstY),
fMaxX = fMinX + static_cast<GLfloat>(stSrcWidth),
fMaxY = fMinY + static_cast<GLfloat>(stSrcHeight),
fBW = DimGetWidth<GLfloat>(),
fBH = DimGetHeight<GLfloat>();
// Get reference to first and second triangles
TriCoordData &tcT1 = cdRef[0], &tcT2 = cdRef[1];
// Push opengl tile coords (keep .fW/.fH to zero which is already zero)
tcT1[0] = tcT1[4] = tcT2[2] = fMinX / fBW; // Left
tcT1[1] = tcT1[3] = tcT2[5] = fMinY / fBH; // Top
tcT1[2] = tcT2[0] = tcT2[4] = fMaxX / fBW; // Right
tcT1[5] = tcT2[1] = tcT2[3] = fMaxY / fBH; // Bottom
}
/* -- Initialise the atlas --------------------------------------- */ public:
void AtlasInit(const string &strId,
const GLuint uiTWidth,
const GLuint uiTHeight,
const GLuint uiISize,
const GLuint _uiPadding,
const OglFilterEnum _ofeFilter)
{ // Make sure padding isn't negative. We use int because it is optimal for
// use with the BinPack routines.
if(UtilIntWillOverflow<int>(uiPadding))
XC("Atlas padding size overflows signed integer range!",
"Identifier", strId, "Requested", _uiPadding);
// Initialise base size, padding and opengl filter
uiPadding = _uiPadding;
ofeFilter = _ofeFilter;
// Set initial tile size. This is just for the Texture class.
duiTile.DimSet(uiTWidth, uiTHeight);
// Set initial size of image. The image size starts here and can
// automatically grow by the power of 2 if more space is needed.
DimSet(uiISize ? uiISize :
TextureGetMaxSizeFromBounds(0, 0, uiTWidth, uiTHeight, 1));
// Check if texture size is valid
if(DimGetWidth() > cOgl->MaxTexSize() || uiTWidth > cOgl->MaxTexSize())
XC("Atlas dimensions for font not supported by graphics processor!",
"Identifier", strId, "Requested", uiISize,
"Width", DimGetWidth(), "Height", DimGetHeight(),
"TileWidth", uiTWidth, "TileHeight", uiTHeight,
"Maximum", cOgl->MaxTexSize());
// Estimate how many glyphs we're fitting in here to prevent unnecessary
// alocations
const size_t stGColumns = DimGetWidth() / uiTWidth,
stGRows = DimGetHeight() / uiTHeight,
stGTotal = UtilNearestPow2<size_t>(stGColumns * stGRows);
// Init bin packer so we can tightly pack glyphs together. We're trying to
// guess the size of the rlFree and rlUsed structs are too.
ipData.Init(DimGetWidth(), DimGetHeight(), stGTotal, stGTotal);
// Initialise texture image. Remember it needs to be cleared as the
// parts that are padding will not be written to 'ever' and that would
// cause display artifacts
Memory mPixels{ DimGetWidth() * DimGetHeight() * 2 };
mPixels.MemFill<uint16_t>(0x00FF);
InitRaw(strId, mPixels, DimGetWidth(), DimGetHeight(), BD_GRAYALPHA);
// Initialise image in GL. This class is responsible for updating the
// texture tile co-ords set.
InitImage(*this,
uiTWidth, uiTHeight, uiPadding, uiPadding, ofeFilter, false);
}
/* -- Constructor (Initialisation then registration) --------------------- */
Atlas(void) : // No parameters
/* -- Initialisers ----------------------------------------------------- */
ICHelperAtlas{ cAtlases, this } // Initially registered
/* --------------------------------------------------------------------- */
{ } // Do nothing else
/* -- Constructor (without registration) --------------------------------- */
explicit Atlas(const bool) : // Dummy parameter
/* -- Initialisers ----------------------------------------------------- */
ICHelperAtlas{ cAtlases } // Initially unregistered
/* --------------------------------------------------------------------- */
{ } // Do nothing else
/* ----------------------------------------------------------------------- */
DELETECOPYCTORS(Atlas) // Suppress default functions for safety
};/* ----------------------------------------------------------------------- */
CTOR_END_NOINITS(Atlases, Atlas, ATLAS) // End of collector class
/* ------------------------------------------------------------------------- */
} // End of public module namespace
/* ------------------------------------------------------------------------- */
} // End of private module namespace
/* == EoF =========================================================== EoF == */
Loading

0 comments on commit dfd1fd6

Please sign in to comment.