mirror of https://github.com/bjornbytes/lovr.git
Mipmap generation;
This commit is contained in:
parent
344320a19d
commit
f1141664b6
|
@ -5,6 +5,29 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void lovrTextureCreateStorage(Texture* texture) {
|
||||
TextureData* textureData = texture->textureData;
|
||||
|
||||
if (textureData->format.compressed || !textureData->mipmaps.generated) {
|
||||
return;
|
||||
}
|
||||
|
||||
int w = textureData->width;
|
||||
int h = textureData->height;
|
||||
int mipmapCount = log2(MAX(w, h)) + 1;
|
||||
GLenum internalFormat = textureData->format.glInternalFormat;
|
||||
GLenum format = textureData->format.glFormat;
|
||||
if (GLAD_GL_ARB_texture_storage) {
|
||||
glTexStorage2D(GL_TEXTURE_2D, mipmapCount, internalFormat, w, h);
|
||||
} else {
|
||||
for (int i = 0; i < mipmapCount; i++) {
|
||||
glTexImage2D(GL_TEXTURE_2D, i, internalFormat, w, h, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
w = MAX(w >> 1, 1);
|
||||
h = MAX(h >> 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture* lovrTextureCreate(TextureData* textureData) {
|
||||
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
|
||||
if (!texture) return NULL;
|
||||
|
@ -13,6 +36,8 @@ Texture* lovrTextureCreate(TextureData* textureData) {
|
|||
texture->depthBuffer = 0;
|
||||
texture->textureData = textureData;
|
||||
glGenTextures(1, &texture->id);
|
||||
lovrGraphicsBindTexture(texture);
|
||||
lovrTextureCreateStorage(texture);
|
||||
lovrTextureRefresh(texture);
|
||||
lovrTextureSetFilter(texture, FILTER_LINEAR, FILTER_LINEAR);
|
||||
lovrTextureSetWrap(texture, WRAP_REPEAT, WRAP_REPEAT);
|
||||
|
@ -132,12 +157,23 @@ void lovrTextureResolveMSAA(Texture* texture) {
|
|||
|
||||
void lovrTextureRefresh(Texture* texture) {
|
||||
TextureData* textureData = texture->textureData;
|
||||
int w = textureData->width;
|
||||
int h = textureData->height;
|
||||
GLenum glInternalFormat = textureData->format.glInternalFormat;
|
||||
GLenum glFormat = textureData->format.glFormat;
|
||||
lovrGraphicsBindTexture(texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, w, h, 0, glFormat, GL_UNSIGNED_BYTE, textureData->data);
|
||||
|
||||
if (textureData->format.compressed) {
|
||||
Mipmap m; int i;
|
||||
vec_foreach(&textureData->mipmaps.list, m, i) {
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, m.width, m.height, 0, m.size, m.data);
|
||||
}
|
||||
} else {
|
||||
int w = textureData->width;
|
||||
int h = textureData->height;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, w, h, 0, glFormat, GL_UNSIGNED_BYTE, textureData->data);
|
||||
if (textureData->mipmaps.generated) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lovrTextureGetHeight(Texture* texture) {
|
||||
|
|
|
@ -589,9 +589,9 @@ TextureData* lovrHeadsetControllerNewTextureData(Controller* controller) {
|
|||
textureData->width = width;
|
||||
textureData->height = height;
|
||||
textureData->format = format;
|
||||
textureData->data = malloc(size);
|
||||
memcpy(textureData->data, vrTexture->rubTextureMapData, size);
|
||||
|
||||
textureData->data = memcpy(malloc(size), vrTexture->rubTextureMapData, size);;
|
||||
textureData->mipmaps.generated = 1;
|
||||
textureData->blob = NULL;
|
||||
return textureData;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/*
|
||||
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.14a0 on Sat Jul 22 10:22:59 2017.
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.14a0 on Sun Jul 23 03:01:38 2017.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
APIs: gl=3.3, gles2=3.0
|
||||
Profile: core
|
||||
Extensions:
|
||||
GL_ARB_texture_storage,
|
||||
GL_EXT_texture_compression_s3tc,
|
||||
GL_EXT_texture_filter_anisotropic
|
||||
Loader: False
|
||||
|
@ -14,9 +15,9 @@
|
|||
Omit khrplatform: False
|
||||
|
||||
Commandline:
|
||||
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --extensions="GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic"
|
||||
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --extensions="GL_ARB_texture_storage,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic"
|
||||
Online:
|
||||
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic
|
||||
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_texture_storage&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -519,8 +520,10 @@ PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex;
|
|||
PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample;
|
||||
PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
|
||||
PFNGLFRONTFACEPROC glad_glFrontFace;
|
||||
int GLAD_GL_ARB_texture_storage;
|
||||
int GLAD_GL_EXT_texture_compression_s3tc;
|
||||
int GLAD_GL_EXT_texture_filter_anisotropic;
|
||||
PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
|
||||
static void load_GL_VERSION_1_0(GLADloadproc load) {
|
||||
if(!GLAD_GL_VERSION_1_0) return;
|
||||
glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
|
||||
|
@ -934,8 +937,15 @@ static void load_GL_VERSION_3_3(GLADloadproc load) {
|
|||
glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui");
|
||||
glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv");
|
||||
}
|
||||
static void load_GL_ARB_texture_storage(GLADloadproc load) {
|
||||
if(!GLAD_GL_ARB_texture_storage) return;
|
||||
glad_glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)load("glTexStorage1D");
|
||||
glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)load("glTexStorage2D");
|
||||
glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)load("glTexStorage3D");
|
||||
}
|
||||
static int find_extensionsGL(void) {
|
||||
if (!get_exts()) return 0;
|
||||
GLAD_GL_ARB_texture_storage = has_ext("GL_ARB_texture_storage");
|
||||
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
|
||||
GLAD_GL_EXT_texture_filter_anisotropic = has_ext("GL_EXT_texture_filter_anisotropic");
|
||||
free_exts();
|
||||
|
@ -1016,6 +1026,7 @@ int gladLoadGLLoader(GLADloadproc load) {
|
|||
load_GL_VERSION_3_3(load);
|
||||
|
||||
if (!find_extensionsGL()) return 0;
|
||||
load_GL_ARB_texture_storage(load);
|
||||
return GLVersion.major != 0 || GLVersion.minor != 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/*
|
||||
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.14a0 on Sat Jul 22 10:22:59 2017.
|
||||
OpenGL, OpenGL ES loader generated by glad 0.1.14a0 on Sun Jul 23 03:01:38 2017.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
APIs: gl=3.3, gles2=3.0
|
||||
Profile: core
|
||||
Extensions:
|
||||
GL_ARB_texture_storage,
|
||||
GL_EXT_texture_compression_s3tc,
|
||||
GL_EXT_texture_filter_anisotropic
|
||||
Loader: False
|
||||
|
@ -14,9 +15,9 @@
|
|||
Omit khrplatform: False
|
||||
|
||||
Commandline:
|
||||
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --extensions="GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic"
|
||||
--profile="core" --api="gl=3.3,gles2=3.0" --generator="c" --spec="gl" --no-loader --extensions="GL_ARB_texture_storage,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic"
|
||||
Online:
|
||||
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic
|
||||
http://glad.dav1d.de/#profile=core&language=c&specification=gl&api=gl%3D3.3&api=gles2%3D3.0&extensions=GL_ARB_texture_storage&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_EXT_texture_filter_anisotropic
|
||||
*/
|
||||
|
||||
|
||||
|
@ -2297,6 +2298,13 @@ GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ;
|
|||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
#ifndef GL_ARB_texture_storage
|
||||
#define GL_ARB_texture_storage 1
|
||||
GLAPI int GLAD_GL_ARB_texture_storage;
|
||||
typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
|
||||
GLAPI PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D;
|
||||
#define glTexStorage1D glad_glTexStorage1D
|
||||
#endif
|
||||
#ifndef GL_EXT_texture_compression_s3tc
|
||||
#define GL_EXT_texture_compression_s3tc 1
|
||||
GLAPI int GLAD_GL_EXT_texture_compression_s3tc;
|
||||
|
|
|
@ -121,7 +121,7 @@ static int parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
|
|||
int mipmapCount = header->mipMapCount;
|
||||
|
||||
// Load mipmaps
|
||||
vec_init(&textureData->mipmaps);
|
||||
vec_init(&textureData->mipmaps.list);
|
||||
for (int i = 0; i < mipmapCount; i++) {
|
||||
size_t numBlocksWide = width ? MAX(1, (width + 3) / 4) : 0;
|
||||
size_t numBlocksHigh = height ? MAX(1, (height + 3) / 4) : 0;
|
||||
|
@ -129,15 +129,15 @@ static int parseDDS(uint8_t* data, size_t size, TextureData* textureData) {
|
|||
|
||||
// Overflow check
|
||||
if (mipmapSize == 0 || (offset + mipmapSize) > size) {
|
||||
vec_deinit(&textureData->mipmaps);
|
||||
vec_deinit(&textureData->mipmaps.list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mipmap mipmap = { .width = width, .height = height, .data = &data[offset], .size = mipmapSize };
|
||||
vec_push(&textureData->mipmaps, mipmap);
|
||||
vec_push(&textureData->mipmaps.list, mipmap);
|
||||
offset += mipmapSize;
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
width = MAX(width >> 1, 1);
|
||||
height = MAX(height >> 1, 1);
|
||||
}
|
||||
|
||||
textureData->data = NULL;
|
||||
|
@ -153,8 +153,9 @@ TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value, Textu
|
|||
textureData->width = width;
|
||||
textureData->height = height;
|
||||
textureData->format = format;
|
||||
textureData->data = malloc(size);
|
||||
memset(textureData->data, value, size);
|
||||
textureData->data = memset(malloc(size), value, size);
|
||||
textureData->mipmaps.generated = 0;
|
||||
textureData->blob = NULL;
|
||||
return textureData;
|
||||
}
|
||||
|
||||
|
@ -166,6 +167,8 @@ TextureData* lovrTextureDataGetEmpty(int width, int height, TextureFormat format
|
|||
textureData->height = height;
|
||||
textureData->format = format;
|
||||
textureData->data = NULL;
|
||||
textureData->mipmaps.generated = 0;
|
||||
textureData->blob = NULL;
|
||||
return textureData;
|
||||
}
|
||||
|
||||
|
@ -182,6 +185,8 @@ TextureData* lovrTextureDataFromBlob(Blob* blob) {
|
|||
stbi_set_flip_vertically_on_load(0);
|
||||
textureData->format = FORMAT_RGBA;
|
||||
textureData->data = stbi_load_from_memory(blob->data, blob->size, &textureData->width, &textureData->height, NULL, 4);
|
||||
textureData->mipmaps.generated = 1;
|
||||
textureData->blob = NULL;
|
||||
|
||||
if (!textureData->data) {
|
||||
error("Could not load texture data from '%s'", blob->name);
|
||||
|
@ -193,6 +198,10 @@ TextureData* lovrTextureDataFromBlob(Blob* blob) {
|
|||
}
|
||||
|
||||
void lovrTextureDataResize(TextureData* textureData, int width, int height, uint8_t value) {
|
||||
if (textureData->format.compressed || textureData->mipmaps.generated) {
|
||||
error("Can't resize a compressed texture or a texture with generated mipmaps.");
|
||||
}
|
||||
|
||||
int size = width * height * textureData->format.blockBytes;
|
||||
textureData->width = width;
|
||||
textureData->height = height;
|
||||
|
@ -201,6 +210,12 @@ void lovrTextureDataResize(TextureData* textureData, int width, int height, uint
|
|||
}
|
||||
|
||||
void lovrTextureDataDestroy(TextureData* textureData) {
|
||||
if (textureData->blob) {
|
||||
lovrRelease(&textureData->blob->ref);
|
||||
}
|
||||
if (textureData->format.compressed) {
|
||||
vec_deinit(&textureData->mipmaps.list);
|
||||
}
|
||||
free(textureData->data);
|
||||
free(textureData);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,10 @@ typedef struct {
|
|||
int height;
|
||||
TextureFormat format;
|
||||
void* data;
|
||||
vec_mipmap_t mipmaps;
|
||||
union MipmapType {
|
||||
vec_mipmap_t list;
|
||||
int generated;
|
||||
} mipmaps;
|
||||
Blob* blob;
|
||||
} TextureData;
|
||||
|
||||
|
|
Loading…
Reference in New Issue