Use srgb formats for textures;

This commit is contained in:
bjorn 2017-11-23 14:19:20 -08:00
parent f7d7098098
commit 1662e79f0e
10 changed files with 55 additions and 17 deletions

View File

@ -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];
for (int i = 0; i < count; i++) {
slices[i] = lovrTextureDataFromBlob(blobs[i]);
@ -837,7 +844,7 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
}
TextureType type = (count == 1) ? TEXTURE_2D : TEXTURE_CUBE;
texture = lovrTextureCreate(type, slices, count);
texture = lovrTextureCreate(type, slices, count, srgb);
}
luax_pushtype(L, Texture, texture);

View File

@ -49,7 +49,7 @@ Font* lovrFontCreate(FontData* fontData) {
// Texture
TextureData* textureData = lovrTextureDataGetBlank(font->atlas.width, font->atlas.height, 0x0, FORMAT_RGB);
TextureFilter filter = { .mode = FILTER_BILINEAR };
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1);
font->texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, false);
lovrTextureSetFilter(font->texture, filter);
lovrTextureSetWrap(font->texture, (TextureWrap) { .s = WRAP_CLAMP, .t = WRAP_CLAMP });

View File

@ -195,12 +195,18 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
glfwSwapInterval(0);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_PROGRAM_POINT_SIZE);
#endif
if (state.gammaCorrect) {
glEnable(GL_FRAMEBUFFER_SRGB);
} else {
glDisable(GL_FRAMEBUFFER_SRGB);
}
#else
if (state.gammaCorrect) {
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
} else {
glDisable(GL_FRAMEBUFFER_SRGB_EXT);
}
#endif
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -1088,7 +1094,7 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
if (!texture) {
if (!state.defaultTexture) {
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;

View File

@ -10,7 +10,7 @@ Material* lovrMaterialCreate(MaterialData* materialData, bool isDefault) {
for (int i = 0; i < MAX_MATERIAL_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 {
material->textures[i] = NULL;
}

View File

@ -15,7 +15,12 @@ static void lovrTextureCreateStorage(Texture* texture) {
int w = textureData->width;
int h = textureData->height;
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;
#ifndef EMSCRIPTEN
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);
if (!texture) return NULL;
@ -59,6 +64,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCo
memcpy(texture->slices, slices, sliceCount * sizeof(TextureData*));
texture->framebuffer = 0;
texture->depthBuffer = 0;
texture->srgb = srgb;
glGenTextures(1, &texture->id);
lovrGraphicsBindTexture(texture, type, 0);
lovrTextureCreateStorage(texture);
@ -71,7 +77,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCo
}
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;
int width = texture->width;
@ -181,7 +187,12 @@ void lovrTextureRefresh(Texture* texture) {
for (int i = 0; i < texture->sliceCount; 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 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 h = textureData->height;
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) {
glGenerateMipmap(GL_TEXTURE_2D); // TODO
}

View File

@ -54,11 +54,12 @@ typedef struct {
TextureFilter filter;
TextureWrap wrap;
int msaa;
bool srgb;
} Texture;
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);
void lovrTextureDestroy(const Ref* ref);
void lovrTextureBindFramebuffer(Texture* texture);

View File

@ -97,6 +97,7 @@ typedef struct {
// headset implementations
extern HeadsetInterface lovrHeadsetOpenVRDriver;
extern HeadsetInterface lovrHeadsetWebVRDriver;
extern HeadsetInterface lovrHeadsetFakeDriver;

View File

@ -1,7 +1,7 @@
#include "loaders/animation.h"
#include <stdlib.h>
AnimationData* lovrAnimationDataCreate(const char* name) {
AnimationData* lovrAnimationDataCreate() {
AnimationData* animationData = malloc(sizeof(AnimationData));
if (!animationData) return NULL;

View File

@ -7,35 +7,35 @@
#include <string.h>
const TextureFormat FORMAT_RGB = {
.glInternalFormat = GL_RGB,
.glInternalFormat = { GL_RGB, GL_SRGB },
.glFormat = GL_RGB,
.compressed = false,
.blockBytes = 3
};
const TextureFormat FORMAT_RGBA = {
.glInternalFormat = GL_RGBA,
.glInternalFormat = { GL_RGBA, GL_SRGB_ALPHA },
.glFormat = GL_RGBA,
.compressed = false,
.blockBytes = 4
};
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,
.compressed = true,
.blockBytes = 8
};
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,
.compressed = true,
.blockBytes = 16
};
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,
.compressed = true,
.blockBytes = 16

View File

@ -5,8 +5,19 @@
#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 {
GLenum glInternalFormat;
struct {
GLenum linear;
GLenum srgb;
} glInternalFormat;
GLenum glFormat;
int blockBytes;
bool compressed;