Code to get uniform locations
This commit is contained in:
@@ -105,9 +105,21 @@ glew_init(PyObject UNUSED *self) {
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Programs {{{
|
// Programs {{{
|
||||||
enum Program { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS };
|
enum ProgramNames { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS };
|
||||||
|
|
||||||
static GLuint program_ids[NUM_PROGRAMS] = {0};
|
typedef struct {
|
||||||
|
char name[256];
|
||||||
|
GLint size;
|
||||||
|
GLenum type;
|
||||||
|
} Uniform;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GLuint id;
|
||||||
|
Uniform uniforms[256];
|
||||||
|
GLint num_of_uniforms;
|
||||||
|
} Program;
|
||||||
|
|
||||||
|
static Program programs[NUM_PROGRAMS] = {{0}};
|
||||||
|
|
||||||
static inline GLuint
|
static inline GLuint
|
||||||
compile_shader(GLenum shader_type, const char *source) {
|
compile_shader(GLenum shader_type, const char *source) {
|
||||||
@@ -130,14 +142,37 @@ compile_shader(GLenum shader_type, const char *source) {
|
|||||||
return shader_id;
|
return shader_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
init_uniforms(int program) {
|
||||||
|
Program *p = programs + program;
|
||||||
|
glGetProgramiv(p->id, GL_ACTIVE_UNIFORMS, &(p->num_of_uniforms));
|
||||||
|
if (set_error_from_gl()) return false;
|
||||||
|
for (GLint i = 0; i < p->num_of_uniforms; i++) {
|
||||||
|
Uniform *u = p->uniforms + i;
|
||||||
|
glGetActiveUniform(p->id, (GLuint)i, sizeof(u->name)/sizeof(u->name[0]), NULL, &(u->size), &(u->type), u->name);
|
||||||
|
if (set_error_from_gl()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline GLint
|
static inline GLint
|
||||||
get_attrib_location(int program, const char *name) {
|
uniform_location(int program, const char *name) {
|
||||||
return glGetAttribLocation(program_ids[program], name);
|
for (GLint i = 0; i < programs[program].num_of_uniforms; i++) {
|
||||||
|
if (strncmp(programs[program].uniforms[i].name, name, sizeof(programs[program].uniforms[i].name)) == 0) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GLint
|
||||||
|
attrib_location(int program, const char *name) {
|
||||||
|
return glGetAttribLocation(programs[program].id, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bind_program(int program) {
|
bind_program(int program) {
|
||||||
glUseProgram(program_ids[program]);
|
glUseProgram(programs[program].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -244,12 +279,12 @@ add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenu
|
|||||||
VAO *vao = vaos + vao_idx;
|
VAO *vao = vaos + vao_idx;
|
||||||
static char err[256] = {0};
|
static char err[256] = {0};
|
||||||
if (!vao->num_buffers) { set_local_error("You must create a buffer for this attribute first"); return false; }
|
if (!vao->num_buffers) { set_local_error("You must create a buffer for this attribute first"); return false; }
|
||||||
GLint attrib_location = get_attrib_location(p, name);
|
GLint aloc = attrib_location(p, name);
|
||||||
if (set_error_from_gl()) return false;
|
if (set_error_from_gl()) return false;
|
||||||
if (attrib_location == -1) { snprintf(err, sizeof(err)/sizeof(err[0]), "No attribute named: %s found in this program", name); set_local_error(err); return false; }
|
if (aloc == -1) { snprintf(err, sizeof(err)/sizeof(err[0]), "No attribute named: %s found in this program", name); set_local_error(err); return false; }
|
||||||
ssize_t buf = vao->buffers[vao->num_buffers - 1];
|
ssize_t buf = vao->buffers[vao->num_buffers - 1];
|
||||||
if (!bind_buffer(buf)) return false;
|
if (!bind_buffer(buf)) return false;
|
||||||
glEnableVertexAttribArray(attrib_location);
|
glEnableVertexAttribArray(aloc);
|
||||||
if (set_error_from_gl()) return false;
|
if (set_error_from_gl()) return false;
|
||||||
switch(data_type) {
|
switch(data_type) {
|
||||||
case GL_BYTE:
|
case GL_BYTE:
|
||||||
@@ -258,15 +293,15 @@ add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenu
|
|||||||
case GL_UNSIGNED_SHORT:
|
case GL_UNSIGNED_SHORT:
|
||||||
case GL_INT:
|
case GL_INT:
|
||||||
case GL_UNSIGNED_INT:
|
case GL_UNSIGNED_INT:
|
||||||
glVertexAttribIPointer(attrib_location, size, data_type, stride, offset);
|
glVertexAttribIPointer(aloc, size, data_type, stride, offset);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
glVertexAttribPointer(attrib_location, size, data_type, GL_FALSE, stride, offset);
|
glVertexAttribPointer(aloc, size, data_type, GL_FALSE, stride, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (set_error_from_gl()) return false;
|
if (set_error_from_gl()) return false;
|
||||||
if (divisor) {
|
if (divisor) {
|
||||||
glVertexAttribDivisor(attrib_location, divisor);
|
glVertexAttribDivisor(aloc, divisor);
|
||||||
if (set_error_from_gl()) return false;
|
if (set_error_from_gl()) return false;
|
||||||
}
|
}
|
||||||
unbind_buffer(buf);
|
unbind_buffer(buf);
|
||||||
@@ -317,33 +352,34 @@ compile_program(PyObject UNUSED *self, PyObject *args) {
|
|||||||
GLuint vertex_shader_id = 0, fragment_shader_id = 0;
|
GLuint vertex_shader_id = 0, fragment_shader_id = 0;
|
||||||
if (!PyArg_ParseTuple(args, "iss", &which, &vertex_shader, &fragment_shader)) return NULL;
|
if (!PyArg_ParseTuple(args, "iss", &which, &vertex_shader, &fragment_shader)) return NULL;
|
||||||
if (which < CELL_PROGRAM || which >= NUM_PROGRAMS) { PyErr_Format(PyExc_ValueError, "Unknown program: %d", which); return NULL; }
|
if (which < CELL_PROGRAM || which >= NUM_PROGRAMS) { PyErr_Format(PyExc_ValueError, "Unknown program: %d", which); return NULL; }
|
||||||
if (program_ids[which] != 0) { PyErr_SetString(PyExc_ValueError, "program already compiled"); return NULL; }
|
if (programs[which].id != 0) { PyErr_SetString(PyExc_ValueError, "program already compiled"); return NULL; }
|
||||||
program_ids[which] = glCreateProgram();
|
programs[which].id = glCreateProgram();
|
||||||
if (program_ids[which] == 0) { set_error_from_gl(); return NULL; }
|
if (programs[which].id == 0) { set_error_from_gl(); return NULL; }
|
||||||
vertex_shader_id = compile_shader(GL_VERTEX_SHADER, vertex_shader);
|
vertex_shader_id = compile_shader(GL_VERTEX_SHADER, vertex_shader);
|
||||||
if (vertex_shader_id == 0) goto end;
|
if (vertex_shader_id == 0) goto end;
|
||||||
fragment_shader_id = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);
|
fragment_shader_id = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);
|
||||||
if (vertex_shader_id == 0) goto end;
|
if (vertex_shader_id == 0) goto end;
|
||||||
glAttachShader(program_ids[which], vertex_shader_id);
|
glAttachShader(programs[which].id, vertex_shader_id);
|
||||||
if (set_error_from_gl()) goto end;
|
if (set_error_from_gl()) goto end;
|
||||||
glAttachShader(program_ids[which], fragment_shader_id);
|
glAttachShader(programs[which].id, fragment_shader_id);
|
||||||
glLinkProgram(program_ids[which]);
|
glLinkProgram(programs[which].id);
|
||||||
GLint ret = GL_FALSE;
|
GLint ret = GL_FALSE;
|
||||||
glGetProgramiv(program_ids[which], GL_LINK_STATUS, &ret);
|
glGetProgramiv(programs[which].id, GL_LINK_STATUS, &ret);
|
||||||
if (ret != GL_TRUE) {
|
if (ret != GL_TRUE) {
|
||||||
GLsizei len;
|
GLsizei len;
|
||||||
glGetProgramInfoLog(program_ids[which], sizeof(glbuf), &len, glbuf);
|
glGetProgramInfoLog(programs[which].id, sizeof(glbuf), &len, glbuf);
|
||||||
fprintf(stderr, "Failed to compile GLSL shader!\n%s", glbuf);
|
fprintf(stderr, "Failed to compile GLSL shader!\n%s", glbuf);
|
||||||
PyErr_SetString(PyExc_ValueError, "Failed to compile shader");
|
PyErr_SetString(PyExc_ValueError, "Failed to compile shader");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (!init_uniforms(which)) goto end;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (vertex_shader_id != 0) glDeleteShader(vertex_shader_id);
|
if (vertex_shader_id != 0) glDeleteShader(vertex_shader_id);
|
||||||
if (fragment_shader_id != 0) glDeleteShader(fragment_shader_id);
|
if (fragment_shader_id != 0) glDeleteShader(fragment_shader_id);
|
||||||
translate_error();
|
translate_error();
|
||||||
if (PyErr_Occurred()) { glDeleteProgram(program_ids[which]); program_ids[which] = 0; return NULL;}
|
if (PyErr_Occurred()) { glDeleteProgram(programs[which].id); programs[which].id = 0; return NULL;}
|
||||||
return Py_BuildValue("I", program_ids[which]);
|
return Py_BuildValue("I", programs[which].id);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ UBO = namedtuple('UBO', 'size index offsets buf_id')
|
|||||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
@lru_cache()
|
|
||||||
def load_shaders(name):
|
def load_shaders(name):
|
||||||
vert = open(os.path.join(BASE, '{}_vertex.glsl'.format(name))).read().replace('GLSL_VERSION', str(GLSL_VERSION), 1)
|
vert = open(os.path.join(BASE, '{}_vertex.glsl'.format(name))).read().replace('GLSL_VERSION', str(GLSL_VERSION), 1)
|
||||||
frag = open(os.path.join(BASE, '{}_fragment.glsl'.format(name))).read().replace('GLSL_VERSION', str(GLSL_VERSION), 1)
|
frag = open(os.path.join(BASE, '{}_fragment.glsl'.format(name))).read().replace('GLSL_VERSION', str(GLSL_VERSION), 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user