diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index efa0f0582..ac36002c8 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -2346,19 +2346,119 @@ template void _loadVBO(GLuint &vbo,std::vector buf,int target=GL_ } } -void Renderer::MapRenderer::Layer::load_vbos() { - _loadVBO(vbo_vertices,vertices); - _loadVBO(vbo_normals,normals); - _loadVBO(vbo_fowTexCoords,fowTexCoords); - _loadVBO(vbo_surfTexCoords,surfTexCoords); +void Renderer::MapRenderer::Layer::load_vbos(bool vboEnabled) { indexCount = indices.size(); - _loadVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB); + if(vboEnabled) { + _loadVBO(vbo_vertices,vertices); + _loadVBO(vbo_normals,normals); + _loadVBO(vbo_fowTexCoords,fowTexCoords); + _loadVBO(vbo_surfTexCoords,surfTexCoords); + + _loadVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB); + } + else { + vbo_vertices = 0; + vbo_normals = 0; + vbo_fowTexCoords = 0; + vbo_surfTexCoords = 0; + vbo_indices = 0; + } +} + +//int32 CalculatePixelsCRC(const Texture2DGl *texture) { +// const uint8 *pixels = static_cast(texture->getPixmapConst())->getPixels(); +// uint64 pixelByteCount = static_cast(texture->getPixmapConst())->getPixelByteCount(); +// Checksum crc; +// for(uint64 i = 0; i < pixelByteCount; ++i) { +// crc.addByte(pixels[i]); +// } +// +// return crc.getSum(); +//} + +void Renderer::MapRenderer::loadVisibleLayers(float coordStep,VisibleQuadContainerCache &qCache) { + int totalCellCount = 0; + // we create a layer for each visible texture in the map + for(int visibleIndex = 0; + visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + + totalCellCount++; + + SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); + SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y); + SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1); + SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1); + + const Vec2f &surfCoord= tc00->getSurfTexCoord(); + + SurfaceCell *tc[4] = { + tc00, + tc10, + tc01, + tc11 + }; + int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); + string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); + //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); + Layer* layer = NULL; + for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) { + if((*it)->textureHandle == textureHandle) { + //if((*it)->texturePath == texturePath) { + //if((*it)->textureCRC == textureCRC) { + layer = *it; + break; + } + } + if(!layer) { + layer = new Layer(textureHandle); + layer->texturePath = texturePath; + //layer->textureCRC = textureCRC; + layers.push_back(layer); + + //printf("Ading new unique texture [%s]\n",texturePath.c_str()); + } + // we'll be super-lazy and re-emit all four corners just because its easier + int index[4]; + int loopIndexes[4] = { 2,0,3,1 }; + for(int i=0; i < 4; i++) { + index[i] = layer->vertices.size(); + SurfaceCell *corner = tc[loopIndexes[i]]; + + layer->vertices.push_back(corner->getVertex()); + layer->normals.push_back(corner->getNormal()); + layer->fowTexCoords.push_back(corner->getFowTexCoord()); + } + + layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y)); + + // and make two triangles (no strip, we may be disjoint) + layer->indices.push_back(index[0]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[2]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[3]); + layer->indices.push_back(index[2]); + + } + // turn them into vbos (actually this method will just calc the index count) + for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){ + (*layer)->load_vbos(false); + } + + //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); } void Renderer::MapRenderer::load(float coordStep) { + int totalCellCount = 0; // we create a layer for each texture in the map for(int y=0; ygetSurfaceH()-1; y++) { for(int x=0; xgetSurfaceW()-1; x++) { + totalCellCount++; + SurfaceCell *tc[4] = { map->getSurfaceCell(x,y), map->getSurfaceCell(x+1,y), @@ -2366,16 +2466,24 @@ void Renderer::MapRenderer::load(float coordStep) { map->getSurfaceCell(x+1,y+1) }; int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); + string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); + //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); Layer* layer = NULL; for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) { if((*it)->textureHandle == textureHandle) { + //if((*it)->texturePath == texturePath) { + //if((*it)->textureCRC == textureCRC) { layer = *it; break; } } if(!layer) { layer = new Layer(textureHandle); + layer->texturePath = texturePath; + //layer->textureCRC = textureCRC; layers.push_back(layer); + + //printf("Ading new unique texture [%s]\n",texturePath.c_str()); } // we'll be super-lazy and re-emit all four corners just because its easier int index[4]; @@ -2397,6 +2505,9 @@ void Renderer::MapRenderer::load(float coordStep) { layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,0)); layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,coordStep)); layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,0)); + + layer->cellToIndicesMap[Vec2i(x,y)] = layer->indices.size(); + // and make two triangles (no strip, we may be disjoint) layer->indices.push_back(index[0]); layer->indices.push_back(index[1]); @@ -2408,8 +2519,10 @@ void Renderer::MapRenderer::load(float coordStep) { } // turn them into vbos for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){ - (*layer)->load_vbos(); + (*layer)->load_vbos(true); } + + //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); } template void* _bindVBO(GLuint vbo,std::vector buf,int target=GL_ARRAY_BUFFER_ARB) { @@ -2421,26 +2534,143 @@ template void* _bindVBO(GLuint vbo,std::vector buf,int target=GL_ } } -void Renderer::MapRenderer::Layer::render() { - glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); - glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); +void Renderer::MapRenderer::Layer::renderVisibleLayer() { + + //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + glClientActiveTexture(Renderer::fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0,&fowTexCoords[0]); + + glBindTexture(GL_TEXTURE_2D, textureHandle); + glClientActiveTexture(Renderer::baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, &surfTexCoords[0]); + + glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + + //glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); + //unsigned short faceIndices[4] = {0, 1, 2, 3}; + //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); + glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,&indices[0]); glClientActiveTexture(Renderer::fowTexUnit); - glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); - + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(Renderer::baseTexUnit); - glBindTexture(GL_TEXTURE_2D,textureHandle); - glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + + + +// glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); +// glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); +// +// glClientActiveTexture(Renderer::fowTexUnit); +// glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); +// +// glClientActiveTexture(Renderer::baseTexUnit); +// glBindTexture(GL_TEXTURE_2D,textureHandle); +// glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); +// +// //glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); +// glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); +// //unsigned short faceIndices[4] = {0, 1, 2, 3}; +// //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); - glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); } -void Renderer::MapRenderer::render(const Map* map,float coordStep) { +void Renderer::MapRenderer::Layer::render(VisibleQuadContainerCache &qCache) { + const bool renderOnlyVisibleQuad = true; + + if(renderOnlyVisibleQuad == true) { + int startIndex = -1; + int lastValidIndex = -1; + + vector > rowsToRender; + + if(rowsToRenderCache.find(qCache.lastVisibleQuad) != rowsToRenderCache.end()) { + rowsToRender = rowsToRenderCache[qCache.lastVisibleQuad]; + } + else { + for(int visibleIndex = 0; + visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + + if(cellToIndicesMap.find(pos) != cellToIndicesMap.end()) { + //printf("Layer Render, visibleindex = %d pos [%s] cellToIndicesMap[pos] = %d lastValidIndex = %d\n",visibleIndex,pos.getString().c_str(),cellToIndicesMap[pos],lastValidIndex); + + if(startIndex < 0 || cellToIndicesMap[pos] == lastValidIndex + 6) { + lastValidIndex = cellToIndicesMap[pos]; + if(startIndex < 0) { + startIndex = lastValidIndex; + } + } + else if(startIndex >= 0) { + rowsToRender.push_back(make_pair(startIndex,lastValidIndex)); + + lastValidIndex = cellToIndicesMap[pos]; + startIndex = lastValidIndex; + } + } + } + if(startIndex >= 0) { + rowsToRender.push_back(make_pair(startIndex,lastValidIndex)); + } + + rowsToRenderCache[qCache.lastVisibleQuad] = rowsToRender; + } + + if(rowsToRender.size() > 0) { + //printf("Layer has %d rows in visible quad, visible quad has %d cells\n",rowsToRender.size(),qCache.visibleScaledCellList.size()); + + glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); + glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); + + glClientActiveTexture(Renderer::fowTexUnit); + glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); + + glClientActiveTexture(Renderer::baseTexUnit); + glBindTexture(GL_TEXTURE_2D,textureHandle); + glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); + + for(unsigned int i = 0; i < rowsToRender.size(); ++i) { + //glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); + glDrawRangeElements(GL_TRIANGLES,rowsToRender[i].first,rowsToRender[i].second,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); + } + } + } + else { + glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); + glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); + + glClientActiveTexture(Renderer::fowTexUnit); + glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); + + glClientActiveTexture(Renderer::baseTexUnit); + glBindTexture(GL_TEXTURE_2D,textureHandle); + glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); + + glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); + } +} + +void Renderer::MapRenderer::renderVisibleLayers(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) { if(map != this->map) { + //printf("New Map loading\n"); destroy(); // clear any previous map data this->map = map; - load(coordStep); + loadVisibleLayers(coordStep,qCache); } + else if(lastVisibleQuad != qCache.lastVisibleQuad) { + //printf("New Visible Quad loading\n"); + destroy(); // clear any previous map data + this->map = map; + loadVisibleLayers(coordStep,qCache); + } + + lastVisibleQuad = qCache.lastVisibleQuad; + //printf("About to render %d layers\n",layers.size()); + glClientActiveTexture(fowTexUnit); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(baseTexUnit); @@ -2448,7 +2678,37 @@ void Renderer::MapRenderer::render(const Map* map,float coordStep) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer) - (*layer)->render(); + (*layer)->renderVisibleLayer(); + glDisableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER_ARB,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); + glDisableClientState(GL_NORMAL_ARRAY); + glClientActiveTexture(fowTexUnit); + glBindTexture(GL_TEXTURE_2D,0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glBindTexture(GL_TEXTURE_2D,0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + assertGl(); +} + +void Renderer::MapRenderer::render(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) { + if(map != this->map) { + destroy(); // clear any previous map data + this->map = map; + load(coordStep); + } + + //printf("About to render %d layers\n",layers.size()); + + glClientActiveTexture(fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer) + (*layer)->render(qCache); glDisableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER_ARB,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); @@ -2525,7 +2785,9 @@ void Renderer::renderSurface(const int renderFps) { bool useVBORendering = getVBOSupported(); if(useVBORendering == true) { - mapRenderer.render(map,coordStep); + VisibleQuadContainerCache &qCache = getQuadCache(); + //mapRenderer.render(map,coordStep,qCache); + mapRenderer.renderVisibleLayers(map,coordStep,qCache); } else if(qCache.visibleScaledCellList.size() > 0) { @@ -2543,6 +2805,18 @@ void Renderer::renderSurface(const int renderFps) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); + std::map uniqueVisibleTextures; + for(int visibleIndex = 0; + visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); + int cellTex= static_cast(tc00->getSurfaceTexture())->getHandle(); + + uniqueVisibleTextures[cellTex]++; + } + + //printf("Current renders = %d possible = %d\n",qCache.visibleScaledCellList.size(),uniqueVisibleTextures.size()); + for(int visibleIndex = 0; visibleIndex < qCache.visibleScaledCellList.size(); ++visibleIndex) { Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index fd3258e95..0b24de17c 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -289,10 +289,13 @@ private: public: MapRenderer(): map(NULL) {} ~MapRenderer() { destroy(); } - void render(const Map* map,float coordStep); + void render(const Map* map,float coordStep,VisibleQuadContainerCache &qCache); + void renderVisibleLayers(const Map* map,float coordStep,VisibleQuadContainerCache &qCache); void destroy(); private: void load(float coordStep); + void loadVisibleLayers(float coordStep,VisibleQuadContainerCache &qCache); + const Map* map; struct Layer { Layer(int th): @@ -301,19 +304,27 @@ private: vbo_indices(0), indexCount(0), textureHandle(th) {} ~Layer(); - void load_vbos(); - void render(); + void load_vbos(bool vboEnabled); + void render(VisibleQuadContainerCache &qCache); + void renderVisibleLayer(); + std::vector vertices, normals; std::vector fowTexCoords, surfTexCoords; std::vector indices; + std::map cellToIndicesMap; + std::map > > rowsToRenderCache; + GLuint vbo_vertices, vbo_normals, vbo_fowTexCoords, vbo_surfTexCoords, vbo_indices; int indexCount; const int textureHandle; + string texturePath; + int32 textureCRC; }; typedef std::vector Layers; Layers layers; + Quad2i lastVisibleQuad; } mapRenderer; private: Renderer(); diff --git a/source/shared_lib/include/graphics/pixmap.h b/source/shared_lib/include/graphics/pixmap.h index b069e703e..7a77b4d56 100644 --- a/source/shared_lib/include/graphics/pixmap.h +++ b/source/shared_lib/include/graphics/pixmap.h @@ -16,6 +16,7 @@ #include "vec.h" #include "types.h" #include +#include "checksum.h" #include "leak_dumper.h" using std::string; @@ -27,6 +28,7 @@ using Shared::Platform::int32; using Shared::Platform::uint32; using Shared::Platform::uint64; using Shared::Platform::float32; +using Shared::Util::Checksum; namespace Shared{ namespace Graphics{ @@ -188,6 +190,7 @@ protected: int components; uint8 *pixels; string path; + Checksum crc; public: //constructor & destructor @@ -210,6 +213,8 @@ public: void deletePixels(); string getPath() const { return path;} uint64 getPixelByteCount() const; + + Checksum * getCRC() { return &crc; } }; // ===================================================== @@ -223,6 +228,8 @@ protected: int components; uint8 *pixels; string path; + Checksum crc; + public: //constructor & destructor Pixmap2D(); @@ -289,6 +296,8 @@ public: string getPath() const { return path;} uint64 getPixelByteCount() const; + Checksum * getCRC() { return &crc; } + private: bool doDimensionsAgree(const Pixmap2D *pixmap); }; @@ -306,6 +315,7 @@ protected: int slice; uint8 *pixels; string path; + Checksum crc; public: //constructor & destructor @@ -333,6 +343,8 @@ public: void deletePixels(); string getPath() const { return path;} uint64 getPixelByteCount() const; + + Checksum * getCRC() { return &crc; } }; // ===================================================== @@ -353,6 +365,7 @@ public: protected: Pixmap2D faces[6]; string path[6]; + Checksum crc; public: //init @@ -370,6 +383,8 @@ public: void deletePixels(); string getPath(int face) const { return path[face];} uint64 getPixelByteCount() const; + + Checksum * getCRC() { return &crc; } }; }}//end namespace diff --git a/source/shared_lib/include/graphics/texture.h b/source/shared_lib/include/graphics/texture.h index 7f55e1a54..9e6dc91d5 100644 --- a/source/shared_lib/include/graphics/texture.h +++ b/source/shared_lib/include/graphics/texture.h @@ -90,6 +90,8 @@ public: virtual void setForceCompressionDisabled(bool value) { forceCompressionDisabled = value;} virtual bool getForceCompressionDisabled() const {return forceCompressionDisabled;} + virtual uint32 getCRC() = 0; + }; // ===================================================== @@ -112,6 +114,7 @@ public: virtual int getTextureWidth() const {return pixmap.getW();} virtual int getTextureHeight() const {return -1;} + virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } }; // ===================================================== @@ -133,6 +136,8 @@ public: virtual int getTextureWidth() const {return pixmap.getW();} virtual int getTextureHeight() const {return pixmap.getH();} + + virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } }; // ===================================================== @@ -154,6 +159,8 @@ public: virtual int getTextureWidth() const {return pixmap.getW();} virtual int getTextureHeight() const {return pixmap.getH();} + + virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } }; // ===================================================== @@ -175,6 +182,8 @@ public: virtual int getTextureWidth() const {return -1;} virtual int getTextureHeight() const {return -1;} + + virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } }; }}//end namespace diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index c1760e4d8..62ab3b03c 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -85,6 +85,13 @@ struct TargaFileHeader{ const int tgaUncompressedRgb= 2; const int tgaUncompressedBw= 3; +void CalculatePixelsCRC(uint8 *pixels,uint64 pixelByteCount, Checksum &crc) { +// crc = Checksum(); +// for(uint64 i = 0; i < pixelByteCount; ++i) { +// crc.addByte(pixels[i]); +// } +} + // ===================================================== // class PixmapIoTga // ===================================================== @@ -732,12 +739,14 @@ void Pixmap1D::init(int components){ this->w= -1; this->components= components; pixels= NULL; + CalculatePixelsCRC(pixels,0, crc); } void Pixmap1D::init(int w, int components){ this->w= w; this->components= components; pixels= new uint8[(std::size_t)getPixelByteCount()]; + CalculatePixelsCRC(pixels,0, crc); } uint64 Pixmap1D::getPixelByteCount() const { @@ -765,6 +774,7 @@ void Pixmap1D::load(const string &path) { throw runtime_error("Unknown pixmap extension: " + extension); } this->path = path; + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap1D::loadBmp(const string &path) { @@ -862,6 +872,7 @@ void Pixmap2D::init(int components) { this->components= components; deletePixels(); pixels= NULL; + CalculatePixelsCRC(pixels,0, crc); } void Pixmap2D::init(int w, int h, int components) { @@ -876,6 +887,7 @@ void Pixmap2D::init(int w, int h, int components) { throw runtime_error(szBuf); } pixels= new uint8[(std::size_t)getPixelByteCount()]; + CalculatePixelsCRC(pixels,0, crc); } uint64 Pixmap2D::getPixelByteCount() const { @@ -909,6 +921,7 @@ void Pixmap2D::Scale(int format, int newW, int newH) { assertGl(); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } Pixmap2D* Pixmap2D::loadPath(const string& path) { @@ -917,6 +930,7 @@ Pixmap2D* Pixmap2D::loadPath(const string& path) { Pixmap2D *pixmap = FileReader::readPath(path); if(pixmap != NULL) { pixmap->path = path; + CalculatePixelsCRC(pixmap->pixels,pixmap->getPixelByteCount(), pixmap->crc); } return pixmap; } @@ -925,6 +939,7 @@ void Pixmap2D::load(const string &path) { //printf("Loading Pixmap2D [%s]\n",path.c_str()); FileReader::readPath(path,this); + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); this->path = path; } @@ -1024,6 +1039,7 @@ void Pixmap2D::setPixel(int x, int y, const uint8 *value) { int index = (w*y+x)*components+i; pixels[index]= value[i]; } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setPixel(int x, int y, const float32 *value) { @@ -1031,16 +1047,19 @@ void Pixmap2D::setPixel(int x, int y, const float32 *value) { int index = (w*y+x)*components+i; pixels[index]= static_cast(value[i]*255.f); } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setComponent(int x, int y, int component, uint8 value) { int index = (w*y+x)*components+component; pixels[index] = value; + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setComponent(int x, int y, int component, float32 value) { int index = (w*y+x)*components+component; pixels[index]= static_cast(value*255.f); + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } //vector set @@ -1049,6 +1068,7 @@ void Pixmap2D::setPixel(int x, int y, const Vec3f &p) { int index = (w*y+x)*components+i; pixels[index]= static_cast(p.ptr()[i]*255.f); } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setPixel(int x, int y, const Vec4f &p) { @@ -1056,11 +1076,13 @@ void Pixmap2D::setPixel(int x, int y, const Vec4f &p) { int index = (w*y+x)*components+i; pixels[index]= static_cast(p.ptr()[i]*255.f); } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setPixel(int x, int y, float p) { int index = (w*y+x)*components; pixels[index]= static_cast(p*255.f); + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setPixels(const uint8 *value){ @@ -1069,6 +1091,7 @@ void Pixmap2D::setPixels(const uint8 *value){ setPixel(i, j, value); } } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setPixels(const float32 *value){ @@ -1077,6 +1100,7 @@ void Pixmap2D::setPixels(const float32 *value){ setPixel(i, j, value); } } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setComponents(int component, uint8 value){ @@ -1086,6 +1110,7 @@ void Pixmap2D::setComponents(int component, uint8 value){ setComponent(i, j, component, value); } } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::setComponents(int component, float32 value){ @@ -1095,6 +1120,7 @@ void Pixmap2D::setComponents(int component, float32 value){ setComponent(i, j, component, value); } } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } float splatDist(Vec2i a, Vec2i b){ @@ -1180,6 +1206,8 @@ void Pixmap2D::copy(const Pixmap2D *sourcePixmap){ throw runtime_error("Pixmap2D::copy() dimensions must agree"); } memcpy(pixels, sourcePixmap->getPixels(), w*h*sourcePixmap->getComponents()); + this->path = sourcePixmap->path; + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap2D::subCopy(int x, int y, const Pixmap2D *sourcePixmap){ @@ -1197,6 +1225,7 @@ void Pixmap2D::subCopy(int x, int y, const Pixmap2D *sourcePixmap){ setPixel(i+x, j+y, pixel); } } + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); delete [] pixel; } @@ -1236,6 +1265,7 @@ void Pixmap3D::init(int w, int h, int d, int components){ this->d= d; this->components= components; pixels= new uint8[(std::size_t)getPixelByteCount()]; + CalculatePixelsCRC(pixels,0, crc); } uint64 Pixmap3D::getPixelByteCount() const { @@ -1248,6 +1278,7 @@ void Pixmap3D::init(int d, int components){ this->d= d; this->components= components; pixels= NULL; + CalculatePixelsCRC(pixels,0, crc); } void Pixmap3D::init(int components) { @@ -1256,6 +1287,7 @@ void Pixmap3D::init(int components) { this->d= -1; this->components= components; pixels= NULL; + CalculatePixelsCRC(pixels,0, crc); } void Pixmap3D::deletePixels() { @@ -1283,6 +1315,7 @@ void Pixmap3D::loadSlice(const string &path, int slice) { throw runtime_error("Unknown pixmap extension: "+extension); } this->path = path; + CalculatePixelsCRC(pixels,getPixelByteCount(), crc); } void Pixmap3D::loadSlicePng(const string &path, int slice) {