void CTextureAtlas::CreateTexture() { const int2 atlasSize = atlasAllocator->GetAtlasSize(); PBO pbo; pbo.Bind(); pbo.Resize(atlasSize.x * atlasSize.y * 4); unsigned char* data = (unsigned char*)pbo.MapBuffer(GL_WRITE_ONLY); { // make spacing between textures black transparent to avoid ugly lines with linear filtering std::memset(data, 0, atlasSize.x * atlasSize.y * 4); for (std::vector<MemTex*>::iterator it = memtextures.begin(); it != memtextures.end(); ++it) { const float4 texCoords = atlasAllocator->GetTexCoords((*it)->names[0]); const float4 absCoords = atlasAllocator->GetEntry((*it)->names[0]); const int xpos = absCoords.x; const int ypos = absCoords.y; AtlasedTexture tex(texCoords); for (size_t n = 0; n < (*it)->names.size(); ++n) { textures[(*it)->names[n]] = tex; } for (int y = 0; y < (*it)->ysize; ++y) { int* dst = ((int*)data) + xpos + (ypos + y) * atlasSize.x; int* src = ((int*)(*it)->data) + y * (*it)->xsize; memcpy(dst, src, (*it)->xsize * 4); } } if (debug) { CBitmap tex(data, atlasSize.x, atlasSize.y); tex.Save(name + "-" + IntToString(atlasSize.x) + "x" + IntToString(atlasSize.y) + ".png"); } } pbo.UnmapBuffer(); const int maxMipMaps = atlasAllocator->GetMaxMipMaps(); glGenTextures(1, &atlasTexID); glBindTexture(GL_TEXTURE_2D, atlasTexID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (maxMipMaps > 0) ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxMipMaps); if (maxMipMaps > 0) { glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, atlasSize.x, atlasSize.y, GL_RGBA, GL_UNSIGNED_BYTE, pbo.GetPtr()); //FIXME disable texcompression //FIXME 2 PBO!!!! } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, atlasSize.x, atlasSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pbo.GetPtr()); } pbo.Unbind(); initialized = true; }
void CTextureAtlas::CreateTexture() { PBO pbo; pbo.Bind(); pbo.Resize(xsize * ysize * 4); unsigned char* data = (unsigned char*)pbo.MapBuffer(GL_WRITE_ONLY); std::memset(data, 0, xsize * ysize * 4); //! make spacing between textures black transparent to avoid ugly lines with linear filtering for (size_t i = 0; i < memtextures.size(); ++i) { MemTex& tex = *memtextures[i]; for (int y = 0; y < tex.ysize; ++y) { int* dst = ((int*)data) + tex.xpos + (tex.ypos + y) * xsize; int* src = ((int*)tex.data) + y * tex.xsize; memcpy(dst, src, tex.xsize * 4); } } if (debug) { //! hack to make sure we don't overwrite our own atlases static int count = 0; char fname[256]; SNPRINTF(fname, sizeof(fname), "textureatlas%d.png", ++count); //! even pbo.MapBuffer(GL_WRITE_ONLY) we can readback from it. GL_READ is only needed if we want to readback GPU data! CBitmap save(data,xsize,ysize); save.Save(fname); logOutput.Print("Saved finalized textureatlas to '%s'.", fname); } pbo.UnmapBuffer(); glGenTextures(1, &gltex); glBindTexture(GL_TEXTURE_2D, gltex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST/*GL_NEAREST_MIPMAP_LINEAR*/); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, xsize, ysize, 0, GL_RGBA, GL_UNSIGNED_BYTE, pbo.GetPtr()); pbo.Unbind(); initialized = true; }
void CTextureAtlas::CreateTexture() { const int2 atlasSize = atlasAllocator->GetAtlasSize(); xsize = atlasSize.x; ysize = atlasSize.y; PBO pbo; pbo.Bind(); pbo.Resize(atlasSize.x * atlasSize.y * 4); unsigned char* data = (unsigned char*)pbo.MapBuffer(GL_WRITE_ONLY); std::memset(data, 0, atlasSize.x * atlasSize.y * 4); // make spacing between textures black transparent to avoid ugly lines with linear filtering for(std::vector<MemTex*>::iterator it = memtextures.begin(); it != memtextures.end(); ++it) { float4 texCoords = atlasAllocator->GetTexCoords((*it)->names[0]); float4 absCoords = atlasAllocator->GetEntry((*it)->names[0]); const int xpos = absCoords.x; const int ypos = absCoords.y; AtlasedTexture tex(texCoords); for (size_t n = 0; n < (*it)->names.size(); ++n) { textures[(*it)->names[n]] = tex; } for (int y = 0; y < (*it)->ysize; ++y) { int* dst = ((int*)data) + xpos + (ypos + y) * atlasSize.x; int* src = ((int*)(*it)->data) + y * (*it)->xsize; memcpy(dst, src, (*it)->xsize * 4); } } if (debug) { // hack to make sure we don't overwrite our own atlases static int count = 0; char fname[256]; SNPRINTF(fname, sizeof(fname), "textureatlas%d.png", ++count); CBitmap save(data, atlasSize.x, atlasSize.y); save.Save(fname); LOG("Saved finalized texture-atlas to '%s'.", fname); } pbo.UnmapBuffer(); const int maxMipMaps = atlasAllocator->GetMaxMipMaps(); glGenTextures(1, &gltex); glBindTexture(GL_TEXTURE_2D, gltex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (maxMipMaps > 0) ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxMipMaps); if (maxMipMaps > 0) { glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, atlasSize.x, atlasSize.y, GL_RGBA, GL_UNSIGNED_BYTE, pbo.GetPtr()); //FIXME disable texcompression //FIXME 2 PBO!!!! } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, atlasSize.x, atlasSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pbo.GetPtr()); } pbo.Unbind(); initialized = true; }