mirror of https://github.com/OpenRCT2/OpenRCT2.git
Add more atlases to increase space efficiency and derive atlas size from device limits
This commit is contained in:
parent
bb3fe8b804
commit
c506e08ac2
|
@ -70,6 +70,7 @@ static const char * TryLoadAllProcAddresses()
|
|||
SetupOpenGLFunction(glViewport);
|
||||
SetupOpenGLFunction(glTexSubImage3D);
|
||||
SetupOpenGLFunction(glTexImage3D);
|
||||
SetupOpenGLFunction(glGetIntegerv);
|
||||
|
||||
// 2.0+ functions
|
||||
SetupOpenGLFunction(glAttachShader);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#define glViewport __static__glViewport
|
||||
#define glTexSubImage3D __static__glTexSubImage3D
|
||||
#define glTexImage3D __static__glTexImage3D
|
||||
#define glGetIntegerv __static__glGetIntegerv
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -71,6 +72,7 @@
|
|||
#undef glViewport
|
||||
#undef glTexSubImage3D
|
||||
#undef glTexImage3D
|
||||
#undef glGetIntegerv
|
||||
|
||||
// 1.1 function signatures
|
||||
typedef void (APIENTRYP PFNGLBEGINPROC )(GLenum mode);
|
||||
|
@ -93,6 +95,7 @@ typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC )(GLenum target, GLenum pname,
|
|||
typedef void (APIENTRYP PFNGLVIEWPORTPROC )(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* data);
|
||||
typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC )(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * data);
|
||||
typedef void (APIENTRYP PFNGLGETINTERGERVPROC )(GLenum pname, GLint * data);
|
||||
|
||||
#ifdef NO_EXTERN_GLAPI
|
||||
// Defines the function pointers
|
||||
|
@ -126,6 +129,7 @@ GLAPI_DECL PFNGLTEXPARAMETERIPROC glTexParameteri GLAP
|
|||
GLAPI_DECL PFNGLVIEWPORTPROC glViewport GLAPI_SET;
|
||||
GLAPI_DECL PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D GLAPI_SET;
|
||||
GLAPI_DECL PFNGLTEXIMAGE3DPROC glTexImage3D GLAPI_SET;
|
||||
GLAPI_DECL PFNGLGETINTERGERVPROC glGetIntegerv GLAPI_SET;
|
||||
|
||||
// 2.0+ function pointers
|
||||
GLAPI_DECL PFNGLATTACHSHADERPROC glAttachShader GLAPI_SET;
|
||||
|
|
|
@ -90,14 +90,24 @@ CachedTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * pale
|
|||
|
||||
void TextureCache::InitialiseAtlases() {
|
||||
if (!_atlasInitialised) {
|
||||
// Determine width and height to use for texture atlases
|
||||
GLint maxSize;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
|
||||
if (maxSize > TEXTURE_CACHE_MAX_ATLAS_SIZE) maxSize = TEXTURE_CACHE_MAX_ATLAS_SIZE;
|
||||
|
||||
// Create an array texture to hold all of the atlases
|
||||
glGenTextures(1, &_atlasTextureArray);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, _atlasTextureArray);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, TEXTURE_CACHE_ATLAS_WIDTH, TEXTURE_CACHE_ATLAS_HEIGHT, _atlases.size(), 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8UI, maxSize, maxSize, _atlases.size(), 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
// Initialise atlases
|
||||
for (auto& atlas : _atlases) {
|
||||
atlas.Initialise(maxSize, maxSize);
|
||||
}
|
||||
|
||||
_atlasInitialised = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,11 +52,11 @@ struct GlyphId
|
|||
};
|
||||
};
|
||||
|
||||
// TODO: Derive from hardware limits instead
|
||||
// TODO: Handle no more slots remaining (allocate more atlases?)
|
||||
// TODO: Handle images larger than 256x256
|
||||
constexpr int TEXTURE_CACHE_ATLAS_WIDTH = 8192;
|
||||
constexpr int TEXTURE_CACHE_ATLAS_HEIGHT = 8192;
|
||||
|
||||
// This is the maximum width and height of each atlas (2048 -> 4 MB)
|
||||
constexpr int TEXTURE_CACHE_MAX_ATLAS_SIZE = 2048;
|
||||
|
||||
// Location of an image (texture atlas index, slot and normalized coordinates)
|
||||
struct CachedTextureInfo {
|
||||
|
@ -72,6 +72,7 @@ class Atlas {
|
|||
private:
|
||||
GLuint _index;
|
||||
int _imageWidth, _imageHeight;
|
||||
int _atlasWidth, _atlasHeight;
|
||||
std::vector<GLuint> _freeSlots;
|
||||
|
||||
int _cols, _rows;
|
||||
|
@ -81,9 +82,14 @@ public:
|
|||
_index = index;
|
||||
_imageWidth = imageWidth;
|
||||
_imageHeight = imageHeight;
|
||||
}
|
||||
|
||||
_cols = TEXTURE_CACHE_ATLAS_WIDTH / imageWidth;
|
||||
_rows = TEXTURE_CACHE_ATLAS_HEIGHT / imageHeight;
|
||||
void Initialise(int atlasWidth, int atlasHeight) {
|
||||
_atlasWidth = atlasWidth;
|
||||
_atlasHeight = atlasHeight;
|
||||
|
||||
_cols = _atlasWidth / _imageWidth;
|
||||
_rows = _atlasHeight / _imageHeight;
|
||||
|
||||
_freeSlots.resize(_cols * _rows);
|
||||
for (size_t i = 0; i < _freeSlots.size(); i++) {
|
||||
|
@ -121,7 +127,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
vec4i GetSlotCoordinates(GLuint slot, int actualWidth, int actualHeight) {
|
||||
vec4i GetSlotCoordinates(GLuint slot, int actualWidth, int actualHeight) const {
|
||||
int row = slot / _cols;
|
||||
int col = slot % _cols;
|
||||
|
||||
|
@ -133,12 +139,12 @@ private:
|
|||
};
|
||||
}
|
||||
|
||||
static vec4f NormalizeCoordinates(const vec4i& coords) {
|
||||
vec4f NormalizeCoordinates(const vec4i& coords) const {
|
||||
return vec4f{
|
||||
coords.x / (float) TEXTURE_CACHE_ATLAS_WIDTH,
|
||||
coords.y / (float) TEXTURE_CACHE_ATLAS_HEIGHT,
|
||||
coords.z / (float) TEXTURE_CACHE_ATLAS_WIDTH,
|
||||
coords.w / (float) TEXTURE_CACHE_ATLAS_HEIGHT
|
||||
coords.x / (float) _atlasWidth,
|
||||
coords.y / (float) _atlasHeight,
|
||||
coords.z / (float) _atlasWidth,
|
||||
coords.w / (float) _atlasHeight
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -151,9 +157,11 @@ private:
|
|||
GLuint _atlasTextureArray;
|
||||
|
||||
// Atlases should be ordered from small to large image support
|
||||
std::array<Atlas, 2> _atlases = {
|
||||
Atlas{0, 64, 64},
|
||||
Atlas{1, 256, 256}
|
||||
std::array<Atlas, 4> _atlases = {
|
||||
Atlas{0, 32, 32},
|
||||
Atlas{1, 64, 64},
|
||||
Atlas{2, 128, 128},
|
||||
Atlas{3, 256, 256}
|
||||
};
|
||||
|
||||
std::unordered_map<uint32, CachedTextureInfo> _imageTextureMap;
|
||||
|
|
Loading…
Reference in New Issue