mirror of https://github.com/bjornbytes/lovr.git
Image uniforms;
This commit is contained in:
parent
d961614184
commit
9ce462a67f
|
@ -37,7 +37,7 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
|
|||
memcpy(dest, blob->data, elements * sizeof(int));
|
||||
break;
|
||||
|
||||
case UNIFORM_SAMPLER:
|
||||
case UNIFORM_TEXTURE:
|
||||
lovrThrow("Texture uniform '%s' can not be updated with a Blob", debug);
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
|
|||
switch (uniform->type) {
|
||||
case UNIFORM_FLOAT: *((float*) dest + i) = luaL_checknumber(L, -1); break;
|
||||
case UNIFORM_INT: *((int*) dest + i) = luaL_checkinteger(L, -1); break;
|
||||
case UNIFORM_SAMPLER: *((Texture**) dest + i) = luax_checktype(L, -1, Texture); break;
|
||||
case UNIFORM_TEXTURE: *((Texture**) dest + i) = luax_checktype(L, -1, Texture); break;
|
||||
default: break;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -64,7 +64,7 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
|
|||
switch (uniform->type) {
|
||||
case UNIFORM_FLOAT: *((float*) dest + i) = luaL_checknumber(L, index + i); break;
|
||||
case UNIFORM_INT: *((int*) dest + i) = luaL_checkinteger(L, index + i); break;
|
||||
case UNIFORM_SAMPLER: *((Texture**) dest + i) = luax_checktype(L, index + i, Texture); break;
|
||||
case UNIFORM_TEXTURE: *((Texture**) dest + i) = luax_checktype(L, index + i, Texture); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
|
|||
*((int*) dest + i * components + j) = luaL_checkinteger(L, -1);
|
||||
break;
|
||||
|
||||
case UNIFORM_SAMPLER: lovrThrow("Unreachable");
|
||||
case UNIFORM_TEXTURE: lovrThrow("Unreachable");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
|
|||
*((float*) dest + i * components + j) = luaL_checknumber(L, -1);
|
||||
break;
|
||||
|
||||
case UNIFORM_SAMPLER: lovrThrow("Unreachable");
|
||||
case UNIFORM_TEXTURE: lovrThrow("Unreachable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ int l_lovrShaderSend(lua_State* L) {
|
|||
case UNIFORM_FLOAT: lovrShaderSetFloat(shader, uniform->name, tempData.data, uniform->count * uniform->components); break;
|
||||
case UNIFORM_INT: lovrShaderSetInt(shader, uniform->name, tempData.data, uniform->count * uniform->components); break;
|
||||
case UNIFORM_MATRIX: lovrShaderSetMatrix(shader, uniform->name, tempData.data, uniform->count * uniform->components * uniform->components); break;
|
||||
case UNIFORM_SAMPLER: lovrShaderSetTexture(shader, uniform->name, tempData.data, uniform->count); break;
|
||||
case UNIFORM_TEXTURE: lovrShaderSetTexture(shader, uniform->name, tempData.data, uniform->count); break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -247,6 +247,4 @@ void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth,
|
|||
void lovrGpuDraw(DrawCommand* command);
|
||||
void lovrGpuCompute(Shader* shader, int x, int y, int z);
|
||||
void lovrGpuPresent();
|
||||
|
||||
void lovrGpuBindTexture(Texture* texture, int slot);
|
||||
void lovrGpuDirtyTexture(int slot);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
// Types
|
||||
|
||||
#define MAX_TEXTURES 16
|
||||
#define MAX_IMAGES 8
|
||||
#define MAX_BLOCK_BUFFERS 8
|
||||
|
||||
#define LOVR_SHADER_POSITION 0
|
||||
|
@ -54,6 +55,7 @@ static struct {
|
|||
uint32_t indexBuffer;
|
||||
uint32_t program;
|
||||
Texture* textures[MAX_TEXTURES];
|
||||
Texture* images[MAX_IMAGES];
|
||||
uint32_t blockBuffers[2][MAX_BLOCK_BUFFERS];
|
||||
uint32_t vertexArray;
|
||||
uint32_t vertexBuffer;
|
||||
|
@ -288,7 +290,13 @@ static UniformType getUniformType(GLenum type, const char* debug) {
|
|||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
return UNIFORM_SAMPLER;
|
||||
#ifdef GL_ARB_shader_image_load_store
|
||||
case GL_IMAGE_2D:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
#endif
|
||||
return UNIFORM_TEXTURE;
|
||||
default:
|
||||
lovrThrow("Unsupported uniform type for uniform '%s'", debug);
|
||||
return UNIFORM_FLOAT;
|
||||
|
@ -297,13 +305,6 @@ static UniformType getUniformType(GLenum type, const char* debug) {
|
|||
|
||||
static int getUniformComponents(GLenum type) {
|
||||
switch (type) {
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
return 1;
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
case GL_FLOAT_MAT2:
|
||||
|
@ -373,6 +374,16 @@ static const char* getUniformTypeName(const Uniform* uniform) {
|
|||
return "";
|
||||
}
|
||||
|
||||
static Texture* lovrGpuGetDefaultTexture() {
|
||||
if (!state.defaultTexture) {
|
||||
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
||||
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false);
|
||||
lovrRelease(textureData);
|
||||
}
|
||||
|
||||
return state.defaultTexture;
|
||||
}
|
||||
|
||||
// GPU
|
||||
|
||||
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
|
||||
|
@ -389,25 +400,16 @@ static void lovrGpuBindIndexBuffer(uint32_t indexBuffer) {
|
|||
}
|
||||
}
|
||||
|
||||
void lovrGpuBindTexture(Texture* texture, int slot) {
|
||||
static void lovrGpuBindTexture(Texture* texture, int slot) {
|
||||
lovrAssert(slot >= 0 && slot < MAX_TEXTURES, "Invalid texture slot %d", slot);
|
||||
|
||||
if (!texture) {
|
||||
if (!state.defaultTexture) {
|
||||
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
||||
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false);
|
||||
lovrRelease(textureData);
|
||||
}
|
||||
|
||||
texture = state.defaultTexture;
|
||||
}
|
||||
texture = texture ? texture : lovrGpuGetDefaultTexture();
|
||||
|
||||
if (texture != state.textures[slot]) {
|
||||
lovrRetain(texture);
|
||||
lovrRelease(state.textures[slot]);
|
||||
state.textures[slot] = texture;
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(texture->target, lovrTextureGetId(texture));
|
||||
glBindTexture(texture->target, texture->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,6 +418,20 @@ void lovrGpuDirtyTexture(int slot) {
|
|||
state.textures[slot] = NULL;
|
||||
}
|
||||
|
||||
static void lovrGpuBindImage(Texture* texture, int slot) {
|
||||
#ifndef EMSCRIPTEN
|
||||
lovrAssert(slot >= 0 && slot < MAX_IMAGES, "Invalid image slot %d", slot);
|
||||
texture = texture ? texture : lovrGpuGetDefaultTexture();
|
||||
|
||||
if (texture != state.images[slot]) {
|
||||
lovrRetain(texture);
|
||||
lovrRelease(state.textures[slot]);
|
||||
state.images[slot] = texture;
|
||||
glBindImageTexture(slot, texture->id, 0, false, 0, GL_READ_WRITE, texture->slices[0]->format);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lovrGpuBindBlockBuffer(BlockType type, uint32_t buffer, int slot) {
|
||||
if (state.blockBuffers[type][slot] != buffer) {
|
||||
state.blockBuffers[type][slot] = buffer;
|
||||
|
@ -1390,7 +1406,8 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
uniform.location = glGetUniformLocation(program, uniform.name);
|
||||
uniform.type = getUniformType(glType, uniform.name);
|
||||
uniform.components = getUniformComponents(glType);
|
||||
uniform.baseTextureSlot = (uniform.type == UNIFORM_SAMPLER) ? textureSlot : -1;
|
||||
uniform.baseTextureSlot = uniform.type == UNIFORM_TEXTURE ? textureSlot : -1;
|
||||
uniform.image = glType == GL_IMAGE_2D || glType == GL_IMAGE_3D || glType == GL_IMAGE_CUBE || glType == GL_IMAGE_2D_ARRAY;
|
||||
|
||||
int blockIndex;
|
||||
glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
|
||||
|
@ -1432,7 +1449,7 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
uniform.value.data = calloc(1, uniform.size);
|
||||
break;
|
||||
|
||||
case UNIFORM_SAMPLER:
|
||||
case UNIFORM_TEXTURE:
|
||||
uniform.size = uniform.components * uniform.count * MAX(sizeof(Texture*), sizeof(int));
|
||||
uniform.value.data = calloc(1, uniform.size);
|
||||
|
||||
|
@ -1477,7 +1494,7 @@ static void lovrShaderSetupUniforms(Shader* shader) {
|
|||
|
||||
map_set(&shader->uniformMap, uniform.name, shader->uniforms.length);
|
||||
vec_push(&shader->uniforms, uniform);
|
||||
textureSlot += (uniform.type == UNIFORM_SAMPLER) ? uniform.count : 0;
|
||||
textureSlot += uniform.type == UNIFORM_TEXTURE ? uniform.count : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1615,7 @@ void lovrShaderBind(Shader* shader) {
|
|||
int i;
|
||||
Uniform* uniform;
|
||||
vec_foreach_ptr(&shader->uniforms, uniform, i) {
|
||||
if (uniform->type != UNIFORM_SAMPLER && !uniform->dirty) {
|
||||
if (uniform->type != UNIFORM_TEXTURE && !uniform->dirty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1633,9 +1650,13 @@ void lovrShaderBind(Shader* shader) {
|
|||
}
|
||||
break;
|
||||
|
||||
case UNIFORM_SAMPLER:
|
||||
case UNIFORM_TEXTURE:
|
||||
for (int i = 0; i < count; i++) {
|
||||
lovrGpuBindTexture(uniform->value.textures[i], uniform->baseTextureSlot + i);
|
||||
if (uniform->image) {
|
||||
//lovrGpuBindImage(uniform->value.textures[i], uniform->baseTextureSlot + i);
|
||||
} else {
|
||||
lovrGpuBindTexture(uniform->value.textures[i], uniform->baseTextureSlot + i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1714,7 +1735,7 @@ void lovrShaderSetMatrix(Shader* shader, const char* name, float* data, int coun
|
|||
}
|
||||
|
||||
void lovrShaderSetTexture(Shader* shader, const char* name, Texture** data, int count) {
|
||||
lovrShaderSetUniform(shader, name, UNIFORM_SAMPLER, data, count, sizeof(Texture*), "texture");
|
||||
lovrShaderSetUniform(shader, name, UNIFORM_TEXTURE, data, count, sizeof(Texture*), "texture");
|
||||
}
|
||||
|
||||
ShaderBlock* lovrShaderGetBlock(Shader* shader, const char* name) {
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef enum {
|
|||
UNIFORM_FLOAT,
|
||||
UNIFORM_MATRIX,
|
||||
UNIFORM_INT,
|
||||
UNIFORM_SAMPLER
|
||||
UNIFORM_TEXTURE
|
||||
} UniformType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -55,6 +55,7 @@ typedef struct {
|
|||
Texture** textures;
|
||||
} value;
|
||||
int baseTextureSlot;
|
||||
bool image;
|
||||
bool dirty;
|
||||
} Uniform;
|
||||
|
||||
|
|
Loading…
Reference in New Issue