From 054d2b58224deeb374c062c4940123741fbf7218 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Mon, 20 May 2024 14:49:26 -0700 Subject: [PATCH 01/13] Generate sprite sheet on the fly. Buildings are drawn in three places now for some odd reason. Fix building showing up three times bug. --- libgag/include/SDLGraphicContext.h | 14 +++++++-- libgag/src/GraphicContext.cpp | 22 +++++++++----- libgag/src/Sprite.cpp | 49 ++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/libgag/include/SDLGraphicContext.h b/libgag/include/SDLGraphicContext.h index fc364c5ce..e78f34d34 100644 --- a/libgag/include/SDLGraphicContext.h +++ b/libgag/include/SDLGraphicContext.h @@ -158,6 +158,7 @@ namespace GAGCore protected: friend struct Color; friend class GraphicContext; + friend class Sprite; //! the underlying software SDL surface SDL_Surface *sdlsurface; //! The clipping rect, we do not draw outside it @@ -166,6 +167,13 @@ namespace GAGCore bool dirty; //! texture index if GPU (GL) is used unsigned int texture; + //! sprite sheet coordinates + int texX = 0; + int texY = 0; + //! width and height if using atlas + int w; + int h; + bool usingAtlas = false; //! texture divisor float texMultX, texMultY; @@ -209,8 +217,8 @@ namespace GAGCore virtual void shiftHSV(float hue, float sat, float lum); // accessors - virtual int getW(void) { return sdlsurface->w; } - virtual int getH(void) { return sdlsurface->h; } + virtual int getW(void) { if (usingAtlas && w) return w; return sdlsurface->w; } + virtual int getH(void) { if (usingAtlas && h) return h; return sdlsurface->h; } // capability querying virtual bool canDrawStretchedSprite(void) { return false; } @@ -420,6 +428,7 @@ namespace GAGCore std::string fileName; std::vector images; std::vector rotated; + DrawableSurface *atlas = nullptr; Color actColor; friend class DrawableSurface; @@ -428,6 +437,7 @@ namespace GAGCore void loadFrame(SDL_RWops *frameStream, SDL_RWops *rotatedStream); //! Check if index is within bound and return true, assert false and return false otherwise bool checkBound(int index); + void createTextureAtlas(); //! Return a rotated drawable surface for actColor, create it if necessary virtual DrawableSurface *getRotatedSurface(int index); diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index 1033c0735..fdce55b15 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -303,6 +303,8 @@ namespace GAGCore void DrawableSurface::allocateTexture(void) { #ifdef HAVE_OPENGL + if (usingAtlas) + return; if (_gc->optionFlags & GraphicContext::USEGPU) { glGenTextures(1, reinterpret_cast(&texture)); @@ -345,6 +347,10 @@ namespace GAGCore void DrawableSurface::uploadToTexture(void) { #ifdef HAVE_OPENGL + if (usingAtlas) + { + return; + } if (_gc->optionFlags & GraphicContext::USEGPU) { glState.setTexture(texture); @@ -1049,22 +1055,22 @@ namespace GAGCore void DrawableSurface::drawSurface(int x, int y, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void DrawableSurface::drawSurface(float x, float y, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void DrawableSurface::drawSurface(int x, int y, int w, int h, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, w, h, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, w, h, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void DrawableSurface::drawSurface(float x, float y, float w, float h, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, w, h, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, w, h, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void DrawableSurface::drawSurface(int x, int y, DrawableSurface *surface, int sx, int sy, int sw, int sh, Uint8 alpha) @@ -1617,22 +1623,22 @@ namespace GAGCore void GraphicContext::drawSurface(int x, int y, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void GraphicContext::drawSurface(float x, float y, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void GraphicContext::drawSurface(int x, int y, int w, int h, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, w, h, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, w, h, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void GraphicContext::drawSurface(float x, float y, float w, float h, DrawableSurface *surface, Uint8 alpha) { - drawSurface(x, y, w, h, surface, 0, 0, surface->getW(), surface->getH(), alpha); + drawSurface(x, y, w, h, surface, surface->texX, surface->texY, surface->getW(), surface->getH(), alpha); } void GraphicContext::drawSurface(int x, int y, DrawableSurface *surface, int sx, int sy, int sw, int sh, Uint8 alpha) diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index 5293e3f35..b7aca3b8c 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -67,9 +67,58 @@ namespace GAGCore SDL_RWclose(rotatedStream); i++; } + if (!images.empty()) + createTextureAtlas(); return getFrameCount() > 0; } + + // Create texture atlas for images array + void Sprite::createTextureAtlas() + { + size_t numImages = images.size(); + int w = 0, h = 0; + for (auto image : images) + { + if (!image) + return; + if (!w || !h) + { + w = image->getW(); + h = image->getH(); + } + if (image->getW() != w || image->getH() != h) + return; + } + int tileWidth = images[0]->getW(); + int tileHeight = images[0]->getH(); + int sheetWidth = tileWidth * (sqrt(numImages) + 1); + int sheetHeight = tileHeight * (sqrt(numImages) + 1); + atlas = new DrawableSurface(sheetWidth, sheetHeight); + int x = 0, y = 0; + for (auto image: images) + { + atlas->drawSurface(x, y, image); + image->texX = x; + image->texY = y; + image->texMultX = 1.f; + image->texMultY = 1.f; + image->w = tileWidth; + image->h = tileHeight; + x += tileWidth; + if (sheetWidth - x < tileWidth) { + x = 0; + y += tileHeight; + } + } + atlas->uploadToTexture(); + for (auto image : images) + { + image->texture = atlas->texture; + image->usingAtlas = true; + image->setRes(sheetWidth, sheetHeight); + } + } DrawableSurface *Sprite::getRotatedSurface(int index) { From 1d92a769e265ab37ab7d34c0a323a51f5c382fbf Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Mon, 20 May 2024 21:57:43 -0700 Subject: [PATCH 02/13] Prepare for a potential speedup with glDrawArrays. --- libgag/src/GraphicContext.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index fdce55b15..c5e567e8d 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -1684,11 +1684,24 @@ namespace GAGCore glState.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glState.doBlend(true); glState.doTexture(true); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glColor4ub(255, 255, 255, alpha); // draw glState.setTexture(surface->texture); - glBegin(GL_QUADS); + float vertices[8] = { x, y, x + w, y, x + w, y + h, x, y + h }; + float texCoords[8] = { static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY, + static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY, + static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY, + static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY + }; + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glDrawArrays(GL_QUADS, 0, 4); + assert(!glGetError()); + //glDrawElements(GL_QUADS, 4, GL_FLOAT, ); + /*glBegin(GL_QUADS); glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY); glVertex2f(x, y); glTexCoord2f(static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY); @@ -1697,7 +1710,10 @@ namespace GAGCore glVertex2f(x+w, y+h); glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY); glVertex2f(x, y+h); - glEnd(); + glEnd();*/ + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } else #endif From 9b01b1dfad0f483081e93a13447dba2320940be9 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:47:33 -0700 Subject: [PATCH 03/13] More efficient sprite drawing. Doesn't compile yet because of a purportedly missing > when compiling native.h. --- libgag/include/SDLGraphicContext.h | 14 ++++++++++ libgag/src/GraphicContext.cpp | 44 ++++++++++++++++++++++++++---- libgag/src/Sprite.cpp | 26 ++++++++++++++++++ src/Game.cpp | 4 ++- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/libgag/include/SDLGraphicContext.h b/libgag/include/SDLGraphicContext.h index e78f34d34..bcec7e4a8 100644 --- a/libgag/include/SDLGraphicContext.h +++ b/libgag/include/SDLGraphicContext.h @@ -161,6 +161,8 @@ namespace GAGCore friend class Sprite; //! the underlying software SDL surface SDL_Surface *sdlsurface; + //! which animation or texture atlas this surface is part of. + Sprite* sprite = nullptr; //! The clipping rect, we do not draw outside it SDL_Rect clipRect; //! this surface has been modified since latest blit @@ -383,6 +385,8 @@ namespace GAGCore virtual void drawSurface(int x, int y, int w, int h, DrawableSurface *surface, int sx, int sy, int sw, int sh, Uint8 alpha = Color::ALPHA_OPAQUE); virtual void drawSurface(float x, float y, float w, float h, DrawableSurface *surface, int sx, int sy, int sw, int sh, Uint8 alpha = Color::ALPHA_OPAQUE); + + void finishDrawingSprite(Sprite* sprite, Uint8 alpha); virtual void drawAlphaMap(const std::valarray &map, int mapW, int mapH, int x, int y, int cellW, int cellH, const Color &color); virtual void drawAlphaMap(const std::valarray &map, int mapW, int mapH, int x, int y, int cellW, int cellH, const Color &color); @@ -424,11 +428,21 @@ namespace GAGCore RotatedImage(DrawableSurface *s) { orig = s; } ~RotatedImage(); }; + + friend class GraphicContext; std::string fileName; std::vector images; std::vector rotated; + + // Sprite sheet stuff to efficiently draw terrain/water/units. +#ifdef HAVE_OPENGL + std::vector vertices; + std::vector texCoords; + unsigned int vbo; + unsigned int texCoordBuffer; DrawableSurface *atlas = nullptr; +#endif Color actColor; friend class DrawableSurface; diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index c5e567e8d..46eb7ddea 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -37,6 +37,7 @@ #include #endif +#define GL_GLEXT_PROTOTYPES #ifdef HAVE_OPENGL #if defined(__APPLE__) || defined(OPENGL_HEADER_DIRECTORY_OPENGL) #include @@ -1690,16 +1691,14 @@ namespace GAGCore // draw glState.setTexture(surface->texture); - float vertices[8] = { x, y, x + w, y, x + w, y + h, x, y + h }; - float texCoords[8] = { static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY, + std::vector vertices = { x, y, x + w, y, x + w, y + h, x, y + h }; + std::vector texCoords = { static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY, static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY, static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY, static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY }; - glVertexPointer(2, GL_FLOAT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - glDrawArrays(GL_QUADS, 0, 4); - assert(!glGetError()); + surface->sprite->vertices.insert(surface->sprite->vertices.end(), vertices.begin(), vertices.end()); + surface->sprite->texCoords.insert(surface->sprite->texCoords.end(), texCoords.begin(), texCoords.end()); //glDrawElements(GL_QUADS, 4, GL_FLOAT, ); /*glBegin(GL_QUADS); glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY); @@ -1720,6 +1719,39 @@ namespace GAGCore DrawableSurface::drawSurface(static_cast(x), static_cast(y), static_cast(w), static_cast(h), surface, sx, sy, sw, sh, alpha); } + // Lets us efficiently draw terrain and water. + void GraphicContext::finishDrawingSprite(Sprite* sprite, Uint8 alpha) + { +#ifdef HAVE_OPENGL + if (_gc->optionFlags & GraphicContext::USEGPU) + { + // state change + glState.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glState.doBlend(true); + glState.doTexture(true); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glColor4ub(255, 255, 255, alpha); + glState.setTexture(sprite->atlas->texture); + glBindBuffer(GL_ARRAY_BUFFER, sprite->vbo); + glBufferData(GL_ARRAY_BUFFER, sprite->vertices.size() * sizeof(float), &sprite->vertices[0], GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, sprite->texCoordBuffer); + glBufferData(GL_ARRAY_BUFFER, sprite->texCoords.size() * sizeof(float), &sprite->texCoords[0], GL_STREAM_DRAW); + + glVertexPointer(2, GL_FLOAT, 0, &sprite->vertices[0]); + glTexCoordPointer(2, GL_FLOAT, 0, &sprite->texCoords[0]); + glDrawArrays(GL_QUADS, 0, sprite->vertices.size() / 4); + + sprite->vertices.clear(); + sprite->texCoords.clear(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } +#endif + } + void GraphicContext::drawAlphaMap(const std::valarray &map, int mapW, int mapH, int x, int y, int cellW, int cellH, const Color &color) { #ifdef HAVE_OPENGL diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index b7aca3b8c..d15d2ae33 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -27,6 +27,24 @@ #include #include +#define GL_GLEXT_PROTOTYPES +#ifdef HAVE_OPENGL +#if defined(__APPLE__) || defined(OPENGL_HEADER_DIRECTORY_OPENGL) +#include +#include +#include +#define GL_TEXTURE_RECTANGLE_NV GL_TEXTURE_RECTANGLE_EXT +#else +#include +#include +#endif +#endif + +#ifdef WIN32 +#include +#endif + + namespace GAGCore { Sprite::RotatedImage::~RotatedImage() @@ -74,8 +92,11 @@ namespace GAGCore } // Create texture atlas for images array + // Using a sprite sheet lets us efficiently drawn terrain and water with a few calls + // to glDrawArrays, rather than 272 individual calls to glBegin...glEnd. void Sprite::createTextureAtlas() { +#ifdef HAVE_OPENGL size_t numImages = images.size(); int w = 0, h = 0; for (auto image : images) @@ -116,8 +137,12 @@ namespace GAGCore { image->texture = atlas->texture; image->usingAtlas = true; + image->sprite = this; image->setRes(sheetWidth, sheetHeight); } + glGenBuffers(1, &vbo); + glGenBuffers(1, &texCoordBuffer); +#endif } DrawableSurface *Sprite::getRotatedSurface(int index) @@ -159,6 +184,7 @@ namespace GAGCore if (*rotatedIt) delete (*rotatedIt); } + delete atlas; } void Sprite::loadFrame(SDL_RWops *frameStream, SDL_RWops *rotatedStream) diff --git a/src/Game.cpp b/src/Game.cpp index df3dab5ae..5904dc2bf 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1971,6 +1971,8 @@ inline void Game::drawMapTerrain(int left, int top, int right, int bot, int view Uint32 visibleTeams = teams[localTeam]->me; if (globalContainer->replaying) visibleTeams = globalContainer->replayVisibleTeams; + Sprite* sprite; + // we draw the terrains, eventually with debug rects: for (int y=top; y<=bot; y++) for (int x=left; x<=right; x++) @@ -1985,7 +1987,6 @@ inline void Game::drawMapTerrain(int left, int top, int right, int bot, int view { // draw terrain int id=map.getTerrain(x+viewportX, y+viewportY); - Sprite *sprite; if (id<272) { sprite=globalContainer->terrain; @@ -1999,6 +2000,7 @@ inline void Game::drawMapTerrain(int left, int top, int right, int bot, int view if ((id < 256) || (id >= 256+16)) globalContainer->gfx->drawSprite(x<<5, y<<5, sprite, id); } + globalContainer->gfx->finishDrawingSprite(globalContainer->terrain, 255); } inline void Game::drawMapRessources(int left, int top, int right, int bot, int viewportX, int viewportY, int localTeam, Uint32 drawOptions) From e7b66a1d158c16ac0c1208c6e7e8b9565d119a41 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:54:37 -0700 Subject: [PATCH 04/13] Inline the initializer lists into vector::insert. Creating and deleting two std::vectors for every sprite draw during every frame took a total of 7s over a profiling run of about 3 minutes. Fix null pointer deref if no sprite or atlas. Fix terrain drawing in-game. Fix nothing to draw causing crash in finishDrawingSprite. --- libgag/src/GraphicContext.cpp | 66 ++++++++++++++++++++--------------- src/Game.cpp | 1 + src/Glob2Screen.cpp | 1 + 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index 46eb7ddea..2f96b27f7 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -1685,34 +1685,33 @@ namespace GAGCore glState.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glState.doBlend(true); glState.doTexture(true); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); glColor4ub(255, 255, 255, alpha); // draw glState.setTexture(surface->texture); - std::vector vertices = { x, y, x + w, y, x + w, y + h, x, y + h }; - std::vector texCoords = { static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY, - static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY, - static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY, - static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY - }; - surface->sprite->vertices.insert(surface->sprite->vertices.end(), vertices.begin(), vertices.end()); - surface->sprite->texCoords.insert(surface->sprite->texCoords.end(), texCoords.begin(), texCoords.end()); - //glDrawElements(GL_QUADS, 4, GL_FLOAT, ); - /*glBegin(GL_QUADS); - glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY); - glVertex2f(x, y); - glTexCoord2f(static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY); - glVertex2f(x+w, y); - glTexCoord2f(static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY); - glVertex2f(x+w, y+h); - glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY); - glVertex2f(x, y+h); - glEnd();*/ - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (surface->sprite && alpha == Color::ALPHA_OPAQUE) + { + surface->sprite->vertices.insert(surface->sprite->vertices.end(), { x, y, x + w, y, x + w, y + h, x, y + h }); + surface->sprite->texCoords.insert(surface->sprite->texCoords.end(), { + static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY, + static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY, + static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY, + static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY + }); + } + else + { + glBegin(GL_QUADS); + glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy) * surface->texMultY); + glVertex2f(x, y); + glTexCoord2f(static_cast(sx + sw) * surface->texMultX, static_cast(sy) * surface->texMultY); + glVertex2f(x + w, y); + glTexCoord2f(static_cast(sx + sw) * surface->texMultX, static_cast(sy + sh) * surface->texMultY); + glVertex2f(x + w, y + h); + glTexCoord2f(static_cast(sx) * surface->texMultX, static_cast(sy + sh) * surface->texMultY); + glVertex2f(x, y + h); + glEnd(); + } } else #endif @@ -1725,6 +1724,18 @@ namespace GAGCore #ifdef HAVE_OPENGL if (_gc->optionFlags & GraphicContext::USEGPU) { + if (!sprite->atlas) + { + // No sprite sheet, so we have nothing to draw. + assert(!sprite->vertices.size()); + assert(!sprite->texCoords.size()); + return; + } + if (sprite->vertices.empty() || sprite->texCoords.empty()) + { + // No data. + return; + } // state change glState.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glState.doBlend(true); @@ -1735,12 +1746,11 @@ namespace GAGCore glState.setTexture(sprite->atlas->texture); glBindBuffer(GL_ARRAY_BUFFER, sprite->vbo); glBufferData(GL_ARRAY_BUFFER, sprite->vertices.size() * sizeof(float), &sprite->vertices[0], GL_STREAM_DRAW); + glVertexPointer(2, GL_FLOAT, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, sprite->texCoordBuffer); glBufferData(GL_ARRAY_BUFFER, sprite->texCoords.size() * sizeof(float), &sprite->texCoords[0], GL_STREAM_DRAW); - - glVertexPointer(2, GL_FLOAT, 0, &sprite->vertices[0]); - glTexCoordPointer(2, GL_FLOAT, 0, &sprite->texCoords[0]); - glDrawArrays(GL_QUADS, 0, sprite->vertices.size() / 4); + glTexCoordPointer(2, GL_FLOAT, 0, 0); + glDrawArrays(GL_QUADS, 0, sprite->vertices.size() / 2); sprite->vertices.clear(); sprite->texCoords.clear(); diff --git a/src/Game.cpp b/src/Game.cpp index 5904dc2bf..d0cd630a7 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -2041,6 +2041,7 @@ inline void Game::drawMapRessources(int left, int top, int right, int bot, int v globalContainer->gfx->drawSprite((x<<5)-dx, (y<<5)-dy, sprite, imgid); } } + globalContainer->gfx->finishDrawingSprite(globalContainer->ressources, 255); } inline void Game::drawMapGroundUnits(int left, int top, int right, int bot, int sw, int sh, int viewportX, int viewportY, int localTeam, Uint32 drawOptions) diff --git a/src/Glob2Screen.cpp b/src/Glob2Screen.cpp index 790ed8f01..18df84270 100644 --- a/src/Glob2Screen.cpp +++ b/src/Glob2Screen.cpp @@ -41,6 +41,7 @@ void Glob2Screen::paint(void) for (int y = 0; y < getH(); y += 32) for (int x = 0; x < getW(); x += 32) gfx->drawSprite(x, y, globalContainer->terrain, getNextTerrain()); + dynamic_cast(gfx)->finishDrawingSprite(globalContainer->terrain, 255); if ((globalContainer->settings.optionFlags & GlobalContainer::OPTION_LOW_SPEED_GFX) == 0) { From bde87da12b91a28659dfdc645edecfdf24c8d0f5 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Sat, 25 May 2024 19:25:24 -0700 Subject: [PATCH 05/13] Fixed Boost error I was stuck on for two days. --- libusl/src/native.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libusl/src/native.h b/libusl/src/native.h index 3af05fbfc..876cbf4a3 100644 --- a/libusl/src/native.h +++ b/libusl/src/native.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -42,7 +43,7 @@ struct NativeValuePrototype: Prototype template void addMethod(const std::string& name, const boost::function& function) { - BOOST_MPL_ASSERT(( boost::is_same::arg1_type> )); + BOOST_MPL_ASSERT(( boost::is_same::arg1_type> )); NativeCode* native = new NativeFunction(name, function, true); Prototype::addMethod(native); } From 4685eaad2d4fb0f7ce076ef77b86a10dbeac0900 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Mon, 27 May 2024 11:03:21 -0700 Subject: [PATCH 06/13] Fix loading screen and Settings menu. Fix water not being drawn. Fix flags, zones, and building rendering. Fix fog of war; missing icons when placing building. Fix brush selection not showing up in flag view. Draw zone animations. Fix bullets not showing up. --- libgag/src/Sprite.cpp | 3 ++- src/Brush.cpp | 2 ++ src/Game.cpp | 8 ++++++++ src/GameGUI.cpp | 2 ++ src/GameGUIToolManager.cpp | 1 + src/Glob2Screen.cpp | 1 + src/GlobalContainer.cpp | 1 + 7 files changed, 17 insertions(+), 1 deletion(-) diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index d15d2ae33..4a83bd520 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -85,7 +85,8 @@ namespace GAGCore SDL_RWclose(rotatedStream); i++; } - if (!images.empty()) + // TODO: How to cache rotated images? + if (!images.empty() && rotated.empty()) createTextureAtlas(); return getFrameCount() > 0; diff --git a/src/Brush.cpp b/src/Brush.cpp index 757994fea..03ded5e9f 100644 --- a/src/Brush.cpp +++ b/src/Brush.cpp @@ -47,6 +47,8 @@ void BrushTool::draw(int x, int y) if ((mode != MODE_NONE) && (figure == i)) globalContainer->gfx->drawSprite(x+decX, y+decY, globalContainer->gamegui, 22); } + globalContainer->gfx->finishDrawingSprite(globalContainer->brush, 255); + globalContainer->gfx->finishDrawingSprite(globalContainer->gamegui, 255); } void BrushTool::handleClick(int x, int y) diff --git a/src/Game.cpp b/src/Game.cpp index d0cd630a7..7a8fbdad0 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1964,6 +1964,7 @@ inline void Game::drawMapWater(int sw, int sh, int viewportX, int viewportY, int for (int y=waterStartY; ygfx->drawSprite(x, y, globalContainer->terrainWater, 0); + globalContainer->gfx->finishDrawingSprite(globalContainer->terrainWater, 255); } inline void Game::drawMapTerrain(int left, int top, int right, int bot, int viewportX, int viewportY, int localTeam, Uint32 drawOptions) @@ -2226,6 +2227,7 @@ inline void Game::drawMapBuilding(int x, int y, int gid, int viewportX, int view // draw building globalContainer->gfx->drawSprite(x+dx, y+dy, buildingSprite, imgid); + globalContainer->gfx->finishDrawingSprite(buildingSprite, 255); if ((drawOptions & DRAW_BUILDING_RECT) != 0) { @@ -2459,6 +2461,7 @@ inline void Game::drawMapArea(int left, int top, int right, int bot, int sw, } } } + globalContainer->gfx->finishDrawingSprite(sprite, 255); } inline void Game::drawMapAirUnits(int left, int top, int right, int bot, int sw, int sh, int viewportX, int viewportY, int localTeam, Uint32 drawOptions) @@ -2541,6 +2544,7 @@ inline void Game::drawMapBulletsExplosionsDeathAnimations(int left, int top, int globalContainer->gfx->drawSprite(x+(balisticShift>>1), y, bulletSprite, BULLET_IMGID+1); } } + globalContainer->gfx->finishDrawingSprite(bulletSprite, 255); // explosions for (std::list::iterator it=s->explosions.begin();it!=s->explosions.end();it++) { @@ -2554,6 +2558,7 @@ inline void Game::drawMapBulletsExplosionsDeathAnimations(int left, int top, int globalContainer->gfx->drawSprite(x+16-decX, y+16-decY, globalContainer->bulletExplosion, frame); } } + globalContainer->gfx->finishDrawingSprite(globalContainer->bulletExplosion, 255); // death animations for (std::list::iterator it=s->deathAnimations.begin();it!=s->deathAnimations.end();++it) { @@ -2570,6 +2575,7 @@ inline void Game::drawMapBulletsExplosionsDeathAnimations(int left, int top, int globalContainer->gfx->drawSprite(x+16-decX, y+16-decY-frame, globalContainer->deathAnimation, frame); } } + globalContainer->gfx->finishDrawingSprite(globalContainer->deathAnimation, 255); } } @@ -2621,6 +2627,8 @@ inline void Game::drawMapFogOfWar(int left, int top, int right, int bot, int sw, globalContainer->gfx->drawSprite((x<<5)+16, (y<<5)+16, globalContainer->terrainShader, shadeValue); } } + globalContainer->gfx->finishDrawingSprite(globalContainer->terrainBlack, 255); + globalContainer->gfx->finishDrawingSprite(globalContainer->terrainShader, 255); } } diff --git a/src/GameGUI.cpp b/src/GameGUI.cpp index 55dfd7e52..cfca77c44 100644 --- a/src/GameGUI.cpp +++ b/src/GameGUI.cpp @@ -2744,6 +2744,7 @@ void GameGUI::drawChoice(int pos, std::vector &types, std::vectorsetBaseColor(localTeam->color); globalContainer->gfx->drawSprite(x+decX, y+decY, buildingSprite, imgid); + globalContainer->gfx->finishDrawingSprite(buildingSprite, 255); globalContainer->gfx->setClipRect(); if(hilights.find(HilightBuildingOnPanel+IntBuildingType::shortNumberFromType(type)) != hilights.end()) @@ -3953,6 +3954,7 @@ void GameGUI::drawFlagView(void) int decX = 8 + ((int)toolManager.getZoneType()) * 40 + dec; globalContainer->gfx->drawSprite(globalContainer->gfx->getW()-RIGHT_MENU_WIDTH+decX, YPOS_BASE_FLAG+YOFFSET_BRUSH, globalContainer->gamegui, 22); } + globalContainer->gfx->finishDrawingSprite(globalContainer->gamegui, 255); if(hilights.find(HilightForbiddenZoneOnPanel) != hilights.end()) { arrowPositions.push_back(HilightArrowPosition(globalContainer->gfx->getW()-RIGHT_MENU_WIDTH-36+8+dec, YPOS_BASE_FLAG+YOFFSET_BRUSH, 38)); diff --git a/src/GameGUIToolManager.cpp b/src/GameGUIToolManager.cpp index 4074a709d..cef8e3e5e 100644 --- a/src/GameGUIToolManager.cpp +++ b/src/GameGUIToolManager.cpp @@ -442,6 +442,7 @@ void GameGUIToolManager::drawBuildingAt(int mapX, int mapY, int localteam, int v sprite->setBaseColor(game.teams[localteam]->color); int spriteIntensity = 127+static_cast(128.0f*splineInterpolation(1.f, 0.f, 1.f, hilightStrength)); globalContainer->gfx->drawSprite(batX, batY, sprite, bt->gameSpriteImage, spriteIntensity); + globalContainer->gfx->finishDrawingSprite(sprite, spriteIntensity); if (!bt->isVirtual) { diff --git a/src/Glob2Screen.cpp b/src/Glob2Screen.cpp index 18df84270..7be7afc70 100644 --- a/src/Glob2Screen.cpp +++ b/src/Glob2Screen.cpp @@ -82,6 +82,7 @@ void Glob2TabScreen::paint(void) for (int y = 0; y < getH(); y += 32) for (int x = 0; x < getW(); x += 32) gfx->drawSprite(x, y, globalContainer->terrain, getNextTerrain()); + dynamic_cast(gfx)->finishDrawingSprite(globalContainer->terrain, 255); if ((globalContainer->settings.optionFlags & GlobalContainer::OPTION_LOW_SPEED_GFX) == 0) { diff --git a/src/GlobalContainer.cpp b/src/GlobalContainer.cpp index a44e2cd52..7ae9d1337 100644 --- a/src/GlobalContainer.cpp +++ b/src/GlobalContainer.cpp @@ -500,6 +500,7 @@ void GlobalContainer::updateLoadProgressScreen(int value) index = ((randomSeed >> 16) & 0xF) + 128; gfx->drawSprite(x, y, terrain, index); } + gfx->finishDrawingSprite(terrain, 255); //gfx->drawFilledRect(0, 0, gfx->getW(), gfx->getH(), Color::black); gfx->drawSurface((gfx->getW()-title->getW())>>1, (gfx->getH()-title->getH())>>1, title); //gfx->drawFilledRect(((gfx->getW()-400)>>1), (gfx->getH()>>1)+11+180, (value)<<2, 20, 10, 50, 255, 80); From f6c0f8875339c3ca1ebfa32dd8ca2a05f15f0d0d Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:44:14 -0700 Subject: [PATCH 07/13] Use Epoxy so that we can access OpenGL 2 functions. --- libgag/src/GraphicContext.cpp | 6 ++++++ libgag/src/Sprite.cpp | 16 +++++++------- vcpkg.json | 39 ++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index 2f96b27f7..cd10d897a 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -25,6 +25,12 @@ #include #include #include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif #include "SDL_ttf.h" #include #include diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index 4a83bd520..a37a7bb7e 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -35,14 +35,14 @@ #include #define GL_TEXTURE_RECTANGLE_NV GL_TEXTURE_RECTANGLE_EXT #else -#include -#include -#endif -#endif - -#ifdef WIN32 -#include -#endif +#include +#ifdef _MSC_VER +#include +#else +#include +#endif // _MSC_VER +#endif // defined(__APPLE__) +#endif // ifdef HAVE_OPENGL namespace GAGCore diff --git a/vcpkg.json b/vcpkg.json index 46727ce93..b9b38ff00 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,23 +3,24 @@ "name": "globulation2", "license": "GPL-3.0", "version": "0.9.5.0", - "dependencies": [ - "sdl2", - "sdl2-net", - "sdl2-ttf", - "sdl2-image", - "zlib", - "fribidi", - "libogg", - "libvorbis", - "boost-math", - "boost-thread", - "boost-date-time", - "boost-random", - "boost-logic", - "boost-lambda", - "speex", - "opengl", - "pcre" - ] + "dependencies": [ + "sdl2", + "sdl2-net", + "sdl2-ttf", + "sdl2-image", + "zlib", + "fribidi", + "libogg", + "libvorbis", + "boost-math", + "boost-thread", + "boost-date-time", + "boost-random", + "boost-logic", + "boost-lambda", + "speex", + "opengl", + "libepoxy", + "pcre" + ] } From 0dbb307ae82da5fb5dce7224f5310106a888da5c Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:50:27 -0700 Subject: [PATCH 08/13] Add Epoxy to Debian build dependencies. --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 8d254ee57..77571b1ff 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: glob2 Section: games Priority: optional Maintainer: Stephane Magnenat -Build-Depends: debhelper (>> 6.0.0), quilt (>= 0.40), scons, libsdl2-dev (>=2.0.0), libsdl2-image-dev (>=2.0.0), libsdl2-net-dev (>=2.0.0), libsdl2-ttf-dev, libglu1-mesa-dev | libglu-dev, libvorbis-dev, libspeex-dev, libfreetype6-dev, libboost-dev, libboost-thread-dev, libboost-date-time-dev, libfribidi-dev, portaudio19-dev, libboost-math-dev +Build-Depends: debhelper (>> 6.0.0), quilt (>= 0.40), scons, libsdl2-dev (>=2.0.0), libsdl2-image-dev (>=2.0.0), libsdl2-net-dev (>=2.0.0), libsdl2-ttf-dev, libglu1-mesa-dev | libglu-dev, libvorbis-dev, libspeex-dev, libfreetype6-dev, libboost-dev, libboost-thread-dev, libboost-date-time-dev, libfribidi-dev, portaudio19-dev, libboost-math-dev, libepoxy-dev Standards-Version: 3.8.1 Homepage: http://globulation2.org From 3cb04f46e9e4204dc2606639954ca6129d94ed80 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:39:35 -0700 Subject: [PATCH 09/13] Look for epoxy in SConstruct. Link against Epoxy. --- SConstruct | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SConstruct b/SConstruct index 8476b3a46..e6ac52ec0 100644 --- a/SConstruct +++ b/SConstruct @@ -193,6 +193,13 @@ def configure(env, server_only): configfile.add("HAVE_OPENGL ", "Defined when OpenGL support is present and compiled") env.Append(LIBS=gl_libraries) + if not server_only: + if conf.CheckLib('epoxy') and conf.CheckCXXHeader('epoxy/gl.h'): + env.Append(LIBS=["epoxy"]) + else: + print("Could not find epoxy/gl.h") + missing.append("epoxy") + #Do checks for fribidi if not server_only and conf.CheckLib('fribidi') and conf.CheckCXXHeader('fribidi/fribidi.h'): configfile.add("HAVE_FRIBIDI ", "Defined when FRIBIDI support is present and compiled") From ba5177a5b192b9fd2ca74ce066e0ef4522f58d07 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Thu, 27 Jun 2024 20:12:03 -0700 Subject: [PATCH 10/13] Check that we have at least one non-NULL image. If all the images in the array are NULL, we don't need to create a texture atlas/sprite sheet. --- libgag/src/Sprite.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index a37a7bb7e..2b7b8f5e6 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -86,8 +86,10 @@ namespace GAGCore i++; } // TODO: How to cache rotated images? - if (!images.empty() && rotated.empty()) + if (std::any_of(images.begin(), images.end(), [](DrawableSurface *s) {return s != nullptr; })) + { createTextureAtlas(); + } return getFrameCount() > 0; } @@ -114,8 +116,8 @@ namespace GAGCore } int tileWidth = images[0]->getW(); int tileHeight = images[0]->getH(); - int sheetWidth = tileWidth * (sqrt(numImages) + 1); - int sheetHeight = tileHeight * (sqrt(numImages) + 1); + int sheetWidth = tileWidth * (static_cast(sqrt(numImages)) + 1); + int sheetHeight = tileHeight * (static_cast(sqrt(numImages)) + 1); atlas = new DrawableSurface(sheetWidth, sheetHeight); int x = 0, y = 0; for (auto image: images) From 01151a83347af3f84430221008e62389b53a5c1a Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Mon, 29 Jul 2024 21:05:12 -0700 Subject: [PATCH 11/13] Make createTextureAtlas more exception-safe. Changes Sprite::atlas variable to be a unique_ptr and adds a bunch of preprocessor macros to find the right make_unique for the C++ and Boost version. --- libgag/include/SDLGraphicContext.h | 2 +- libgag/src/Sprite.cpp | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libgag/include/SDLGraphicContext.h b/libgag/include/SDLGraphicContext.h index bcec7e4a8..5b8dedbd7 100644 --- a/libgag/include/SDLGraphicContext.h +++ b/libgag/include/SDLGraphicContext.h @@ -441,7 +441,7 @@ namespace GAGCore std::vector texCoords; unsigned int vbo; unsigned int texCoordBuffer; - DrawableSurface *atlas = nullptr; + std::unique_ptr atlas = nullptr; #endif Color actColor; diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index 2b7b8f5e6..efb8529c5 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -27,6 +27,22 @@ #include #include +#if __cplusplus >= 201402L +#include +using std::make_unique; +#else +#if BOOST_VERSION >= 107500 +#include +#elif BOOST_VERSION >= 106300 +#include +#elif BOOST_VERSION >= 105700 +#include +#else +#error "Can't make_unique when there's no Boost and C++ standard is earlier than C++14" +#endif +using boost::make_unique; +#endif // __cplusplus + #define GL_GLEXT_PROTOTYPES #ifdef HAVE_OPENGL #if defined(__APPLE__) || defined(OPENGL_HEADER_DIRECTORY_OPENGL) @@ -118,7 +134,7 @@ namespace GAGCore int tileHeight = images[0]->getH(); int sheetWidth = tileWidth * (static_cast(sqrt(numImages)) + 1); int sheetHeight = tileHeight * (static_cast(sqrt(numImages)) + 1); - atlas = new DrawableSurface(sheetWidth, sheetHeight); + atlas = make_unique(sheetWidth, sheetHeight); int x = 0, y = 0; for (auto image: images) { @@ -187,7 +203,6 @@ namespace GAGCore if (*rotatedIt) delete (*rotatedIt); } - delete atlas; } void Sprite::loadFrame(SDL_RWops *frameStream, SDL_RWops *rotatedStream) From 5a340b2bcfe0510523c4ea364da6bbe2d586c2e4 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:15:21 -0700 Subject: [PATCH 12/13] Remove unnecessary usingAtlas boolean. --- libgag/include/SDLGraphicContext.h | 11 +++++------ libgag/src/GraphicContext.cpp | 4 ++-- libgag/src/Sprite.cpp | 1 - 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/libgag/include/SDLGraphicContext.h b/libgag/include/SDLGraphicContext.h index 5b8dedbd7..cc6ad107d 100644 --- a/libgag/include/SDLGraphicContext.h +++ b/libgag/include/SDLGraphicContext.h @@ -172,10 +172,9 @@ namespace GAGCore //! sprite sheet coordinates int texX = 0; int texY = 0; - //! width and height if using atlas - int w; - int h; - bool usingAtlas = false; + //! width and height of this tile if using atlas + int w = 0; + int h = 0; //! texture divisor float texMultX, texMultY; @@ -219,8 +218,8 @@ namespace GAGCore virtual void shiftHSV(float hue, float sat, float lum); // accessors - virtual int getW(void) { if (usingAtlas && w) return w; return sdlsurface->w; } - virtual int getH(void) { if (usingAtlas && h) return h; return sdlsurface->h; } + virtual int getW(void) { if (sprite) return w; return sdlsurface->w; } + virtual int getH(void) { if (sprite) return h; return sdlsurface->h; } // capability querying virtual bool canDrawStretchedSprite(void) { return false; } diff --git a/libgag/src/GraphicContext.cpp b/libgag/src/GraphicContext.cpp index cd10d897a..221ef2e0b 100644 --- a/libgag/src/GraphicContext.cpp +++ b/libgag/src/GraphicContext.cpp @@ -310,7 +310,7 @@ namespace GAGCore void DrawableSurface::allocateTexture(void) { #ifdef HAVE_OPENGL - if (usingAtlas) + if (sprite) return; if (_gc->optionFlags & GraphicContext::USEGPU) { @@ -354,7 +354,7 @@ namespace GAGCore void DrawableSurface::uploadToTexture(void) { #ifdef HAVE_OPENGL - if (usingAtlas) + if (sprite) { return; } diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index efb8529c5..ffbec675d 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -155,7 +155,6 @@ namespace GAGCore for (auto image : images) { image->texture = atlas->texture; - image->usingAtlas = true; image->sprite = this; image->setRes(sheetWidth, sheetHeight); } From 0dfc8bdc47e621cb67b84df6214bce8e930564e6 Mon Sep 17 00:00:00 2001 From: Nathan Mills <38995150+Quipyowert2@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:55:33 -0700 Subject: [PATCH 13/13] Prevent drawing on atlas once generated by making it readonly. --- libgag/include/SDLGraphicContext.h | 2 +- libgag/src/Sprite.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libgag/include/SDLGraphicContext.h b/libgag/include/SDLGraphicContext.h index cc6ad107d..2c42a2fb8 100644 --- a/libgag/include/SDLGraphicContext.h +++ b/libgag/include/SDLGraphicContext.h @@ -440,7 +440,7 @@ namespace GAGCore std::vector texCoords; unsigned int vbo; unsigned int texCoordBuffer; - std::unique_ptr atlas = nullptr; + std::unique_ptr atlas = nullptr; #endif Color actColor; diff --git a/libgag/src/Sprite.cpp b/libgag/src/Sprite.cpp index ffbec675d..6cdef83a7 100644 --- a/libgag/src/Sprite.cpp +++ b/libgag/src/Sprite.cpp @@ -134,7 +134,7 @@ namespace GAGCore int tileHeight = images[0]->getH(); int sheetWidth = tileWidth * (static_cast(sqrt(numImages)) + 1); int sheetHeight = tileHeight * (static_cast(sqrt(numImages)) + 1); - atlas = make_unique(sheetWidth, sheetHeight); + std::unique_ptr atlas = make_unique(sheetWidth, sheetHeight); int x = 0, y = 0; for (auto image: images) { @@ -158,6 +158,7 @@ namespace GAGCore image->sprite = this; image->setRes(sheetWidth, sheetHeight); } + this->atlas = std::move(atlas); glGenBuffers(1, &vbo); glGenBuffers(1, &texCoordBuffer); #endif