#include <cstring>
#include <msp/core/hash.h>
#include <msp/core/maputils.h>
+#include <msp/gl/extensions/arb_shader_objects.h>
+#include <msp/gl/extensions/arb_uniform_buffer_object.h>
+#include <msp/gl/extensions/arb_vertex_shader.h>
#include <msp/strings/format.h>
-#include "arb_shader_objects.h"
-#include "arb_uniform_buffer_object.h"
-#include "arb_vertex_shader.h"
#include "buffer.h"
#include "error.h"
+#include "misc.h"
#include "program.h"
#include "shader.h"
(*i)->compile();
uniforms.clear();
+ legacy_vars = false;
glLinkProgram(id);
- int value;
- glGetProgramiv(id, GL_LINK_STATUS, &value);
- if(!(linked = value))
+ linked = get_program_i(id, GL_LINK_STATUS);
+ if(!linked)
throw compile_error(get_info_log());
- glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &value);
- unsigned count = value;
+ unsigned count = get_program_i(id, GL_ACTIVE_UNIFORMS);
vector<UniformInfo *> uniforms_by_index(count);
for(unsigned i=0; i<count; ++i)
{
int len = 0;
int size;
GLenum type;
- glGetActiveUniform(id, i, 128, &len, &size, &type, name);
+ glGetActiveUniform(id, i, sizeof(name), &len, &size, &type, name);
if(len && strncmp(name, "gl_", 3))
{
+ /* Some implementations report the first element of a uniform array,
+ others report just the name of an array. */
+ if(len>3 && !strcmp(name+len-3, "[0]"))
+ name[len-3] = 0;
+
UniformInfo &info = uniforms[name];
info.block = 0;
info.name = name;
info.type = type;
uniforms_by_index[i] = &info;
}
+ else
+ legacy_vars = true;
+ }
+
+ count = get_program_i(id, GL_ACTIVE_ATTRIBUTES);
+ for(unsigned i=0; i<count; ++i)
+ {
+ char name[128];
+ int len = 0;
+ int size;
+ GLenum type;
+ glGetActiveAttrib(id, i, sizeof(name), &len, &size, &type, name);
+ if(len && !strncmp(name, "gl_", 3))
+ legacy_vars = true;
}
if(ARB_uniform_buffer_object)
{
- glGetProgramiv(id, GL_ACTIVE_UNIFORM_BLOCKS, &value);
- count = value;
+ count = get_program_i(id, GL_ACTIVE_UNIFORM_BLOCKS);
for(unsigned i=0; i<count; ++i)
{
char name[128];
int len;
- glGetActiveUniformBlockName(id, i, 128, &len, name);
+ glGetActiveUniformBlockName(id, i, sizeof(name), &len, name);
UniformBlockInfo &info = uniform_blocks[name];
info.name = name;
+ int value;
glGetActiveUniformBlockiv(id, i, GL_UNIFORM_BLOCK_DATA_SIZE, &value);
info.data_size = value;
vector<const UniformInfo *> blockless_uniforms;
for(UniformMap::iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
- {
if(!i->second.block)
{
i->second.location = glGetUniformLocation(id, i->second.name.c_str());
blockless_uniforms.push_back(&i->second);
}
- /* Some implementations report the first element of a uniform array,
- others report just the name of an array. */
- if(i->second.name.size()>3 && !i->second.name.compare(i->second.name.size()-3, 3, "[0]"))
- i->second.name.erase(i->second.name.size()-3, 3);
- }
-
uniform_layout_hash = compute_layout_hash(blockless_uniforms);
}
string Program::get_info_log() const
{
- GLsizei len = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &len);
+ GLsizei len = get_program_i(id, GL_INFO_LOG_LENGTH);
char *buf = new char[len+1];
glGetProgramInfoLog(id, len+1, &len, buf);
string log(buf, len);