Autodetect integer attribute types;

Fixes inability to use integer attributes with Mesh.
This commit is contained in:
bjorn 2020-05-21 00:24:19 -06:00
parent 902774e800
commit 1185fcf6e1
6 changed files with 30 additions and 16 deletions

View File

@ -1290,8 +1290,7 @@ static int l_lovrGraphicsNewMesh(lua_State* L) {
.buffer = lovrGraphicsGetIdentityBuffer(),
.type = U8,
.components = 1,
.divisor = 1,
.integer = true
.divisor = 1
});
if (dataIndex) {

View File

@ -248,8 +248,8 @@ void lovrGraphicsCreateWindow(WindowFlags* flags) {
MeshAttribute position = { .buffer = vertexBuffer, .offset = 0, .stride = stride, .type = F32, .components = 3 };
MeshAttribute normal = { .buffer = vertexBuffer, .offset = 12, .stride = stride, .type = F32, .components = 3 };
MeshAttribute texCoord = { .buffer = vertexBuffer, .offset = 24, .stride = stride, .type = F32, .components = 2 };
MeshAttribute drawId = { .buffer = state.buffers[STREAM_DRAWID], .type = U8, .components = 1, .integer = true };
MeshAttribute identity = { .buffer = state.identityBuffer, .type = U8, .components = 1, .divisor = 1, .integer = true };
MeshAttribute drawId = { .buffer = state.buffers[STREAM_DRAWID], .type = U8, .components = 1 };
MeshAttribute identity = { .buffer = state.identityBuffer, .type = U8, .components = 1, .divisor = 1 };
state.mesh = lovrMeshCreate(DRAW_TRIANGLES, NULL, 0);
lovrMeshAttachAttribute(state.mesh, "lovrPosition", &position);

View File

@ -17,7 +17,6 @@ typedef struct {
unsigned type : 3; // AttributeType
unsigned components : 3;
unsigned normalized : 1;
unsigned integer : 1;
unsigned disabled : 1;
} MeshAttribute;

View File

@ -150,7 +150,6 @@ Model* lovrModelCreate(ModelData* data) {
.stride = data->buffers[attribute->buffer].stride,
.type = attribute->type,
.components = attribute->components,
.integer = j == ATTR_BONES,
.normalized = attribute->normalized
});
@ -165,8 +164,7 @@ Model* lovrModelCreate(ModelData* data) {
.buffer = lovrGraphicsGetIdentityBuffer(),
.type = U8,
.components = 1,
.divisor = 1,
.integer = true
.divisor = 1
});
if (primitive->indices) {

View File

@ -491,6 +491,22 @@ static GLenum convertTopology(DrawMode topology) {
}
}
static bool isAttributeTypeInteger(GLenum type) {
switch (type) {
case GL_INT:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4:
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_VEC2:
case GL_UNSIGNED_INT_VEC3:
case GL_UNSIGNED_INT_VEC4:
return true;
default:
return false;
}
}
static UniformType getUniformType(GLenum type, const char* debug) {
switch (type) {
case GL_FLOAT:
@ -788,9 +804,10 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int baseDivisor) {
for (uint32_t i = 0; i < mesh->attributeCount; i++) {
MeshAttribute* attribute;
int location;
bool integer;
if ((attribute = &mesh->attributes[i])->disabled) { continue; }
if ((location = lovrShaderGetAttributeLocation(shader, mesh->attributeNames[i])) < 0) { continue; }
if ((location = lovrShaderGetAttributeLocation(shader, mesh->attributeNames[i], &integer)) < 0) { continue; }
lovrBufferUnmap(attribute->buffer);
enabledLocations |= (1 << location);
@ -808,7 +825,7 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int baseDivisor) {
GLenum type = convertAttributeType(attribute->type);
GLvoid* offset = (GLvoid*) (intptr_t) attribute->offset;
if (attribute->integer) {
if (integer) {
glVertexAttribIPointer(location, attribute->components, type, attribute->stride, offset);
} else {
glVertexAttribPointer(location, attribute->components, type, attribute->normalized, attribute->stride, offset);
@ -2585,14 +2602,14 @@ Shader* lovrShaderCreateGraphics(const char* vertexSource, int vertexSourceLengt
// Attribute cache
int32_t attributeCount;
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attributeCount);
map_init(&shader->attributes, 0);
map_init(&shader->attributes, attributeCount);
for (int i = 0; i < attributeCount; i++) {
char name[LOVR_MAX_ATTRIBUTE_LENGTH];
GLint size;
GLenum type;
GLsizei length;
glGetActiveAttrib(program, i, LOVR_MAX_ATTRIBUTE_LENGTH, &length, &size, &type, name);
map_set(&shader->attributes, hash64(name, length), glGetAttribLocation(program, name));
map_set(&shader->attributes, hash64(name, length), (glGetAttribLocation(program, name) << 1) | isAttributeTypeInteger(type));
}
shader->multiview = multiview;
@ -2660,9 +2677,10 @@ ShaderType lovrShaderGetType(Shader* shader) {
return shader->type;
}
int lovrShaderGetAttributeLocation(Shader* shader, const char* name) {
uint64_t location = map_get(&shader->attributes, hash64(name, strlen(name)));
return location == MAP_NIL ? -1 : (int) location;
int lovrShaderGetAttributeLocation(Shader* shader, const char* name, bool* integer) {
uint64_t info = map_get(&shader->attributes, hash64(name, strlen(name)));
*integer = info & 1;
return info == MAP_NIL ? -1 : (int) (info >> 1);
}
bool lovrShaderHasUniform(Shader* shader, const char* name) {

View File

@ -110,7 +110,7 @@ Shader* lovrShaderCreateCompute(const char* source, int length, ShaderFlag* flag
Shader* lovrShaderCreateDefault(DefaultShader type, ShaderFlag* flags, uint32_t flagCount, bool multiview);
void lovrShaderDestroy(void* ref);
ShaderType lovrShaderGetType(Shader* shader);
int lovrShaderGetAttributeLocation(Shader* shader, const char* name);
int lovrShaderGetAttributeLocation(Shader* shader, const char* name, bool* integer);
bool lovrShaderHasUniform(Shader* shader, const char* name);
bool lovrShaderHasBlock(Shader* shader, const char* name);
const Uniform* lovrShaderGetUniform(Shader* shader, const char* name);