mirror of https://github.com/bjornbytes/lovr.git
Use srgb formats for textures;
This commit is contained in:
parent
f7d7098098
commit
1662e79f0e
|
@ -830,6 +830,13 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool srgb = true;
|
||||||
|
if (lua_istable(L, count + 1)) {
|
||||||
|
lua_getfield(L, count + 1, "linear");
|
||||||
|
srgb = !lua_toboolean(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
TextureData* slices[6];
|
TextureData* slices[6];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
slices[i] = lovrTextureDataFromBlob(blobs[i]);
|
slices[i] = lovrTextureDataFromBlob(blobs[i]);
|
||||||
|
@ -837,7 +844,7 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureType type = (count == 1) ? TEXTURE_2D : TEXTURE_CUBE;
|
TextureType type = (count == 1) ? TEXTURE_2D : TEXTURE_CUBE;
|
||||||
texture = lovrTextureCreate(type, slices, count);
|
texture = lovrTextureCreate(type, slices, count, srgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_pushtype(L, Texture, texture);
|
luax_pushtype(L, Texture, texture);
|
||||||
|
|
|
@ -49,7 +49,7 @@ Font* lovrFontCreate(FontData* fontData) {
|
||||||
// Texture
|
// Texture
|
||||||
TextureData* textureData = lovrTextureDataGetBlank(font->atlas.width, font->atlas.height, 0x0, FORMAT_RGB);
|
TextureData* textureData = lovrTextureDataGetBlank(font->atlas.width, font->atlas.height, 0x0, FORMAT_RGB);
|
||||||
TextureFilter filter = { .mode = FILTER_BILINEAR };
|
TextureFilter filter = { .mode = FILTER_BILINEAR };
|
||||||
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1);
|
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, false);
|
||||||
lovrTextureSetFilter(font->texture, filter);
|
lovrTextureSetFilter(font->texture, filter);
|
||||||
lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP });
|
lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP });
|
||||||
|
|
||||||
|
|
|
@ -195,12 +195,18 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
#endif
|
|
||||||
if (state.gammaCorrect) {
|
if (state.gammaCorrect) {
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (state.gammaCorrect) {
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_FRAMEBUFFER_SRGB_EXT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
@ -1088,7 +1094,7 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
if (!state.defaultTexture) {
|
if (!state.defaultTexture) {
|
||||||
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
||||||
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1);
|
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = state.defaultTexture;
|
texture = state.defaultTexture;
|
||||||
|
|
|
@ -10,7 +10,7 @@ Material* lovrMaterialCreate(MaterialData* materialData, bool isDefault) {
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
for (int i = 0; i < MAX_MATERIAL_TEXTURES; i++) {
|
||||||
if (materialData->textures[i]) {
|
if (materialData->textures[i]) {
|
||||||
material->textures[i] = lovrTextureCreate(TEXTURE_2D, &materialData->textures[i], 1);
|
material->textures[i] = lovrTextureCreate(TEXTURE_2D, &materialData->textures[i], 1, true);
|
||||||
} else {
|
} else {
|
||||||
material->textures[i] = NULL;
|
material->textures[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,12 @@ static void lovrTextureCreateStorage(Texture* texture) {
|
||||||
int w = textureData->width;
|
int w = textureData->width;
|
||||||
int h = textureData->height;
|
int h = textureData->height;
|
||||||
int mipmapCount = log2(MAX(w, h)) + 1;
|
int mipmapCount = log2(MAX(w, h)) + 1;
|
||||||
GLenum internalFormat = textureData->format.glInternalFormat;
|
GLenum internalFormat;
|
||||||
|
if (lovrGraphicsIsGammaCorrect() && texture->srgb) {
|
||||||
|
internalFormat = textureData->format.glInternalFormat.srgb;
|
||||||
|
} else {
|
||||||
|
internalFormat = textureData->format.glInternalFormat.linear;
|
||||||
|
}
|
||||||
GLenum format = textureData->format.glFormat;
|
GLenum format = textureData->format.glFormat;
|
||||||
#ifndef EMSCRIPTEN
|
#ifndef EMSCRIPTEN
|
||||||
if (GLAD_GL_ARB_texture_storage) {
|
if (GLAD_GL_ARB_texture_storage) {
|
||||||
|
@ -49,7 +54,7 @@ static void validateSlices(TextureType type, TextureData* slices[6], int sliceCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCount) {
|
Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCount, bool srgb) {
|
||||||
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
|
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
|
||||||
if (!texture) return NULL;
|
if (!texture) return NULL;
|
||||||
|
|
||||||
|
@ -59,6 +64,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCo
|
||||||
memcpy(texture->slices, slices, sliceCount * sizeof(TextureData*));
|
memcpy(texture->slices, slices, sliceCount * sizeof(TextureData*));
|
||||||
texture->framebuffer = 0;
|
texture->framebuffer = 0;
|
||||||
texture->depthBuffer = 0;
|
texture->depthBuffer = 0;
|
||||||
|
texture->srgb = srgb;
|
||||||
glGenTextures(1, &texture->id);
|
glGenTextures(1, &texture->id);
|
||||||
lovrGraphicsBindTexture(texture, type, 0);
|
lovrGraphicsBindTexture(texture, type, 0);
|
||||||
lovrTextureCreateStorage(texture);
|
lovrTextureCreateStorage(texture);
|
||||||
|
@ -71,7 +77,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCo
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection, int msaa) {
|
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection, int msaa) {
|
||||||
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1);
|
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true);
|
||||||
if (!texture) return NULL;
|
if (!texture) return NULL;
|
||||||
|
|
||||||
int width = texture->width;
|
int width = texture->width;
|
||||||
|
@ -181,7 +187,12 @@ void lovrTextureRefresh(Texture* texture) {
|
||||||
|
|
||||||
for (int i = 0; i < texture->sliceCount; i++) {
|
for (int i = 0; i < texture->sliceCount; i++) {
|
||||||
TextureData* textureData = texture->slices[i];
|
TextureData* textureData = texture->slices[i];
|
||||||
GLenum glInternalFormat = textureData->format.glInternalFormat;
|
GLenum glInternalFormat;
|
||||||
|
if (lovrGraphicsIsGammaCorrect() && texture->srgb) {
|
||||||
|
glInternalFormat = textureData->format.glInternalFormat.srgb;
|
||||||
|
} else {
|
||||||
|
glInternalFormat = textureData->format.glInternalFormat.linear;
|
||||||
|
}
|
||||||
GLenum glFormat = textureData->format.glFormat;
|
GLenum glFormat = textureData->format.glFormat;
|
||||||
GLenum binding = (texture->type == TEXTURE_CUBE) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : GL_TEXTURE_2D;
|
GLenum binding = (texture->type == TEXTURE_CUBE) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : GL_TEXTURE_2D;
|
||||||
|
|
||||||
|
@ -194,6 +205,7 @@ void lovrTextureRefresh(Texture* texture) {
|
||||||
int w = textureData->width;
|
int w = textureData->width;
|
||||||
int h = textureData->height;
|
int h = textureData->height;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, w, h, 0, glFormat, GL_UNSIGNED_BYTE, textureData->data);
|
glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, w, h, 0, glFormat, GL_UNSIGNED_BYTE, textureData->data);
|
||||||
|
printf("%d %d\n", glGetError(), GL_INVALID_OPERATION);
|
||||||
if (textureData->mipmaps.generated) {
|
if (textureData->mipmaps.generated) {
|
||||||
glGenerateMipmap(GL_TEXTURE_2D); // TODO
|
glGenerateMipmap(GL_TEXTURE_2D); // TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,11 +54,12 @@ typedef struct {
|
||||||
TextureFilter filter;
|
TextureFilter filter;
|
||||||
TextureWrap wrap;
|
TextureWrap wrap;
|
||||||
int msaa;
|
int msaa;
|
||||||
|
bool srgb;
|
||||||
} Texture;
|
} Texture;
|
||||||
|
|
||||||
GLenum lovrTextureGetGLFormat(TextureFormat format);
|
GLenum lovrTextureGetGLFormat(TextureFormat format);
|
||||||
|
|
||||||
Texture* lovrTextureCreate(TextureType type, TextureData* data[6], int count);
|
Texture* lovrTextureCreate(TextureType type, TextureData* data[6], int count, bool srgb);
|
||||||
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection, int msaa);
|
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection, int msaa);
|
||||||
void lovrTextureDestroy(const Ref* ref);
|
void lovrTextureDestroy(const Ref* ref);
|
||||||
void lovrTextureBindFramebuffer(Texture* texture);
|
void lovrTextureBindFramebuffer(Texture* texture);
|
||||||
|
|
|
@ -97,6 +97,7 @@ typedef struct {
|
||||||
|
|
||||||
// headset implementations
|
// headset implementations
|
||||||
extern HeadsetInterface lovrHeadsetOpenVRDriver;
|
extern HeadsetInterface lovrHeadsetOpenVRDriver;
|
||||||
|
extern HeadsetInterface lovrHeadsetWebVRDriver;
|
||||||
extern HeadsetInterface lovrHeadsetFakeDriver;
|
extern HeadsetInterface lovrHeadsetFakeDriver;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "loaders/animation.h"
|
#include "loaders/animation.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
AnimationData* lovrAnimationDataCreate(const char* name) {
|
AnimationData* lovrAnimationDataCreate() {
|
||||||
AnimationData* animationData = malloc(sizeof(AnimationData));
|
AnimationData* animationData = malloc(sizeof(AnimationData));
|
||||||
if (!animationData) return NULL;
|
if (!animationData) return NULL;
|
||||||
|
|
||||||
|
|
|
@ -7,35 +7,35 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
const TextureFormat FORMAT_RGB = {
|
const TextureFormat FORMAT_RGB = {
|
||||||
.glInternalFormat = GL_RGB,
|
.glInternalFormat = { GL_RGB, GL_SRGB },
|
||||||
.glFormat = GL_RGB,
|
.glFormat = GL_RGB,
|
||||||
.compressed = false,
|
.compressed = false,
|
||||||
.blockBytes = 3
|
.blockBytes = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextureFormat FORMAT_RGBA = {
|
const TextureFormat FORMAT_RGBA = {
|
||||||
.glInternalFormat = GL_RGBA,
|
.glInternalFormat = { GL_RGBA, GL_SRGB_ALPHA },
|
||||||
.glFormat = GL_RGBA,
|
.glFormat = GL_RGBA,
|
||||||
.compressed = false,
|
.compressed = false,
|
||||||
.blockBytes = 4
|
.blockBytes = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextureFormat FORMAT_DXT1 = {
|
const TextureFormat FORMAT_DXT1 = {
|
||||||
.glInternalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
|
.glInternalFormat = { GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT },
|
||||||
.glFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
|
.glFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
|
||||||
.compressed = true,
|
.compressed = true,
|
||||||
.blockBytes = 8
|
.blockBytes = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextureFormat FORMAT_DXT3 = {
|
const TextureFormat FORMAT_DXT3 = {
|
||||||
.glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
.glInternalFormat = { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT },
|
||||||
.glFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
.glFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
||||||
.compressed = true,
|
.compressed = true,
|
||||||
.blockBytes = 16
|
.blockBytes = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextureFormat FORMAT_DXT5 = {
|
const TextureFormat FORMAT_DXT5 = {
|
||||||
.glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
.glInternalFormat = { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT },
|
||||||
.glFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
.glFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
||||||
.compressed = true,
|
.compressed = true,
|
||||||
.blockBytes = 16
|
.blockBytes = 16
|
||||||
|
|
|
@ -5,8 +5,19 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// WEBGL_compressed_texture_s3tc_srgb isn't ratified yet...
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
|
||||||
|
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
||||||
|
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
||||||
|
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLenum glInternalFormat;
|
struct {
|
||||||
|
GLenum linear;
|
||||||
|
GLenum srgb;
|
||||||
|
} glInternalFormat;
|
||||||
GLenum glFormat;
|
GLenum glFormat;
|
||||||
int blockBytes;
|
int blockBytes;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
|
|
Loading…
Reference in New Issue