Exemple #1
0
// used for debugging to print the offsets of uniform buffer members 
void printUniformOffsets(GLuint program, GLuint uniformBlock)
{
    GLchar name[256];
    GLint uniformCount;
    glGetActiveUniformBlockiv( program, uniformBlock, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformCount );

    GLint *indices = new GLint[uniformCount];
    glGetActiveUniformBlockiv( program, uniformBlock, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices );

    for ( GLint i = 0; i < uniformCount; ++i )
    {
        const GLuint index = (GLuint)indices[i];

        GLint type, offset;

        glGetActiveUniformName(program, index, 256, 0, name); 
        glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_TYPE, &type);
        glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_OFFSET, &offset);

        std::cout << " " << name << " (offset) : " << offset << std::endl;
    }
    std::cout << std::endl;

    delete [] indices;
}
Exemple #2
0
//----------------------------------------------------------
static void GetUniforms(GLuint shader, Shader::ShaderParamList& params)
{
  GLint numUniforms = 0;
  glGetProgramiv(shader, GL_ACTIVE_UNIFORMS, &numUniforms);

  std::vector<GLuint> indices(numUniforms);
  std::vector<GLint>  nameLengths(numUniforms);
  std::vector<GLint>  blockIndices(numUniforms);

  for (int i = 0; i < numUniforms; ++i)
  {
    indices[i] = i;
  }
  glGetActiveUniformsiv(shader, numUniforms, indices.data(), GL_UNIFORM_BLOCK_INDEX, blockIndices.data());
  glGetActiveUniformsiv(shader, numUniforms, indices.data(), GL_UNIFORM_NAME_LENGTH, nameLengths.data());

  for (int i = 0; i < numUniforms; ++i)
  {
    if (blockIndices[i] == -1)  // Uniform is not a block...
    {
      std::vector<char> buffer(nameLengths[i]);
      glGetActiveUniformName(shader, i, buffer.size(), NULL, buffer.data());

      ShaderParamPtr p(new ShaderParam(shader, buffer.data()));

      std::string name(buffer.data());
      params[name] = p;
    }
  }
}
void ShaderPair::PrintActiveUniforms()
{
	if(ready)
	{
		GLint numUniforms;
		glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms);
			
		if(numUniforms > 0)
		{
			std::vector<std::string> nameList;
			nameList.reserve(numUniforms);

			for(int i = 0; i < numUniforms; ++i)
			{
				GLchar name[64];
				GLint  len;
				glGetActiveUniformName(program, i, 64, &len, &name[0]);

				nameList.push_back(std::string(name));
			}

			LogMessage("\nCurrent active Uniform variables in program:\n");

			for(size_t i = 0; i < nameList.size(); i++)
			{
				LogError("%s\n",nameList[i].c_str());
			}
		}
	}
}
std::string Program::getActiveUniformName(GLuint uniformIndex) const
{
    checkDirty();

    GLint length = getActiveUniform(uniformIndex, GL_UNIFORM_NAME_LENGTH);
    std::vector<char> name(length);
    glGetActiveUniformName(id(), uniformIndex, length, nullptr, name.data());

    return std::string(name.data(), length);
}
bool effect::create()
{
	_program = createProgram(&_shaders[0], _shaders.size());
	if (!_program)
		return false;

	std::vector<std::string> uniformNames;
	GLint numUniforms, maxLength;
	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
	glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &numUniforms);
	char* buf = new char[maxLength];
	for (int i = 0; i < numUniforms; ++i)
	{
		GLsizei size;
		glGetActiveUniformName(_program, i, maxLength, &size, buf);
		std::string name(buf);
		if (uniformNames.size() > 0 && uniformNames[i - 1] == name)
			break;
		else
			uniformNames.push_back(name);
	}
	delete[] buf;

	for (int i = 0; i < uniformNames.size(); ++i)
	{
		GLint uniformLocation = glGetUniformLocation(_program, uniformNames[i].c_str());
		if (uniformLocation != -1) _uniforms[uniformNames[i]] = uniformLocation;
	}

	std::vector<std::string> uniformBlockNames;
	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength);
	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniforms);
	buf = new char[maxLength];
	for (int i = 0; i < numUniforms; ++i)
	{
		GLsizei size;
		glGetActiveUniformBlockName(_program, i, maxLength, &size, buf);
		std::string name(buf);
		if (uniformBlockNames.size() > 0 && uniformBlockNames[i - 1] == name)
			break;
		else
			uniformBlockNames.push_back(name);
	}
	delete[] buf;

	for (int i = 0; i < uniformBlockNames.size(); ++i)
	{
		GLuint blockIndex = glGetUniformBlockIndex(_program, uniformBlockNames[i].c_str());
		glUniformBlockBinding(_program, blockIndex, i);
		_blockUniforms[uniformBlockNames[i]] = i;
	}

	return true;
}
void PrintActiveUniforms(GLuint handle){
		
	GLint activeUniforms,length;
	glGetProgramiv(handle,GL_ACTIVE_UNIFORMS,&activeUniforms);

	for(int index = 0; index < activeUniforms; index++){
		char* uniformName = new char[50];
		glGetActiveUniformName(handle,index,50,&length,uniformName);
		printf(uniformName);
		delete [] uniformName;
	}
}
Exemple #7
0
std::string Program::getActiveUniformName(const GLuint uniformIndex) const
{
    checkDirty();

    GLint length = getActiveUniform(uniformIndex, GL_UNIFORM_NAME_LENGTH);
    assert(length > 1); // Has to include at least 1 char and '\0'
        
    std::vector<char> name(length);
    glGetActiveUniformName(id(), uniformIndex, length, nullptr, name.data());

	// glGetActiveUniformName() insists we query '\0' as well, but it 
	// shouldn't be passed to std::string(), otherwise std::string::size()
	// returns <actual size> + 1 (on clang)	
    auto numChars = length - 1; 
    return std::string(name.data(), numChars);
}
bool ShaderUniformBuffer::createUniforms(UNIFORM_BUFFER_DESC* pdescs, int nr)
{
   glGetActiveUniformBlockiv(mProgram, mBlock, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &mElementNr);
   GLuint* pindices = new GLuint[mElementNr];
   glGetActiveUniformBlockiv(mProgram, mBlock, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*) pindices);

   GLint maxlength;
   glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlength);
   GLchar* pname = new GLchar[maxlength];

   mpElements = new BLOCK_UNIFORM[mElementNr];
   for ( int index = 0; index < mElementNr; ++index )
   {
      BLOCK_UNIFORM& element = mpElements[index];

      int length;
      glGetActiveUniformName(mProgram, pindices[index], maxlength, &length, pname);
      element.name = String::fromUtf8(pname);

      glGetActiveUniformsiv(mProgram, 1, &pindices[index], GL_UNIFORM_OFFSET, &element.offset);
      
      int offset = 0;
      for ( int src = 0; src < nr; ++src )
      {
         UNIFORM_BUFFER_DESC& desc = pdescs[src];
         if ( desc.name == element.name )
         {
            element.source_offset = offset;
            element.size = desc.size;
            break;
         }
         else
         {
            offset += desc.size;
         }
      }
   }

   // determine total buffer size that needs to be allocated
   glGetActiveUniformBlockiv(mProgram, mBlock, GL_UNIFORM_BLOCK_DATA_SIZE, &mBufferSize);

   return true;
}
bool GLUniform::CreateUBO(GLuint program, GLuint location, GLenum draw)
{
    GLint size;
    GLint type;
    GLint offset;
    std::string uname;
    GLsizei dataSize = 0;
    GLsizeiptr uniformSize;
    Uniform unif;
    this->location = location;
    GLint numUniforms;
    GLuint index;
    GLint padding = 0;
      
    this->block = glGetUniformBlockIndex(program, this->name.c_str());
    std::cout<<"Block index "<<block<< " and location "<<location<<std::endl;
    glGetActiveUniformBlockiv( program, this->block, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
    GLint *indices = new GLint[numUniforms];
    glGetActiveUniformBlockiv( program, this->block, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices );

    for( int i = 0; i < numUniforms; i++)
    {
        index = (GLuint)indices[i];

        glGetActiveUniformName(program, index, 256, 0, &uname[0]);
        glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_TYPE, &type);
        glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_OFFSET, &offset);
        glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_SIZE, &size);

        if(type == GL_FLOAT_VEC3)
            uniformSize = sizeof(glm::vec3);
        else if(type == GL_FLOAT_VEC2)
             uniformSize = sizeof(glm::vec2);
        else if(type == GL_FLOAT_VEC4)
            uniformSize = sizeof(glm::vec4);
        else if(type == GL_FLOAT_MAT4)
            uniformSize = sizeof(glm::mat4);
        else if(type == GL_FLOAT_MAT3)
            uniformSize = sizeof(glm::mat3);
        else if(type == GL_INT)
        {
            uniformSize = sizeof(int);
            padding += 3*sizeof(int);
        }
        else if(type == GL_FLOAT)
        {
            uniformSize = sizeof(float);
            padding += 3*sizeof(float);
        }
        else 
            uniformSize = 0.0f;

        dataSize += size*uniformSize;

        unif = {&uname[0], static_cast<GLint>(size*uniformSize), index, offset};
		this->uniforms[&uname[0]] = unif;

        std::cout << "Uniform <" << unif.name << "> (offset): " << unif.offset <<", (size): " <<unif.size<< ", (index): "<<unif.index<< std::endl;
    }

    GLBufferObject ubo(name.c_str(), dataSize + padding, (GLuint)1, GL_UNIFORM_BUFFER, draw); 
    if( ubo.Status(GL_UNIFORM_BUFFER, dataSize) )
    {
            std::cerr << "[E] Buffer " << name << " not created."<<std::endl;
            return false;
    }

    glBindBufferBase(ubo.Type(), location, ubo.Buffer());

    this->block = glGetUniformBlockIndex(program, this->name.c_str());
    std::cout<<"Block index "<<this->block<< " after bind "<<std::endl;
    ubo.SetBlockIndex(this->block); 
    
    this->id = ubo.Buffer();

	glBindBuffer(GL_UNIFORM_BUFFER, 0);

    delete [] indices;

    return true;
}
void
piglit_init(int argc, char **argv)
{
        struct atomic_counters_limits ls = atomic_counters_get_limits();
        bool visited_buffers[8] = { false };
        bool visited_counters[8] = { false };
        GLuint prog = glCreateProgram();
        int i, j, n, ret;

        piglit_require_gl_version(31);
        piglit_require_extension("GL_ARB_shader_atomic_counters");

        if (ls.fragment_counters < 9) {
                fprintf(stderr, "Insufficient number of supported atomic "
                        "counters.\n");
                piglit_report_result(PIGLIT_SKIP);
        }

        if (ls.fragment_buffers < 4) {
                fprintf(stderr, "Insufficient number of supported atomic "
                        "counter buffers.\n");
                piglit_report_result(PIGLIT_SKIP);
        }

        if (!atomic_counters_compile(prog, GL_FRAGMENT_SHADER, fs_source)) {
                fprintf(stderr, "Program failed to compile.\n");
                piglit_report_result(PIGLIT_FAIL);
        }

        if (!atomic_counters_link(prog)) {
                fprintf(stderr, "Program failed to link.\n");
                piglit_report_result(PIGLIT_FAIL);
        }

        glGetProgramiv(prog, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, &n);
        if (n != 4) {
                fprintf(stderr, "Unexpected number of active counter "
                        "buffers.\n");
                piglit_report_result(PIGLIT_FAIL);
        }

        ret = 0xdeadbeef;
        glGetActiveAtomicCounterBufferiv(
                prog, n, GL_ATOMIC_COUNTER_BUFFER_BINDING, &ret);

        if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
                fprintf(stderr, "glGetActiveAtomicCounterBufferiv should have "
                        "failed when trying to query a non-existent buffer.\n");
                piglit_report_result(PIGLIT_FAIL);
        }

        if (ret != 0xdeadbeef) {
                fprintf(stderr, "Failed call to glGetActiveAtomicCounterBufferiv"
                        "didn't preserve the output parameter contents.\n");
                piglit_report_result(PIGLIT_FAIL);
        }

        for (i = 0; i < n; ++i) {
                const struct buffer_info *binfo;
                int binding, data_size, num_counters, ref;
                GLuint counters[4];

                glGetActiveAtomicCounterBufferiv(
                        prog, i, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
                if (!piglit_check_gl_error(GL_NO_ERROR)) {
                        fprintf(stderr, "Couldn't obtain counter buffer binding"
                                " point.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                binfo = expected_buffer_info(binding);
                if (!binfo) {
                        fprintf(stderr, "Got unexpected buffer binding "
                                "point.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(
                        prog, i, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE,
                        &data_size);
                if (!piglit_check_gl_error(GL_NO_ERROR) ||
                    data_size < binfo->min_reasonable_size) {
                        fprintf(stderr, "Invalid buffer data size: %d,"
                               " expected at least: %d.\n", data_size,
                               binfo->min_reasonable_size);
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(
                        prog, i, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS,
                        &num_counters);
                if (!piglit_check_gl_error(GL_NO_ERROR) ||
                    num_counters != binfo->num_counters) {
                        fprintf(stderr, "Invalid number of atomic counters: %d,"
                               " expected: %d.\n", num_counters,
                               binfo->num_counters);
                        piglit_report_result(PIGLIT_FAIL);
                }

                if (visited_buffers[i]) {
                        fprintf(stderr, "Buffer at binding point %d seen twice."
                                "\n", binding);
                        piglit_report_result(PIGLIT_FAIL);
                }
                visited_buffers[i] = true;

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER,
                        &ref);
                if (!piglit_check_gl_error(GL_NO_ERROR) || ref) {
                        fprintf(stderr, "Buffer incorrectly reported to be "
                                "referenced by vertex shader.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER,
                        &ref);
                if (!piglit_check_gl_error(GL_NO_ERROR) || ref) {
                        fprintf(stderr, "Buffer incorrectly reported to be "
                                "referenced by tessellation control shader.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER,
                        &ref);
                if (!piglit_check_gl_error(GL_NO_ERROR) || ref) {
                        fprintf(stderr, "Buffer incorrectly reported to be "
                                "referenced by tessellation evaluation shader."
                                "\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER,
                        &ref);
                if (!piglit_check_gl_error(GL_NO_ERROR) || ref) {
                        fprintf(stderr, "Buffer incorrectly reported to be "
                                "referenced by geometry shader.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER,
                        &ref);
                if (!piglit_check_gl_error(GL_NO_ERROR) || !ref) {
                        fprintf(stderr, "Buffer incorrectly reported as "
                                "unreferenced from the fragment shader.\n");
                        piglit_report_result(PIGLIT_FAIL);
                }

                glGetActiveAtomicCounterBufferiv(prog, i,
                        GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES,
                        (GLint *)counters);
                if (!piglit_check_gl_error(GL_NO_ERROR)) {
                        fprintf(stderr, "Couldn't obtain list of active atomic "
                                "counters for buffer at binding point %d.\n",
                                binding);
                        piglit_report_result(PIGLIT_FAIL);
                }

                for (j = 0; j < num_counters; ++j) {
                        const struct counter_info *cinfo;
                        int unif_type, unif_size, unif_name_len,
                                unif_block_idx, unif_offset, unif_stride,
                                unif_buffer_idx;
                        char unif_name[8];

                        glGetActiveUniformName(prog, counters[j],
                                               sizeof(unif_name), NULL,
                                               unif_name);

                        cinfo = expected_counter_info(unif_name);
                        if (!piglit_check_gl_error(GL_NO_ERROR) || !cinfo) {
                                fprintf(stderr, "Unknown atomic counter \"%s\"."
                                        "\n", unif_name);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_TYPE, &unif_type);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_type != GL_UNSIGNED_INT_ATOMIC_COUNTER) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid type 0x%x, expected 0x%x.\n",
                                        unif_name, unif_type,
                                        GL_UNSIGNED_INT_ATOMIC_COUNTER);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_SIZE, &unif_size);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_size != cinfo->size) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid size %d, expected: %d.\n",
                                        unif_name, unif_size, cinfo->size);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_NAME_LENGTH, &unif_name_len);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_name_len != strlen(unif_name) + 1) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid name length %d, expected: %d."
                                        "\n", unif_name, unif_name_len,
                                        (int)strlen(unif_name) + 1);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_BLOCK_INDEX, &unif_block_idx);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_block_idx != -1) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid block index %d, expected: -1."
                                        "\n", unif_name, unif_block_idx);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_OFFSET, &unif_offset);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_offset != cinfo->offset) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid offset %d, expected: %d.\n",
                                        unif_name, unif_offset, cinfo->offset);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_ARRAY_STRIDE, &unif_stride);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            (cinfo->size > 1 && unif_stride < 4) ||
                            (cinfo->size == 1 && unif_stride != 0)) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid array stride %d.\n",
                                        unif_name, unif_stride);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        glGetActiveUniformsiv(prog, 1, &counters[j],
                                              GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX,
                                              &unif_buffer_idx);
                        if (!piglit_check_gl_error(GL_NO_ERROR) ||
                            unif_buffer_idx != i) {
                                fprintf(stderr, "Atomic counter \"%s\" has "
                                        "invalid buffer index %d, expected %d."
                                        "\n", unif_name, unif_buffer_idx, i);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        if (cinfo->binding != binding) {
                                fprintf(stderr, "Atomic counter \"%s\" belongs "
                                        "to the wrong binding point %d.\n",
                                        unif_name, binding);
                                piglit_report_result(PIGLIT_FAIL);
                        }

                        if (visited_counters[counters[j]]) {
                                fprintf(stderr, "Atomic counter \"%s\" seen "
                                        "twice.\n", unif_name);
                                piglit_report_result(PIGLIT_FAIL);
                        }
                        visited_counters[counters[j]] = true;
                }
        }

        glDeleteProgram(prog);

        piglit_report_result(PIGLIT_PASS);
}
Exemple #11
0
UniformBuffer::UniformBuffer(const Shader& shader,
                             const string& block_name) 
{
    GLuint program = shader.get_program_ID();
    GLint max_uniform_length;
    GLint uniform_count;
    
    glGetProgramiv(program, 
                   GL_ACTIVE_UNIFORM_MAX_LENGTH, 
                   &max_uniform_length);
    
    GLuint block_index = glGetUniformBlockIndex(program, block_name.c_str());
    glGetActiveUniformBlockiv(program, block_index, 
                              GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniform_count);

    char* uniform_name = new char[max_uniform_length];
    GLint* uniform_indices = new GLint[uniform_count];

    glGetActiveUniformBlockiv(program, block_index, 
                              GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
                              uniform_indices);

    GLint uniform_block_size;

    glGetActiveUniformBlockiv(program, block_index,
                              GL_UNIFORM_BLOCK_DATA_SIZE,
                              &uniform_block_size);

    _buffer = new byte[uniform_block_size];

    _buffer_size = uniform_block_size;


    const boost::regex pattern(block_name+"\\.(.*)$");  // ..fourth
    boost::match_results<std::string::const_iterator> match;

    for (int i = 0; i < uniform_count; ++i) {
        glGetActiveUniformName(program, uniform_indices[i], 
                               max_uniform_length, NULL, uniform_name);
        
        GLint size;
        GLint offset;
        GLint array_stride;
        GLint matrix_stride;
        GLint is_row_major;

        glGetActiveUniformsiv(program, 1, (GLuint*)uniform_indices + i,
                              GL_UNIFORM_SIZE, &size);
        glGetActiveUniformsiv(program, 1, (GLuint*)uniform_indices + i,
                              GL_UNIFORM_OFFSET, &offset);
        glGetActiveUniformsiv(program, 1, (GLuint*)uniform_indices + i,
                              GL_UNIFORM_ARRAY_STRIDE, &array_stride);
        glGetActiveUniformsiv(program, 1, (GLuint*)uniform_indices + i,
                              GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
        glGetActiveUniformsiv(program, 1, (GLuint*)uniform_indices + i,
                              GL_UNIFORM_IS_ROW_MAJOR, &is_row_major);

        Entry entry = {(size_t)offset,
                       (size_t)matrix_stride,
                       (is_row_major == GL_TRUE) ? true : false,
                       (size_t)array_stride,
                       (size_t)size};

        string uniform_name_str(uniform_name);
        if (boost::regex_match(uniform_name_str, match, pattern)) {
            _entries[string(match[1])] = entry;
        } else {
            _entries[uniform_name_str] = entry;
        }

    }

    delete[] uniform_name;
    delete[] uniform_indices;

    glGenBuffers(1, &_buffer_object);


    glBindBuffer(GL_UNIFORM_BUFFER, _buffer_object);

    glBufferData(GL_UNIFORM_BUFFER, _buffer_size, _buffer, GL_DYNAMIC_DRAW);

    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    _block_index = block_index;
    _buffer_binding = 0xffffffff;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL31_nglGetActiveUniformName(JNIEnv *env, jclass clazz, jint program, jint uniformIndex, jint bufSize, jlong length, jlong uniformName, jlong function_pointer) {
	GLsizei *length_address = (GLsizei *)(intptr_t)length;
	GLchar *uniformName_address = (GLchar *)(intptr_t)uniformName;
	glGetActiveUniformNamePROC glGetActiveUniformName = (glGetActiveUniformNamePROC)((intptr_t)function_pointer);
	glGetActiveUniformName(program, uniformIndex, bufSize, length_address, uniformName_address);
}
	bool initProgram()
	{
		bool Validated = true;

		compiler Compiler;
	
		// Create program
		if(Validated)
		{
			compiler Compiler;
			GLuint VertShaderName = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERT_SHADER_SOURCE, "--version 150 --profile core");
			GLuint FragShaderName = Compiler.create(GL_FRAGMENT_SHADER, getDataDirectory() + FRAG_SHADER_SOURCE, "--version 150 --profile core");

			ProgramName = glCreateProgram();
			glAttachShader(ProgramName, VertShaderName);
			glAttachShader(ProgramName, FragShaderName);

			glBindAttribLocation(ProgramName, semantic::attr::POSITION, "Position");
			glBindFragDataLocation(ProgramName, semantic::frag::COLOR, "Color");
			glLinkProgram(ProgramName);

			Validated = Validated && Compiler.check();
			Validated = Validated && Compiler.checkProgram(ProgramName);
		}

		// Get variables locations
		if(Validated)
		{
			UniformMaterial = glGetUniformBlockIndex(ProgramName, "material");
			UniformTransform = glGetUniformBlockIndex(ProgramName, "transform");

			glUniformBlockBinding(ProgramName, UniformTransform, semantic::uniform::TRANSFORM0);
			glUniformBlockBinding(ProgramName, UniformMaterial, semantic::uniform::MATERIAL);
		}

		GLint ActiveUniformBlocks(0);
		glGetProgramiv(ProgramName, GL_ACTIVE_UNIFORM_BLOCKS, &ActiveUniformBlocks);

		for(GLint i = 0; i < ActiveUniformBlocks; ++i)
		{
			char Name[128];
			memset(Name, '\0', sizeof(Name));
			GLsizei Length(0);

			glGetActiveUniformBlockName(ProgramName, i, GLsizei(sizeof(Name)), &Length, Name);

			std::string StringName(Name);

			Validated = Validated && (StringName == std::string("material") || StringName == std::string("transform"));
		}

		GLint ActiveUniform(0);
		glGetProgramiv(ProgramName, GL_ACTIVE_UNIFORMS, &ActiveUniform);

		for(GLint i = 0; i < ActiveUniformBlocks; ++i)
		{
			char Name[128];
			memset(Name, '\0', sizeof(Name));
			GLsizei Length(0);

			glGetActiveUniformName(ProgramName, i, GLsizei(sizeof(Name)), &Length, Name);

			std::string StringName(Name);

			Validated = Validated && (
				StringName == std::string("material.Diffuse") || 
				StringName == std::string("transform.MVP"));
		}
	
		return Validated && this->checkError("initProgram");
	}
Exemple #14
0
void
OGLShaderObject::_initActiveUniformBlock() noexcept
{
	GLint numUniformBlock = 0;
	GLint maxUniformBlockLength = 0;
	GLint maxUniformLength = 0;

	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlock);
	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxUniformBlockLength);
	glGetProgramiv(_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLength);

	if (numUniformBlock)
	{
		auto nameUniformBlock = make_scope<GLchar[]>(maxUniformBlockLength + 1);
		nameUniformBlock[maxUniformBlockLength] = 0;

		for (GLint i = 0; i < numUniformBlock; ++i)
		{
			GLsizei lengthUniformBlock;
			glGetActiveUniformBlockName(_program, (GLuint)i, maxUniformBlockLength, &lengthUniformBlock, nameUniformBlock.get());

			GLuint location = glGetUniformBlockIndex(_program, nameUniformBlock.get());
			if (location == GL_INVALID_INDEX)
				continue;

			glUniformBlockBinding(_program, location, location);

			GLint size;
			GLint count;

			glGetActiveUniformBlockiv(_program, location, GL_UNIFORM_BLOCK_DATA_SIZE, &size);
			glGetActiveUniformBlockiv(_program, location, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &count);

			if (count)
			{
				std::vector<GLint> indices(count);
				glGetActiveUniformBlockiv(_program, location, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices.data());

				std::vector<GLint> offset((std::size_t)count);
				std::vector<GLint> type((std::size_t)count);
				std::vector<GLint> datasize((std::size_t)count);
				std::vector<std::string> varlist((std::size_t)count);
				std::vector<GLchar> name(maxUniformLength);

				glGetActiveUniformsiv(_program, count, (GLuint*)&indices[0], GL_UNIFORM_OFFSET, &offset[0]);
				glGetActiveUniformsiv(_program, count, (GLuint*)&indices[0], GL_UNIFORM_TYPE, &type[0]);
				glGetActiveUniformsiv(_program, count, (GLuint*)&indices[0], GL_UNIFORM_SIZE, &datasize[0]);

				for (GLint j = 0; j < count; ++j)
				{
					GLsizei length = 0;
#if !defined(EGLAPI)
					glGetActiveUniformName(_program, indices[j], maxUniformLength, &length, name.data());
#else
					glGetActiveUniform(_program, indices[j], maxUniformLength, &length, &datasize[j], (GLenum*)&type[j], name.data());
#endif
					
					varlist[j].append(name.data(), length);
				}

				auto uniformblock = std::make_shared<ShaderUniform>();
				uniformblock->setName(nameUniformBlock.get());
				uniformblock->setType(ShaderVariantType::SPT_BUFFER);
				uniformblock->setLocation(location);

				_activeUniforms.push_back(uniformblock);
			}
		}
	}
}
Exemple #15
0
void
VSShaderLib::addBlocks() {

	int count, dataSize, actualLen, activeUnif, maxUniLength;
	int uniType, uniSize, uniOffset, uniMatStride, uniArrayStride, auxSize;
	char *name, *name2;

	UniformBlock block;

	glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_BLOCKS, &count);

	for (int i = 0; i < count; ++i) {
		// Get buffers name
		glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &actualLen);
		name = (char *)malloc(sizeof(char) * actualLen);
		glGetActiveUniformBlockName(pProgram, i, actualLen, NULL, name);

		if (!spBlocks.count(name)) {
			// Get buffers size
			block = spBlocks[name];
			glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &dataSize);
			//printf("DataSize:%d\n", dataSize);
			glGenBuffers(1, &block.buffer);
			glBindBuffer(GL_UNIFORM_BUFFER, block.buffer);
			glBufferData(GL_UNIFORM_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW);
			glUniformBlockBinding(pProgram, i, spBlockCount);
			glBindBufferRange(GL_UNIFORM_BUFFER, spBlockCount, block.buffer, 0, dataSize);

			glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &activeUnif);

			unsigned int *indices;
			indices = (unsigned int *)malloc(sizeof(unsigned int) * activeUnif);
			glGetActiveUniformBlockiv(pProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (int *)indices);
			
			glGetProgramiv(pProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLength);
			name2 = (char *)malloc(sizeof(char) * maxUniLength);

			for (int k = 0; k < activeUnif; ++k) {
		
				myBlockUniform bUni;

				glGetActiveUniformName(pProgram, indices[k], maxUniLength, &actualLen, name2);
				glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_TYPE, &uniType);
				glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_SIZE, &uniSize);
				glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_OFFSET, &uniOffset);
				glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_MATRIX_STRIDE, &uniMatStride);
				glGetActiveUniformsiv(pProgram, 1, &indices[k], GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride);
			
				if (uniArrayStride > 0)
					auxSize = uniArrayStride * uniSize;
				
				else if (uniMatStride > 0) {

					switch(uniType) {
						case GL_FLOAT_MAT2:
						case GL_FLOAT_MAT2x3:
						case GL_FLOAT_MAT2x4:
						case GL_DOUBLE_MAT2:
						case GL_DOUBLE_MAT2x3:
						case GL_DOUBLE_MAT2x4:
							auxSize = 2 * uniMatStride;
							break;
						case GL_FLOAT_MAT3:
						case GL_FLOAT_MAT3x2:
						case GL_FLOAT_MAT3x4:
						case GL_DOUBLE_MAT3:
						case GL_DOUBLE_MAT3x2:
						case GL_DOUBLE_MAT3x4:
							auxSize = 3 * uniMatStride;
							break;
						case GL_FLOAT_MAT4:
						case GL_FLOAT_MAT4x2:
						case GL_FLOAT_MAT4x3:
						case GL_DOUBLE_MAT4:
						case GL_DOUBLE_MAT4x2:
						case GL_DOUBLE_MAT4x3:
							auxSize = 4 * uniMatStride;
							break;
					}
				}
				else
					auxSize = typeSize(uniType);

				bUni.offset = uniOffset;
				bUni.type = uniType;
				bUni.size = auxSize;
				bUni.arrayStride = uniArrayStride;

				block.uniformOffsets[name2] = bUni;


			}
			free(name2);

			block.size = dataSize;
			block.bindingIndex = spBlockCount;
			spBlocks[name] = block;
			spBlockCount++;
		}
		else
			glUniformBlockBinding(pProgram, i, spBlocks[name].bindingIndex);

	}

}
PIGLIT_GL_TEST_CONFIG_END

