void ShaderProgram::FetchUniforms() { GLint num_active_uniforms = 0; glGetProgramiv(m_program_id, GL_ACTIVE_UNIFORMS, &num_active_uniforms); // uniforms for( int i = 0; i < num_active_uniforms; ++i ) { char buffer[64]; GLsizei uniform_length = 0; GLint uniform_size = 0; GLenum uniform_type = 0; // grab uniform info glGetActiveUniform( m_program_id, (GLuint)i, (GLsizei)sizeof(buffer), &uniform_length, &uniform_size, &uniform_type, buffer ); ASSERT( buffer ); ASSERT( uniform_length ); // get uniform location GLint uniform_id = glGetUniformLocation( m_program_id, buffer ); ASSERT(uniform_id != -1); // add to map UniformData uniform_data; uniform_data.gl_id = uniform_id; uniform_data.gl_type_enum = uniform_type; uint32_t hashed_str = HashString(buffer); m_uniform_map.insert( std::make_pair(hashed_str,uniform_data) ); } CheckGLError(); }
void CL_OpenGLProgramObjectProvider::fetch_uniforms() const { if (!cached_uniforms.empty()) return; CL_OpenGL::set_active(); GLint count = 0; glGetProgramiv(handle, GL_ACTIVE_UNIFORMS, &count); GLint name_size = 0; glGetProgramiv(handle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &name_size); GLchar *name = new GLchar[name_size+1]; name[name_size] = 0; for (int i=0; i<count; i++) { GLsizei length = 0; GLint size = 0; GLenum type = 0; name[0] = 0; glGetActiveUniform(handle, i, name_size, &length, &size, &type, name); CL_String uniform_name = CL_StringHelp::local8_to_text(CL_StringRef8(name, length, false)); int loc = glGetUniformLocation(handle, CL_StringHelp::text_to_local8(name).c_str()); CL_ProgramUniform uniform(uniform_name, size, type, loc); cached_uniforms.push_back(uniform); } delete[] name; };
bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info) { if (!program) { synthesizeGLError(INVALID_VALUE); return false; } makeContextCurrent(); GLint maxLength = 0; glGetProgramiv(static_cast<GLuint>(program), GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); GLchar* name = (GLchar*) fastMalloc(maxLength); GLsizei nameLength = 0; GLint size = 0; GLenum type = 0; glGetActiveUniform(static_cast<GLuint>(program), index, maxLength, &nameLength, &size, &type, name); if (!nameLength) { fastFree(name); return false; } info.name = String(name, nameLength); info.type = type; info.size = size; fastFree(name); return true; }
void Shader::get_uniforms() { GLint unif_num; glGetProgramiv(m_program_id, GL_ACTIVE_UNIFORMS, &unif_num); //Temp arrays. They contain only instances attributes, not the vertex ones U8 max_name_char = 50; for (GLuint i = 0; i < unif_num; i++){ //Temp return values GLint temp_size, temp_name_size; GLenum temp_type; GLchar* temp_name = (GLchar*)malloc(50); glGetActiveUniform(m_program_id, i, 50, &temp_name_size, &temp_size, &temp_type, temp_name); GLuint loc = glGetUniformLocation(m_program_id, temp_name); if (temp_name[0] == 'g' && temp_name[1] == '_'){ global_uniforms_data[temp_name].index = loc; global_uniforms_data[temp_name].type = temp_type; global_uniforms_data[temp_name].value = nullptr; } else{ uniforms_data[temp_name].index = loc; uniforms_data[temp_name].type = temp_type; uniforms_data[temp_name].size = sizeof(U32) * get_size_from_type(temp_type) * temp_size; } } }
/** Get list of uniforms used in the program */ GLuint GetUniforms(GLuint program, struct uniform_info uniforms[]) { GLint n, max, i; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n); glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max); for (i = 0; i < n; i++) { GLint size, len; GLenum type; char name[100]; glGetActiveUniform(program, i, 100, &len, &size, &type, name); uniforms[i].name = strdup(name); uniforms[i].size = size; uniforms[i].type = type; uniforms[i].location = glGetUniformLocation(program, name); } uniforms[i].name = NULL; /* end of list */ return n; }
bool WebGraphicsContext3DDefaultImpl::getActiveUniform(WebGLId program, unsigned long index, ActiveInfo& info) { GLint maxNameLength = -1; glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); if (maxNameLength < 0) return false; GLchar* name = 0; if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { synthesizeGLError(GL_OUT_OF_MEMORY); return false; } GLsizei length = 0; GLint size = -1; GLenum type = 0; glGetActiveUniform(program, index, maxNameLength, &length, &size, &type, name); if (size < 0) { fastFree(name); return false; } info.name = WebString::fromUTF8(name, length); info.type = type; info.size = size; fastFree(name); return true; }
void ShaderProgram::Link() { //link shaders and attribs glLinkProgram(program); CheckForLinkErrors(); CHECK_GL_ERROR(); //if they were linked we no longer need them //delete vShader; //delete fShader; //going to iterate through every uniform and cache info about it GLint uniformCount = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); //printf("Contains %d uniforms:\n", uniformCount); const int maxLength = 100; char nameChars[maxLength]; for (int i = 0; i < uniformCount; i++) { GLenum type = 0; GLsizei nameLength = 0; GLsizei uniSize = 0; glGetActiveUniform(program, i, maxLength, &nameLength, &uniSize, &type, nameChars); string name(nameChars, nameLength); GLint loc = glGetUniformLocation(program, name.c_str()); locations[name] = loc; types[name] = type; //printf("\t%d(%d). %s - %d\n", i, loc, name.c_str(), type); } }
bool GLProgram::link() { glLinkProgram(m_program); glValidateProgram(m_program); GLint status; glGetProgramiv(m_program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { FZLOGERROR("GLProgram: Error linking program: %i.", m_program); FZLOGERROR("%s", getProgramLog().c_str()); fzGLDeleteProgram( m_program ); m_program = 0; return false; } char uniformName[256]; GLint nuUniforms = 0; glGetProgramiv(m_program, GL_ACTIVE_UNIFORMS, &nuUniforms); for(fzInt index = 0; index < nuUniforms; ++index) { glGetActiveUniform(m_program, index, 256, NULL, NULL, NULL, uniformName); m_uniforms.insert(uniformsPair(fzHash(uniformName), glGetUniformLocation(m_program, uniformName))); } CHECK_GL_ERROR_DEBUG(); setUniform1i("u_texture", 0); return true; }
GLint Uniform::getSize() { GLint size; GLenum type; GLchar name; glGetActiveUniform(program, id, 0, NULL, &size, &type, &name); return size; }
void ShaderProgram::retrieveLocations() { GLint n, maxLen; GLint size, location; GLsizei written; GLenum type; GLchar* name; glGetProgramiv(_handle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLen); glGetProgramiv(_handle, GL_ACTIVE_ATTRIBUTES, &n); name = new GLchar[maxLen]; for (int i = 0; i < n; ++i) { glGetActiveAttrib(_handle, i, maxLen, &written, &size, &type, name); location = glGetAttribLocation(_handle, name); _attribs[name] = location; } delete[] name; glGetProgramiv(_handle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen); glGetProgramiv(_handle, GL_ACTIVE_UNIFORMS, &n); name = new GLchar[maxLen]; for (int i = 0; i < n; ++i) { glGetActiveUniform(_handle, i, maxLen, &written, &size, &type, name); location = glGetUniformLocation(_handle, name); _uniforms[name] = location; } delete[] name; }
void GLHelper::fillUniformMap(const GLuint program, std::map<std::string, GLHelper::Uniform *> &uniformMap) const { GLint i; GLint count; GLint size; // size of the variable GLenum type; // type of the variable (float, vec3 or mat4, etc) GLint maxLength; glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); GLchar name[maxLength]; // variable name in GLSL GLsizei length; // name length glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count); //std::cout << "Active Uniforms:" << count << std::endl; for (i = 0; i < count; i++) { glGetActiveUniform(program, (GLuint)i, maxLength, &length, &size, &type, name); //std::cout << "Uniform " << i << " Type: " << type << " Name: " << name << std::endl; uniformMap[name] = new Uniform(i, name, type, size); } }
int GLSLProgramObject::GetUniformType(const int loc) { GLint size = 0; GLenum type = 0; glGetActiveUniform(objID, loc, 0, nullptr, &size, &type, nullptr); assert(size == 1); // arrays aren't handled yet return type; }
void neb::glsl::program::scanUniforms() { GLsizei len; GLint size; GLenum type; GLchar str_name[128]; for(int i = 0; i < 1000; i++) { glGetActiveUniform(o_, i, 128, &len, &size, &type, str_name); if(isGLError()) break; //printf("name=%32s type=%s\n", str_name, shaderTypeString(type)); // scalar or vector std::string name = str_name; size_t find_open = name.find("["); size_t find_close = name.find("]"); if(find_open != std::string::npos) { std::string name1 = name.substr(0, find_open); std::string name2 = name.substr(find_close + 2); auto it = uniform_vector_.find(name1 + "." + name2); if(it != uniform_vector_.end()) continue; add_uniform_vector(name1, name2, type); } else { add_uniform_scalar(name, type); } } }
/** * Show detailed information for all uniforms of this program */ void SciIllLib::CGLShaderProgram::showUniformInformation() { std::cout << "Getting ShaderProgram uniform information: " << std::endl; int count = 0; glGetProgramiv(m_hndProgram, GL_ACTIVE_UNIFORMS, &count); if (count == 0) { std::cout << "--> No uniforms defined!" << std::endl; return; } GLsizei bufSize = 256; GLint size; GLsizei length; GLenum type; char* name = new char[bufSize]; for (int idx=0; idx < count; idx++) { glGetActiveUniform(m_hndProgram, idx, bufSize, &length, &size, &type, name); std::cout << "- " << idx << ":" << name << ", "; printTypeInfo(type); std::cout << std::endl; } }
static int CountUniforms( const ShaderProgram* program ) { static char name[MAX_UNIFORM_NAME_SIZE]; int count = 0; int activeUniformCount = 0; glGetProgramiv(program->handle, GL_ACTIVE_UNIFORMS, &activeUniformCount); REPEAT(activeUniformCount, i) { int size = 0; GLenum glType = GL_ZERO; glGetActiveUniform( program->handle, i, MAX_UNIFORM_NAME_SIZE-1, NULL, &size, &glType, name ); const int location = glGetUniformLocation(program->handle, name); if(location == -1) continue; count += size; // treat array elements as full uniforms }
void COpenGLShaderProgram::GetShaderUniform() { //glGetProgramInterface л┬ий╩й GLint uniformsNum = 0; GLDebug(glGetProgramiv(m_hProgram, GL_ACTIVE_UNIFORMS, &uniformsNum)); if (uniformsNum > 0) { GLint maxLength; GLDebug(glGetProgramiv(m_hProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); char *name = new char[maxLength]; for (int i = 0; i < uniformsNum; ++i) { Uniform uniform; GLenum type; GLsizei nameLength; GLDebug(glGetActiveUniform(m_hProgram, i, maxLength, &nameLength, &uniform.m_count, &type, name)); uniform.m_format = GetUniformFormat(type); if (uniform.m_format == UF_UNKNOWN) { printf("GetUniformFormat:UF_UNKNOWN [%s:%d]", __FILE__, __LINE__); } strncpy(uniform.m_name, name, MAX_FILE_NAME - 1); uniform.m_size = GetUniformTypeSize(uniform.m_format); uniform.m_location = i; m_uniforms[i] = uniform; } delete name; } }
std::string Uniform::getName() { GLint size; GLenum type; GLchar name[256]; glGetActiveUniform(program, id, 255, NULL, &size, &type, name); return std::string(name); }
shaderparameter_t* shader_get_param(shaderprogram_t* program, const char* name, ShaderParamType type) { GLint paramIndex = 0; GLint paramSize = 0; GLenum paramType; switch(type) { default: case ShaderParamType_Uniform: { GLsizei nameLength; paramIndex = glGetUniformLocation(program->program, name); glGetActiveUniform(program->program, paramIndex, 0, &nameLength, ¶mSize, ¶mType, nullptr); FOUNDATION_ASSERT(paramSize > 0); } case ShaderParamType_UniformBlock: { paramIndex = glGetUniformBlockIndex(program->program, name); glGetActiveUniformBlockiv(program->program, paramIndex, GL_UNIFORM_BLOCK_DATA_SIZE, ¶mSize); FOUNDATION_ASSERT(paramSize > 0); } } shaderparameter_t* param = (shaderparameter_t*) memory_allocate(sizeof(shaderparameter_t), 4, MEMORY_PERSISTENT); param->index = paramIndex; param->size = paramSize; param->gltype = paramType; param->name = string_clone(name); param->type = type; return param; }
static GLint get_uniform_vector(const char *name, GLuint program, GLenum *type) { glGetError(); // flush current error state. GLint size; GLint location; // Get the position for the uniform var. if(GLSLProgram::m_bGLUseARB) { location=glGetUniformLocationARB(program, name); } else { location=glGetUniformLocation(program, name); } GLenum gl_err = glGetError(); if(gl_err != GL_NO_ERROR || location == -1) { throw GL_ERROR(gl_err); } if (GLSLProgram::m_bGLUseARB) { glGetActiveUniformARB(program, location, 0, NULL, &size, type, NULL); } else { glGetActiveUniform(program, location, 1, &AtiHackLen, &size, type, &AtiHackChar); } gl_err = glGetError(); if(gl_err != GL_NO_ERROR) { T_ERROR("Error getting type."); throw GL_ERROR(gl_err); } return location; }
Handle<Value> GLESglGetActiveUniformCallback(const Arguments& args) { if (args.Length() != 2) return v8::Undefined(); unsigned program = args[0]->Uint32Value(); unsigned index = args[1]->Uint32Value(); char name[256]; int length = 0; int size = 0; unsigned type = 0; glGetActiveUniform((GLuint)program, (GLuint)index, (GLsizei)sizeof(name), (GLsizei*)&length, (GLint*)&size, (GLenum*)&type, (GLchar*)name); // Create a template for the answer object that'll hold // type/size/name as properties Handle<Object> ans = Object::New(); ans->Set(String::New("type"), Uint32::New(type)); ans->Set(String::New("size"), Integer::New(size)); ans->Set(String::New("name"), String::New(name)); return ans; }
void App::parseUniforms() { // clean up if (uniforms) {delete [] uniforms; uniforms = nullptr;} if (uniform_data) {delete [] uniform_data; uniform_data = nullptr;} // get uniform count glGetProgramiv(shader.getProgram(), GL_ACTIVE_UNIFORMS, &uniform_count); if (uniform_count == 0) return; // shader has no uniforms uniforms = new ShaderUniform[uniform_count]; // 1st pass: parse uniforms and calculate data size uniform_data_size = 0; for (int uniform_index = 0; uniform_index < uniform_count; uniform_index++) { ShaderUniform *uniform = uniforms+uniform_index; GLsizei uniform_name_len; glGetActiveUniform(shader.getProgram(), uniform_index, (GLsizei)sizeof(uniform->name), &uniform_name_len, &uniform->size, &uniform->type, uniform->name); uniform->location = shader.getUniformLocation(uniform->name); uniform_data_size += uniform->getSize(); if (strstr(uniform->name, "color")) uniform->flags |= SUF_IS_COLOR; } uniform_data = new u8[uniform_data_size]; memset(uniform_data, 0, uniform_data_size); // 2nd pass: store offsets into uniform_data for each uniform size_t offset = 0; for (int uniform_index = 0; uniform_index < uniform_count; uniform_index++) { ShaderUniform *uniform = uniforms+uniform_index; uniform->data = uniform_data+offset; offset += uniform->getSize(); } }
void VSShaderLib::addUniforms() { int count; GLsizei actualLen; GLint size; GLint uniArrayStride; GLenum type; char *name; int maxUniLength; glGetProgramiv(pProgram, GL_ACTIVE_UNIFORMS, &count); glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLength); name = (char *)malloc(sizeof(char) * maxUniLength); unsigned int loc; for (int i = 0; i < count; ++i) { glGetActiveUniform(pProgram, i, maxUniLength, &actualLen, &size, &type, name); // -1 indicates that is not an active uniform, although it may be present in a // uniform block loc = glGetUniformLocation(pProgram, name); if (loc != -1) { glGetActiveUniformsiv(pProgram, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride); addUniform(name, type, size); } } free(name); }
GLvoid Shader::fetchUniforms() { GLint iParams = 0; GLsizei iMaxLength = 0; GLint iSize = 0; GLint iWritten = 0; GLenum eType = 0; GLchar* cpName = NULL; //GLint iLocation = 0; glGetProgramiv(uiProgramID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &iMaxLength); glGetProgramiv(uiProgramID, GL_ACTIVE_UNIFORMS, &iParams); iUniformSize = iParams; cpName = new GLchar[iMaxLength]; pUniformNames = new std::string[iParams]; pUniformLocation = new GLint[iParams]; for (GLint i = 0; i < iParams; ++i) { glGetActiveUniform(uiProgramID, i, iMaxLength, &iWritten, &iSize, &eType, cpName); pUniformLocation[i] = glGetUniformLocation(uiProgramID, cpName); pUniformNames[i] = cpName; mapUniform[pUniformNames[i]] = pUniformLocation[i]; /*iLocation = glGetUniformLocation(uiProgramID, cpName); mapUniform[iLocation] = cpName;*/ } }
void kzsGLSL::printActiveUniforms() { GLint nUniforms, size, location, maxLen; GLchar* name; GLsizei written; GLenum type; glGetProgramiv( shaderProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen ); glGetProgramiv( shaderProgram, GL_ACTIVE_UNIFORMS, &nUniforms ); name = ( GLchar* ) malloc( maxLen ); printf( " Location | Name\n" ); printf( "------------------------------------------------\n" ); for (int i = 0; i < nUniforms; i++) { glGetActiveUniform( shaderProgram, i, maxLen, &written, &size, &type, name ); location = glGetUniformLocation( shaderProgram, name ); printf(" %-8d | %s\n",location, name); } printf( "\n" ); free( name ); }
const std::vector< GLSLProgram::UniformInformations > GLSLProgram::getActiveUniforms() const { if ( isInUse() ) { // number of active uniforms GLint numUniforms; glGetProgramiv( getProgramObject(), GL_ACTIVE_UNIFORMS, &numUniforms ); GLint maxLength; glGetProgramiv( getProgramObject(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength ); std::vector< UniformInformations > uniforms(numUniforms, UniformInformations(maxLength) ); // for each uniform, do for( GLint index = 0; index< numUniforms; ++index ) { UniformInformations& uniform = uniforms[index]; glGetActiveUniform( getProgramObject(), index, uniform.name.size(), 0, &uniform.size, &uniform.type, &uniform.name[0] ); } return uniforms; } else { std::vector< UniformInformations > uniforms; return uniforms; } }
std::vector<ShaderVariableInfo> ShaderFactory::get_uniform_infos(const unsigned int program) { std::vector<ShaderVariableInfo> uniform_infos; std::vector<char> name_buffer; int active_uniforms = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniforms); uniform_infos.reserve(active_uniforms); int max_uniform_name_length = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_length); name_buffer.assign(max_uniform_name_length+1, '\0'); for (int i = 0; i < active_uniforms; ++i) { int name_length = 0; int size = 0; GLenum type = 0; glGetActiveUniform(program, i, name_buffer.size(), &name_length, &size, &type, name_buffer.data()); std::string name(name_buffer.begin(), name_buffer.begin() + name_length); //if (name.compare(0, 3, "gl_") != 0) { // We do not add uniform values that can not be modified by glUniform* og glProgramUniform* uniform_infos.emplace_back(name, type, size, glGetUniformLocation(program, name.c_str())); } } return uniform_infos; }
UniformInfo Program::getUniformInfo(const GLint index) const { UniformInfo ui; ui.index = index; if(index < 0) { WARNING("Tried to get info on shader with bad index."); ui.name = ""; ui.size = 0; ui.type = 0; return ui; } // The the maximum size of the attribe name GLsizei max_name_length; getProgram(Program::ActiveUniformMaxLength, &max_name_length); GLsizei length; std::vector<GLchar> name(max_name_length); // Retrive atribute data and store it in the info struct glGetActiveUniform(getProgramId(), index, name.size(), &length, &ui.size, &ui.type, &name[0]); ui.name = std::string(&name[0], length); return ui; }
void ShaderAPITest::test_uniform_size_type1(const char *glslType, GLenum glType, const char *el) { char buffer[1024]; GLuint program; GLint active, i; //printf(" Running subtest %s\n", glslType); //fflush(stdout); sprintf(buffer, "#version 120\nuniform %s m[60];\nvoid main() { gl_Position[0] = m[59]%s; }\n", glslType, el); program = make_program(buffer, NULL); glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active); assert_no_error(); for (i = 0; i < active; i++) { GLint size = -1; GLenum type = 0; glGetActiveUniform(program, i, sizeof(buffer), NULL, &size, &type, buffer); assert_no_error(); assert(type == glType); assert(size == 60); if (strncmp(buffer, "m", 1) == 0) break; } }
//-------------------------------------------------------------- void ofShader::printActiveUniforms() const{ GLint numUniforms = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); ofLogNotice("ofShader") << numUniforms << " uniforms"; GLint uniformMaxLength = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxLength); GLint count = -1; GLenum type = 0; GLchar* uniformName = new GLchar[uniformMaxLength]; stringstream line; for(GLint i = 0; i < numUniforms; i++) { GLsizei length; glGetActiveUniform(program, i, uniformMaxLength, &length, &count, &type, uniformName); line << "[" << i << "] "; for(int j = 0; j < length; j++) { line << uniformName[j]; } line << " @ index " << getUniformLocation(uniformName); ofLogNotice("ofShader") << line.str(); line.str(""); } delete [] uniformName; }
void CShaderObject::HashSamplers() { glUseProgram(m_shaderObject); int nUniforms = 0; int nSamplers = 0; glGetProgramiv(m_shaderObject, GL_ACTIVE_UNIFORMS, &nUniforms); GLint* size = (GLint*)malloc(nUniforms * sizeof(GLint)); GLenum* type = (GLenum*)malloc(nUniforms * sizeof(GLenum)); GLsizei* length = (GLsizei*)malloc(nUniforms * sizeof(GLsizei)); GLchar** name = (GLchar**)malloc(nUniforms * sizeof(GLcharARB**)); for (int i = 0; i < nUniforms; i++) { name[i] = (GLcharARB*)malloc(MAX_UNIFORM_LEN * sizeof(GLcharARB)); glGetActiveUniform(m_shaderObject, i, MAX_UNIFORM_LEN, &length[i], &size[i], &type[i], name[i]); if(type[i] >= GL_SAMPLER_1D_ARB && type[i] <= GL_SAMPLER_2D_RECT_SHADOW_ARB) { m_samplerHash.Add(name[i], nSamplers); glUniform1i(glGetUniformLocation(m_shaderObject, name[i]), nSamplers); ++nSamplers; } } free(size); free(type); free(length); free(name); glUseProgram(0); }