Gawain: Add support for multiple attrib names.

This adds the possibility to give multiple name to the same attrib.
This allow multiple binding points depending on the shader.
This commit is contained in:
Clément Foucault 2017-05-13 22:52:29 +02:00
parent acc5d02f69
commit cfbfa94e6b
4 changed files with 48 additions and 23 deletions

@ -14,6 +14,7 @@
#include "common.h"
#define MAX_VERTEX_ATTRIBS 16
#define MAX_ATTRIB_NAMES 3
#define AVG_VERTEX_ATTRIB_NAME_LEN 11
#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
@ -54,7 +55,8 @@ typedef struct {
unsigned sz; // size in bytes, 1 to 16
unsigned offset; // from beginning of vertex, in bytes
VertexFetchMode fetch_mode;
const char* name;
const char* name[MAX_ATTRIB_NAMES];
unsigned name_ct;
} Attrib;
typedef struct {
@ -70,6 +72,7 @@ void VertexFormat_clear(VertexFormat*);
void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src);
unsigned VertexFormat_add_attrib(VertexFormat*, const char* name, VertexCompType, unsigned comp_ct, VertexFetchMode);
void VertexFormat_add_alias(VertexFormat*, const char* alias);
// Memory Management

@ -55,13 +55,16 @@ void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, co
for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx)
{
const Attrib* a = format->attribs + a_idx;
const ShaderInput* input = ShaderInterface_attrib(shaderface, a->name);
for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
{
const ShaderInput* input = ShaderInterface_attrib(shaderface, a->name[n_idx]);
#if TRUST_NO_ONE
assert(input != NULL);
// TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
assert(input != NULL);
// TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program
#endif
write_attrib_location(binding, a_idx, input->location);
write_attrib_location(binding, a_idx, input->location);
}
}
}

@ -127,23 +127,26 @@ static void Batch_update_program_bindings(Batch* batch)
const GLvoid* pointer = (const GLubyte*)0 + a->offset;
const ShaderInput* input = ShaderInterface_attrib(batch->interface, a->name);
if (input == NULL) continue;
glEnableVertexAttribArray(input->location);
switch (a->fetch_mode)
for (unsigned n_idx = 0; n_idx < a->name_ct; ++n_idx)
{
case KEEP_FLOAT:
case CONVERT_INT_TO_FLOAT:
glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
break;
case NORMALIZE_INT_TO_FLOAT:
glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
break;
case KEEP_INT:
glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
const ShaderInput* input = ShaderInterface_attrib(batch->interface, a->name[n_idx]);
if (input == NULL) continue;
glEnableVertexAttribArray(input->location);
switch (a->fetch_mode)
{
case KEEP_FLOAT:
case CONVERT_INT_TO_FLOAT:
glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer);
break;
case NORMALIZE_INT_TO_FLOAT:
glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer);
break;
case KEEP_INT:
glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer);
}
}
}
}

@ -28,6 +28,7 @@ void VertexFormat_clear(VertexFormat* format)
format->attrib_ct = 0;
format->packed = false;
format->name_offset = 0;
format->name_ct = 0;
#endif
}
@ -37,7 +38,13 @@ void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
memcpy(dest, src, sizeof(VertexFormat));
for (unsigned i = 0; i < dest->attrib_ct; i++)
dest->attribs[i].name = (char *)dest + (dest->attribs[i].name - ((char *)src));
{
dest->attribs[i].name_ct = dest->attribs[i].name_ct;
for (unsigned j = 0; j < dest->attribs[i].name_ct; j++)
{
dest->attribs[i].name[j] = (char *)dest + (src->attribs[i].name[j] - ((char *)src));
}
}
}
static GLenum convert_comp_type_to_gl(VertexCompType type)
@ -160,7 +167,7 @@ unsigned VertexFormat_add_attrib(VertexFormat* format, const char* name, VertexC
const unsigned attrib_id = format->attrib_ct++;
Attrib* attrib = format->attribs + attrib_id;
attrib->name = copy_attrib_name(format, name);
attrib->name[attrib->name_ct++] = copy_attrib_name(format, name);
attrib->comp_type = comp_type;
attrib->gl_comp_type = convert_comp_type_to_gl(comp_type);
#if USE_10_10_10
@ -175,6 +182,15 @@ unsigned VertexFormat_add_attrib(VertexFormat* format, const char* name, VertexC
return attrib_id;
}
void VertexFormat_add_alias(VertexFormat* format, const char* alias)
{
Attrib* attrib = format->attribs + (format->attrib_ct - 1);
#if TRUST_NO_ONE
assert(attrib->name_ct < MAX_ATTRIB_NAMES);
#endif
attrib->name[attrib->name_ct++] = copy_attrib_name(format, alias);
}
unsigned padding(unsigned offset, unsigned alignment)
{
const unsigned mod = offset % alignment;