Gawain: improve ShaderInterface
- builtin uniforms match what Blender needs - set input counts in struct (stupid mistake) - look up uniforms by name - look up builtin uniforms by enum - check attrib/uniform locations for error
This commit is contained in:
@@ -20,7 +20,9 @@ typedef enum {
|
|||||||
UNIFORM_PROJECTION_3D, // mat4 ProjectionMatrix
|
UNIFORM_PROJECTION_3D, // mat4 ProjectionMatrix
|
||||||
UNIFORM_MVP_3D, // mat4 ModelViewProjectionMatrix
|
UNIFORM_MVP_3D, // mat4 ModelViewProjectionMatrix
|
||||||
UNIFORM_NORMAL_3D, // mat3 NormalMatrix
|
UNIFORM_NORMAL_3D, // mat3 NormalMatrix
|
||||||
UNIFORM_INV_NORMAL_3D, // mat3 InverseNormalMatrix
|
|
||||||
|
UNIFORM_MODELVIEW_INV_3D, // mat4 ModelViewInverseMatrix
|
||||||
|
UNIFORM_PROJECTION_INV_3D, // mat4 ProjectionInverseMatrix
|
||||||
|
|
||||||
UNIFORM_MODELVIEW_2D, // mat3 ModelViewMatrix
|
UNIFORM_MODELVIEW_2D, // mat3 ModelViewMatrix
|
||||||
UNIFORM_PROJECTION_2D, // mat3 ProjectionMatrix
|
UNIFORM_PROJECTION_2D, // mat3 ProjectionMatrix
|
||||||
@@ -47,3 +49,6 @@ typedef struct {
|
|||||||
|
|
||||||
ShaderInterface* ShaderInterface_create(GLint program_id);
|
ShaderInterface* ShaderInterface_create(GLint program_id);
|
||||||
void ShaderInterface_discard(ShaderInterface*);
|
void ShaderInterface_discard(ShaderInterface*);
|
||||||
|
|
||||||
|
const ShaderInput* ShaderInterface_uniform(const ShaderInterface*, const char* name);
|
||||||
|
const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface*, BuiltinUniform);
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include "shader_interface.h"
|
#include "shader_interface.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define DEBUG_SHADER_INTERFACE 0
|
#define DEBUG_SHADER_INTERFACE 0
|
||||||
|
|
||||||
@@ -19,8 +20,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static const char* BuiltinUniform_name(BuiltinUniform u)
|
static const char* BuiltinUniform_name(BuiltinUniform u)
|
||||||
{
|
{
|
||||||
static const char* names[] =
|
static const char* names[] =
|
||||||
@@ -31,7 +30,9 @@ static const char* BuiltinUniform_name(BuiltinUniform u)
|
|||||||
[UNIFORM_PROJECTION_3D] = "ProjectionMatrix",
|
[UNIFORM_PROJECTION_3D] = "ProjectionMatrix",
|
||||||
[UNIFORM_MVP_3D] = "ModelViewProjectionMatrix",
|
[UNIFORM_MVP_3D] = "ModelViewProjectionMatrix",
|
||||||
[UNIFORM_NORMAL_3D] = "NormalMatrix",
|
[UNIFORM_NORMAL_3D] = "NormalMatrix",
|
||||||
[UNIFORM_INV_NORMAL_3D] = "InverseNormalMatrix",
|
|
||||||
|
[UNIFORM_MODELVIEW_INV_3D] = "ModelViewInverseMatrix",
|
||||||
|
[UNIFORM_PROJECTION_INV_3D] = "ProjectionInverseMatrix",
|
||||||
|
|
||||||
[UNIFORM_MODELVIEW_2D] = "ModelViewMatrix",
|
[UNIFORM_MODELVIEW_2D] = "ModelViewMatrix",
|
||||||
[UNIFORM_PROJECTION_2D] = "ProjectionMatrix",
|
[UNIFORM_PROJECTION_2D] = "ProjectionMatrix",
|
||||||
@@ -45,8 +46,6 @@ static const char* BuiltinUniform_name(BuiltinUniform u)
|
|||||||
return names[u];
|
return names[u];
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool setup_builtin_uniform(ShaderInput* input, const char* name)
|
static bool setup_builtin_uniform(ShaderInput* input, const char* name)
|
||||||
{
|
{
|
||||||
// TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
|
// TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types
|
||||||
@@ -76,6 +75,8 @@ ShaderInterface* ShaderInterface_create(GLint program)
|
|||||||
|
|
||||||
// allocate enough space for input counts, details for each input, and a buffer for name strings
|
// allocate enough space for input counts, details for each input, and a buffer for name strings
|
||||||
ShaderInterface* shaderface = calloc(1, offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput) + name_buffer_len);
|
ShaderInterface* shaderface = calloc(1, offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput) + name_buffer_len);
|
||||||
|
shaderface->uniform_ct = uniform_ct;
|
||||||
|
shaderface->attrib_ct = attrib_ct;
|
||||||
|
|
||||||
char* name_buffer = (char*)shaderface + offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput);
|
char* name_buffer = (char*)shaderface + offsetof(ShaderInterface, inputs) + input_ct * sizeof(ShaderInput);
|
||||||
uint32_t name_buffer_offset = 0;
|
uint32_t name_buffer_offset = 0;
|
||||||
@@ -89,12 +90,19 @@ ShaderInterface* ShaderInterface_create(GLint program)
|
|||||||
|
|
||||||
glGetActiveUniform(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
|
glGetActiveUniform(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name);
|
||||||
|
|
||||||
|
input->location = glGetUniformLocation(program, name);
|
||||||
|
|
||||||
|
#if TRUST_NO_ONE
|
||||||
|
assert(input->location != -1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (setup_builtin_uniform(input, name))
|
if (setup_builtin_uniform(input, name))
|
||||||
; // reclaim space from name buffer (don't advance offset)
|
; // reclaim space from name buffer (don't advance offset)
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
input->name = name;
|
||||||
name_buffer_offset += name_len + 1; // include NULL terminator
|
name_buffer_offset += name_len + 1; // include NULL terminator
|
||||||
|
}
|
||||||
input->location = glGetUniformLocation(program, name);
|
|
||||||
|
|
||||||
#if DEBUG_SHADER_INTERFACE
|
#if DEBUG_SHADER_INTERFACE
|
||||||
printf("uniform[%u] '%s' at location %d\n", i, name, input->location);
|
printf("uniform[%u] '%s' at location %d\n", i, name, input->location);
|
||||||
@@ -112,11 +120,15 @@ ShaderInterface* ShaderInterface_create(GLint program)
|
|||||||
|
|
||||||
// TODO: reject DOUBLE gl_types
|
// TODO: reject DOUBLE gl_types
|
||||||
|
|
||||||
|
input->location = glGetAttribLocation(program, name);
|
||||||
|
|
||||||
|
#if TRUST_NO_ONE
|
||||||
|
assert(input->location != -1);
|
||||||
|
#endif
|
||||||
|
|
||||||
input->name = name;
|
input->name = name;
|
||||||
name_buffer_offset += name_len + 1; // include NULL terminator
|
name_buffer_offset += name_len + 1; // include NULL terminator
|
||||||
|
|
||||||
input->location = glGetAttribLocation(program, name);
|
|
||||||
|
|
||||||
#if DEBUG_SHADER_INTERFACE
|
#if DEBUG_SHADER_INTERFACE
|
||||||
printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
|
printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
|
||||||
#endif
|
#endif
|
||||||
@@ -138,3 +150,21 @@ void ShaderInterface_discard(ShaderInterface* shaderface)
|
|||||||
// allocated as one chunk, so discard is simple
|
// allocated as one chunk, so discard is simple
|
||||||
free(shaderface);
|
free(shaderface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ShaderInput* ShaderInterface_uniform(const ShaderInterface* shaderface, const char* name)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < shaderface->uniform_ct; ++i)
|
||||||
|
{
|
||||||
|
const ShaderInput* uniform = shaderface->inputs + i;
|
||||||
|
|
||||||
|
if (strcmp(uniform->name, name) == 0)
|
||||||
|
return uniform;
|
||||||
|
}
|
||||||
|
return NULL; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface* shaderface, BuiltinUniform builtin)
|
||||||
|
{
|
||||||
|
// TODO: look up by enum, not name (fix setup_builtin_uniform first)
|
||||||
|
return ShaderInterface_uniform(shaderface, BuiltinUniform_name(builtin));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user