void
piglit_init(int argc, char **argv)
{
	unsigned int i;
	GLuint prog;
	const char *source =
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"uniform ubo1 { float a; };\n"
		"uniform ubo2 { float bb; float c; };\n"
		"uniform float dddd;\n"
		"void main() {\n"
		"	gl_FragColor = vec4(a + bb + c + dddd);\n"
		"}\n";
	int uniforms;
	bool pass = true;
	const char *names[4] = {"a", "bb", "c", "dddd"};
	bool found[4] = {false, false, false, false};
	char no_write;
	char fill_char = 0xd0;

	piglit_require_extension("GL_ARB_uniform_buffer_object");

	prog = piglit_build_simple_program(NULL, source);

	glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &uniforms);
	assert(uniforms == 4);

	for (i = 0; i < uniforms; i++) {
		GLint written_strlen = 0;
		GLint namelen = 9999;
		char name[1000];
		int name_index;

		/* This is the size including null terminator. */
		glGetActiveUniformsiv(prog, 1, &i,
				      GL_UNIFORM_NAME_LENGTH, &namelen);

		memset(name, 0xd0, sizeof(name));
		glGetActiveUniformName(prog, i, sizeof(name),
				       &written_strlen, name);
		if (written_strlen >= sizeof(name) - 1) {
			fprintf(stderr,
				"return strlen %d, longer than the buffer size\n",
				written_strlen);
			pass = false;
			continue;
		} else if (name[written_strlen] != 0) {
			fprintf(stderr, "return name[%d] was %d, expected 0\n",
				written_strlen, name[written_strlen]);
			pass = false;
			continue;
		} else if (strlen(name) != written_strlen) {
			fprintf(stderr, "return strlen was %d, but \"%s\" "
				"has strlen %d\n", written_strlen, name,
				(int)strlen(name));
			pass = false;
			continue;
		}

		for (name_index = 0; name_index < ARRAY_SIZE(names); name_index++) {
			if (strcmp(names[name_index], name) == 0) {
				if (found[name_index]) {
					fprintf(stderr,
						"Uniform name \"%s\" "
						"returned twice.\n", name);
					pass = false;
				}
				found[name_index] = true;
				break;
			}
		}
		if (name_index == ARRAY_SIZE(names)) {
			fprintf(stderr,
				"uniform \"%s\" is not a known name\n", name);
			pass = false;
			continue;
		}

		if (namelen != written_strlen + 1) {
			fprintf(stderr,
				"uniform \"%s\" had "
				"GL_UNIFORM_NAME_LENGTH %d, expected %d\n",
				name, namelen, written_strlen + 1);
			pass = false;
			continue;
		}

		/* Test for overflow by writing to a bufSize equal to
		 * strlen and checking if a null terminator or
		 * something landed past that.
		 */
		memset(name, fill_char, sizeof(name));
		glGetActiveUniformName(prog, i, written_strlen, NULL, name);
		if (name[written_strlen] != fill_char) {
			fprintf(stderr, "glGetActiveUniformName overflowed: "
				"name[%d] = 0x%02x instead of 0x%02x\n",
				written_strlen, name[written_strlen],
				fill_char);
			pass = false;
		}
	}

	if (!piglit_khr_no_error) {
		no_write = fill_char;
		glGetActiveUniformName(0xd0d0, 0, 1, NULL, &no_write);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		if (no_write != fill_char)
			pass = false;

		no_write = fill_char;
		glGetActiveUniformName(prog, 0, -1, NULL, &no_write);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		if (no_write != fill_char)
			pass = false;

		no_write = fill_char;
		glGetActiveUniformName(prog, uniforms, 1, NULL, &no_write);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		if (no_write != fill_char)
			pass = false;
	}

	glDeleteProgram(prog);

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
Exemple #17
0
ofxUboLayout ofxUboShader::getLayout(const string &blockName){
    ofxUboLayout layout;
    layout.blockName = blockName;
    
    // get block Index
    GLuint blockIndex = glGetUniformBlockIndex(getProgram(),blockName.c_str());
    if (blockIndex == GL_INVALID_INDEX) {
        ofLogError("ofxUbo") << "The block '" << blockName << "' does not exist in program:" << getProgram() <<
        " make sure you are actually using the block '" << blockName << "' inside your GLSL program, otherwise openGL will not consider your block active";
        layout.blockName = "";
        layout.size = -99;
        return layout;
    }
    
    // get the Size of the Uniform Block
    int uboSize;
    glGetActiveUniformBlockiv(getProgram(), blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
    layout.size = uboSize;
    
    // get the number of active uniforms of the Uniform Block
    int activeUnif;
    glGetActiveUniformBlockiv(getProgram(), blockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &activeUnif);
    
    // get each unifom inside the Uniform block
    unsigned int *indices = new unsigned int[activeUnif];
    glGetActiveUniformBlockiv(getProgram(), blockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (int *)indices);
    
    // loop through all active Uniforms and get each, uniform's name,type,offset,size,arrayStride,and MatrixStride
    int actualLen, index, uniType,uniSize, uniMatStride, uniArrayStride, uniOffset;
	char name[256];
    
    for (int k = 0; k < activeUnif; ++k) {
		glGetActiveUniformName(getProgram(), indices[k], 256, &actualLen, name);
        glGetActiveUniformsiv(getProgram(), 1, &indices[k], GL_UNIFORM_TYPE, &uniType);
        glGetActiveUniformsiv(getProgram(), 1, &indices[k], GL_UNIFORM_OFFSET, &uniOffset);
        
        // This function retrives array length, not the actual size;
        glGetActiveUniformsiv(getProgram(), 1, &indices[k], GL_UNIFORM_SIZE, &uniSize);
        glGetActiveUniformsiv(getProgram(), 1, &indices[k], GL_UNIFORM_ARRAY_STRIDE, &uniArrayStride);
        glGetActiveUniformsiv(getProgram(), 1, &indices[k], GL_UNIFORM_MATRIX_STRIDE, &uniMatStride);
        
        int auxSize;
        if (uniArrayStride > 0)
            auxSize = uniArrayStride * uniSize;
        
        else if (uniMatStride > 0) {
            
            switch(uniType) {
                case GL_FLOAT_MAT2:
                case GL_FLOAT_MAT2x3:
                case GL_FLOAT_MAT2x4:
                case GL_DOUBLE_MAT2:
                    auxSize = 2 * uniMatStride;
                    break;
                case GL_FLOAT_MAT3:
                case GL_FLOAT_MAT3x2:
                case GL_FLOAT_MAT3x4:
                case GL_DOUBLE_MAT3:
                    auxSize = 3 * uniMatStride;
                    break;
                case GL_FLOAT_MAT4:
                case GL_FLOAT_MAT4x2:
                case GL_FLOAT_MAT4x3:
                case GL_DOUBLE_MAT4:
                    auxSize = 4 * uniMatStride;
                    break;
            }
        }
        else
            auxSize = ofxUboSingeltons::spGLSLTypeSize[uniType];
        
        ofxUniformInfo info;
        info.name = name;
        info.type = uniType;
        info.offest = uniOffset;
        info.size = auxSize;
        info.arrayStride = uniArrayStride;
        info.matrixStride = uniMatStride;
        layout.uniformData.push_back(info);
    }
    // Sort unifoms based on offset. Some opengl drivers seem to fetch uniforms in a non sequential order.
    // The offset data is still correct but glGetActiveUniformBlockiv feeds you uniforms in a random order.
    ofSort(layout.uniformData);
    
    delete[] indices;
    return layout;
}