void s_light_t::setup(GLuint program) { const int block_sz = 10; const char *block_name = "sLight"; static const char *s_light_names[block_sz] = { "sLight_num", "sLight_position", "sLight_direction", "sLight_ambient", "sLight_diffuse", "sLight_specular", "sLight_attenuation", "sLight_cutoff", "sLight_exponent", "sLight_mat" }; static GLuint index[block_sz]; static int offset[block_sz]; static GLuint blockIndex; static int blockSize; static bool init = false; static GLuint buffer; if (!init) { init = true; blockIndex = glGetUniformBlockIndex(program, block_name); glGetActiveUniformBlockiv(program, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); glGetUniformIndices(program, block_sz, s_light_names, index); glGetActiveUniformsiv(program, block_sz, index, GL_UNIFORM_OFFSET, offset); char *ch = new char[blockSize]; memset(ch, 0, blockSize); glGenBuffersARB(1, &buffer); glBindBuffer(GL_UNIFORM_BUFFER, buffer); glBufferData(GL_UNIFORM_BUFFER, blockSize, ch, GL_STREAM_DRAW); } glBindBufferBase(GL_UNIFORM_BUFFER, 2, buffer); glUniformBlockBinding(program, blockIndex, 2); char *ptr = (char*)glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); memcpy(ptr + offset[0], &cnt, sizeof(int)); if (!cnt) { glUnmapBuffer(GL_UNIFORM_BUFFER); return; } memcpy(ptr + offset[1], position[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[2], direction[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[3], ambient[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[4], diffuse[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[5], specular[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[6], attenuation[0].v, cnt * 4 * sizeof(GLfloat)); memcpy(ptr + offset[7], &cutoff[0], cnt * sizeof(GLfloat)); memcpy(ptr + offset[8], &exponent[0], cnt * sizeof(GLfloat)); memcpy(ptr + offset[9], mat[0].m, cnt * 4 * 4 * sizeof(GLfloat)); glUnmapBuffer(GL_UNIFORM_BUFFER); }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint fs; GLuint save_index = 0xaaaaaaaa; const GLchar *one_uniform = "a"; const GLchar *uniform_names[] = {"a", "b", "c"}; bool found_index[3] = {false, false, false}; GLuint indices[3], index; int i; piglit_require_extension("GL_ARB_uniform_buffer_object"); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_shader_text); if (!fs) { printf("Failed to compile FS:\n%s", frag_shader_text); piglit_report_result(PIGLIT_FAIL); } prog = piglit_link_simple_program(0, fs); if (!prog) piglit_report_result(PIGLIT_FAIL); /* From the GL_ARB_uniform_buffer_object spec: * * "The error INVALID_VALUE is generated by GetUniformIndices, * GetActiveUniformsiv, GetActiveUniformName, GetUniformBlockIndex, * GetActiveUniformBlockiv, GetActiveUniformBlockName, and * UniformBlockBinding if <program> is not a value generated by GL. * * ... * * The error INVALID_VALUE is generated by GetUniformIndices and * GetActiveUniformsiv if <uniformCount> is less than zero. * * ... * * "If an error occurs, nothing is written to <uniformIndices>." */ index = save_index; glGetUniformIndices(prog, -1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } index = save_index; glGetUniformIndices(0xd0d0, 1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } glGetUniformIndices(prog, 3, uniform_names, indices); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); for (i = 0; i < 3; i++) { printf("%s: index %d\n", uniform_names[i], indices[i]); if (indices[i] < 0 || indices[i] > 2 || found_index[indices[i]]) { printf("Expected consecutive numbers starting from 0\n"); pass = false; } found_index[indices[i]] = true; } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint save_index = 0xaaaaaaaa; const GLchar *one_uniform = "a"; const GLchar *bad_uniform = "d"; const GLchar *uniform_names[] = {"a", "b", "c"}; bool found_index[3] = {false, false, false}; GLuint indices[3], index; int i; piglit_require_extension("GL_ARB_uniform_buffer_object"); prog = piglit_build_simple_program(NULL, frag_shader_text); /* From the GL_ARB_uniform_buffer_object spec: * * "The error INVALID_VALUE is generated by GetUniformIndices, * GetActiveUniformsiv, GetActiveUniformName, GetUniformBlockIndex, * GetActiveUniformBlockiv, GetActiveUniformBlockName, and * UniformBlockBinding if <program> is not a value generated by GL. * * ... * * The error INVALID_VALUE is generated by GetUniformIndices and * GetActiveUniformsiv if <uniformCount> is less than zero. * * ... * * "If an error occurs, nothing is written to <uniformIndices>." */ index = save_index; glGetUniformIndices(prog, -1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } index = save_index; glGetUniformIndices(0xd0d0, 1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } glGetUniformIndices(prog, 3, uniform_names, indices); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); for (i = 0; i < 3; i++) { printf("%s: index %d\n", uniform_names[i], indices[i]); if (indices[i] > 2 || found_index[indices[i]]) { printf("Expected consecutive numbers starting from 0\n"); pass = false; } found_index[indices[i]] = true; } /* "If a string in <uniformNames> is not the name of an * active uniform, the value INVALID_INDEX will be * written to the corresponding element of * <uniformIndices>." */ glGetUniformIndices(prog, 1, &bad_uniform, &index); if (!piglit_check_gl_error(0)) { pass = false; } else if (index != GL_INVALID_INDEX) { printf("Bad uniform index for %s: 0x%08x\n", bad_uniform, index); printf(" Expected 0x%08x\n", GL_INVALID_INDEX); pass = false; } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void shader_set_parameter(shader_t *s, char *nm, void *value, size_t sz) { char buf[64]; GLint current_program; glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program); glUseProgram(s->program); int location = glGetUniformLocation(s->program, nm); GLuint index; //Why is there a distinction between location/index? glGetUniformIndices(s->program, 1, (const GLchar * const*)&nm, &index); if(location < 0 || location == GL_INVALID_INDEX) // ERROR uniform does not exist { shader_set_block(s, nm, value, sz); // try with uniform block goto CLEANUP; } GLenum type; glGetActiveUniform(s->program, index, 0, NULL, NULL, &type, NULL); //void (*uniform_func)(GLint loc, GLsizei count, const GLuint *val) = 0; switch(type) { case GL_FLOAT_VEC4: glUniform4fv(location, sz/(sizeof(float) * 4), value); break; case GL_FLOAT_VEC3: glUniform3fv(location, sz/(sizeof(float) * 3), value); break; case GL_FLOAT_VEC2: glUniform2fv(location, sz/(sizeof(float) * 2), value); break; case GL_FLOAT: glUniform1fv(location, sz/sizeof(float), value); break; case GL_INT_VEC4: glUniform4iv(location, (sz/sizeof(int) * 4), value); break; case GL_INT_VEC3: glUniform3iv(location, (sz/sizeof(int) * 3), value); break; case GL_INT_VEC2: glUniform2iv(location, (sz/sizeof(int) * 2), value); break; case GL_INT: case GL_BOOL: case GL_SAMPLER_2D: case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: glUniform1iv(location, sz/sizeof(int), value); break; case GL_UNSIGNED_INT_VEC4: glUniform4uiv(location, (sz/sizeof(unsigned int) * 4), value); break; case GL_UNSIGNED_INT_VEC3: glUniform3uiv(location, (sz/sizeof(unsigned int) * 3), value); break; case GL_UNSIGNED_INT_VEC2: glUniform2uiv(location, (sz/sizeof(unsigned int) * 2), value); break; case GL_UNSIGNED_INT: glUniform1uiv(location, sz/sizeof(unsigned int), value); break; case GL_FLOAT_MAT4: glUniformMatrix4fv(location, sz/(sizeof(float) * 16), true, value); break; case GL_FLOAT_MAT3: glUniformMatrix3fv(location, sz/(sizeof(float) * 9), true, value); break; default: assert(0 && "invalid parameter type"); } CLEANUP: glUseProgram(current_program); }
static bool test_format(const struct uniform_type *type, bool row_major) { /* Using 140 to get unsigned ints. */ const char *fs_template = "#version 140\n" "layout(std140) uniform ubo {\n" " float pad;\n" " %s %s u;\n" " float size_test;\n" "};\n" "\n" "void main() {\n" " gl_FragColor = vec4(pad) + vec4(%s) + vec4(size_test);\n" "}\n"; char *fs_source; GLuint prog; const char *uniform_names[] = { "u", "size_test" }; GLuint uniform_indices[2]; GLint offsets[2]; int offset, size, expected_offset; const struct uniform_type *transposed_type; bool pass; const char *deref; if (row_major) transposed_type = get_transposed_type(type); else transposed_type = type; if (type->size == 4) deref = "u"; else if (type->size <= 16) deref = "u.x"; else deref = "u[0].x"; asprintf(&fs_source, fs_template, row_major && type->size > 16 ? "layout(row_major) " : "", type->type, deref); prog = piglit_build_simple_program(NULL, fs_source); free(fs_source); glGetUniformIndices(prog, 2, uniform_names, uniform_indices); glGetActiveUniformsiv(prog, 2, uniform_indices, GL_UNIFORM_OFFSET, offsets); glDeleteProgram(prog); offset = offsets[0]; size = offsets[1] - offsets[0]; /* "pad" at the start of the UBO is a float, so our test * uniform would start at byte 4 if not for alignment. */ expected_offset = 4; expected_offset = align(expected_offset, transposed_type->alignment); pass = (offset == expected_offset && size == transposed_type->size); printf("%-10s %10s %8d %-16d %8d %-16d%s\n", type->type, row_major ? "y" : "n", offset, expected_offset, size, transposed_type->size, pass ? "" : " FAIL"); return pass; }
int main(int argc, char **argv) { wrt = (struct warp_runtime *)malloc(sizeof(struct warp_runtime)); assert(NULL != wrt); memset(wrt, 0, sizeof(struct warp_runtime)); create_warp_runtime(wrt); glViewport(0, 0, 500, 500); /* setup shader & program */ GLchar message[512]; GLint status; GLchar *source = NULL; GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); load_shader_from_file("shaders/es3_ubo.vert", &source); glShaderSource(vertex_shader, 1, (const GLchar * const*)&source, NULL); glCompileShader(vertex_shader); glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status); if (!status) { glGetShaderInfoLog(vertex_shader, 512, NULL, message); printf("%s\n", message); } GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); free(source); load_shader_from_file("shaders/es3_ubo.frag", &source); glShaderSource(fragment_shader, 1, (const GLchar * const*)&source, NULL); glCompileShader(fragment_shader); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status); if (!status) { glGetShaderInfoLog(fragment_shader, 512, NULL, message); printf("%s\n", message); } GLuint prog = glCreateProgram(); glAttachShader(prog, vertex_shader); glAttachShader(prog, fragment_shader); glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &status); if (!status) { glGetProgramInfoLog(prog, 512, NULL, message); printf("%s\n", message); } glUseProgram(prog); /* set up resource */ GLfloat pos_buf[] = { -0.25f, 0.25f, 0.0f, 0.25f, -0.25f, 0.0f, -0.25f, -0.25f, 0.0f, 0.25f, 0.25f, 0.0f }; GLfloat color_buf[] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, }; GLushort index_buf[] = { 2, 0, 1, 3 }; GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); /* setup array buffer for position and color */ GLuint vbo_pos; glGenBuffers(1, &vbo_pos); glBindBuffer(GL_ARRAY_BUFFER, vbo_pos); glBufferData(GL_ARRAY_BUFFER, sizeof(pos_buf), pos_buf, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0); GLuint vbo_color; glGenBuffers(1, &vbo_color); glBindBuffer(GL_ARRAY_BUFFER, vbo_color); glBufferData(GL_ARRAY_BUFFER, sizeof(color_buf), color_buf, GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid *)0); /* setup index buffer for index */ GLuint vbo_index; glGenBuffers(1, &vbo_index); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_index); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_buf), index_buf, GL_STATIC_DRAW); /* updating uniform block */ glm::mat4 model_mat = glm::mat4(1.0f); glm::mat4 view_mat = glm::lookAt( glm::vec3(-2, 1, 2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0) ); glm::mat4 proj_mat = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); GLuint ubo_blk_idx = glGetUniformBlockIndex(prog, "MVP"); GLint ubo_sz; glGetActiveUniformBlockiv(prog, ubo_blk_idx, GL_UNIFORM_BLOCK_DATA_SIZE, &ubo_sz); const char *names[3] = {"uModel", "uView", "uProj"}; GLuint indices[3]; GLint size[3]; GLint offset[3]; GLint type[3]; glGetUniformIndices(prog, 3, names, indices); glGetActiveUniformsiv(prog, 3, indices, GL_UNIFORM_OFFSET, offset); glGetActiveUniformsiv(prog, 3, indices, GL_UNIFORM_SIZE, size); glGetActiveUniformsiv(prog, 3, indices, GL_UNIFORM_TYPE, type); /* mat4 here is 4x4=16 GLfloat */ GLubyte *buffer = (GLubyte *)malloc(ubo_sz); memcpy(buffer + offset[0], &model_mat[0][0], size[0] * sizeof(GLfloat) * 16); memcpy(buffer + offset[1], &view_mat[0][0], size[1] * sizeof(GLfloat) * 16); memcpy(buffer + offset[2], &proj_mat[0][0], size[2] * sizeof(GLfloat) * 16); GLuint ubo; glGenBuffers(1, &ubo); glBindBuffer(GL_UNIFORM_BUFFER, ubo); glBufferData(GL_UNIFORM_BUFFER, ubo_sz, buffer, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, ubo_blk_idx, ubo); /* game loop */ while (1) { XNextEvent(wrt->x11_display, &(wrt->event)); switch(wrt->event.type) { case Expose: /* do the render */ glClearColor(0.3f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(vao); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0); glBindVertexArray(0); eglSwapBuffers(wrt->egl_display, wrt->egl_surface); break; case ButtonPress: case KeyPress: goto finish; default: break; } } finish: glDeleteBuffers(1, &vbo_pos); glDeleteBuffers(1, &vbo_color); glDeleteBuffers(1, &vbo_index); glDeleteBuffers(1, &ubo); glDeleteVertexArrays(1, &vao); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(prog); destroy_warp_runtime(wrt); return 0; }
void LightSystem::renderLight() { // creating temporary data that will be send to light buffer glGenBuffers(1, &LightBuffer); glBindBuffer(GL_UNIFORM_BUFFER, LightBuffer); int lc = lightList.size(); const GLchar *uniformNames[1] = { "Lights.cont" }; GLuint uniformIndices; glGetUniformIndices(*shader, 1, uniformNames, &uniformIndices); GLint uniformOffsets[1]; glGetActiveUniformsiv(*shader, 1, &uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets); GLuint uniformIndex = glGetUniformBlockIndex(*shader, "Lights"); GLsizei uniformBlockSize(0); glGetActiveUniformBlockiv(*shader, uniformIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize); GLint maxSize; glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxSize); GLint bufferAlignment; glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &bufferAlignment); //std::cout << "Uniform Block size: " << uniformBlockSize << std::endl; //std::cout << "Uniform Block max size: " << maxSize << std::endl; //std::cout << "Uniform Buffer alignment: " << bufferAlignment << std::endl; GLuint indices[lc * 2]; glGetUniformIndices(*shader, lc * 2, names, indices); lightUniformOffsets.clear(); lightUniformOffsets.resize(lc * 2); glGetActiveUniformsiv(*shader, lightUniformOffsets.size(), indices, GL_UNIFORM_OFFSET, &lightUniformOffsets[0]); GLint *offsets = &lightUniformOffsets[0]; unsigned int bSize(uniformBlockSize); std::vector<unsigned char> buffer(bSize); int offset; for (unsigned int n = 0; n < lightList.size(); ++n) { offset = offsets[0 + n * 2]; *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].position.x; offset += sizeof(GLfloat); *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].position.y; offset += sizeof(GLfloat); *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].position.z; offset += sizeof(GLfloat); offset = offsets[1 + n * 2]; *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].color.x; offset += sizeof(GLfloat); *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].color.y; offset += sizeof(GLfloat); *(reinterpret_cast<GLfloat*>(&buffer[0] + offset)) = lightList[n].color.z; offset += sizeof(GLfloat); } glUniform1i(LightCount, lc); glBufferData(GL_UNIFORM_BUFFER, bSize, &buffer[0], GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, LightBuffer); glUniformBlockBinding(*shader, uniformIndex, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0); }
void SharedProjectionAndViewing::findOffsets(GLuint shaderProgram) { const int numberOfNames = 4; GLuint uniformIndices[numberOfNames] = { 0 }; GLint uniformOffsets[numberOfNames] = { 0 }; const GLchar * charStringNames[] = { "modelMatrix", "viewingMatrix", "projectionMatrix", "normalModelMatrix" }; glGetUniformIndices(shaderProgram, numberOfNames, (const GLchar **)charStringNames, uniformIndices); if (uniformIndices[0] != GL_INVALID_INDEX && uniformIndices[1] != GL_INVALID_INDEX) { for (int i = 0; i < numberOfNames; i++) { checkLocationFound(charStringNames[i], uniformIndices[i]); } //Get the offsets of the uniforms. The offsets in the buffer will be the same. glGetActiveUniformsiv(shaderProgram, numberOfNames, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets); for (int i = 0; i < numberOfNames; i++) { cout << '\t' << charStringNames[i] << " offset is " << uniformOffsets[i] << endl; } // Save locations modelLocation = uniformOffsets[0]; viewLocation = uniformOffsets[1]; projectionLocation = uniformOffsets[2]; normalModelLocation = uniformOffsets[3]; } else { cout << " Did not find names in " << transformBlockName.c_str() << endl; } GLuint uniformEyeIndice = 0; GLint uniformEyeOffset = 0; const GLchar * eyeName[] = { "worldEyePosition" }; glGetUniformIndices(shaderProgram, 1, eyeName, &uniformEyeIndice); if (uniformEyeIndice != GL_INVALID_INDEX) { //Get the offsets of the uniforms. The offsets in the buffer will be the same. glGetActiveUniformsiv(shaderProgram, 1, &uniformEyeIndice, GL_UNIFORM_OFFSET, &uniformEyeOffset); cout << '\t' << eyeName[0] << " offset is " << uniformEyeOffset << endl; // Save location eyePositionLocation = uniformEyeOffset; } else { cout << " Did not find names in " << eyeBlockName.c_str() << endl; } checkOpenGLErrors("findOffets"); } // findOffsets
void TopazSample::renderStandartWeightedBlendedOIT() { glEnable(GL_DEPTH_TEST); glDisable(GL_POLYGON_OFFSET_FILL); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_SCENE, ubos.sceneUbo); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_IDENTITY, ubos.identityUbo); glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); drawModel(GL_TRIANGLES, *shaderPrograms["draw"], *models.at(0)); glBindFramebuffer(GL_FRAMEBUFFER, 0); /* first pass oit */ glDisable(GL_DEPTH_TEST); // TODO : change on transparent list of models for (auto model = models.begin() + 1; model != models.end(); model++) { /* geometry pass */ { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); GLfloat clearColorZero[4] = { 0.0f }; GLfloat clearColorOne[4] = { 1.0f }; glClearBufferfv(GL_COLOR, 0, clearColorZero); glClearBufferfv(GL_COLOR, 1, clearColorOne); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData); objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData); drawModel(GL_TRIANGLES, *shaderPrograms["weightBlended"], **model); glDisable(GL_BLEND); CHECK_GL_ERROR(); } /* composition pass */ { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OIT, ubos.weightBlendedUbo, 0, sizeof(WeightBlendedData)); // check uniform buffer offset { const char* uniformNames[] = { "weightBlendedData.background", "weightBlendedData.colorTex0", "weightBlendedData.colorTex1" }; std::unique_ptr<GLint> parameters(new GLint[3]); std::unique_ptr<GLuint> uniformIndices(new GLuint[3]); glGetUniformIndices(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformNames, uniformIndices.get()); glGetActiveUniformsiv(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformIndices.get(), GL_UNIFORM_OFFSET, parameters.get()); GLint* offset = parameters.get(); } { shaderPrograms["weightBlendedFinal"]->enable(); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnableVertexAttribArray(VERTEX_POS); glBindVertexBuffer(0, fullScreenRectangle.vboFullScreen, 0, sizeof(nv::vec3f)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); shaderPrograms["weightBlendedFinal"]->disable(); } CHECK_GL_ERROR(); } } }
static bool consistency_check(GLuint prog, GLenum programInterface, const char *name, GLint index) { bool subroutine = false; const GLchar *names[] = { name }; GLuint old_idx = 0xdeadcafe; GLenum shader; /* Validate result against old API. */ switch (programInterface) { case GL_UNIFORM: glGetUniformIndices(prog, 1, names, &old_idx); piglit_check_gl_error(GL_NO_ERROR); break; case GL_UNIFORM_BLOCK: old_idx = glGetUniformBlockIndex(prog, name); piglit_check_gl_error(GL_NO_ERROR); break; case GL_VERTEX_SUBROUTINE: shader = GL_VERTEX_SHADER; subroutine = true; break; case GL_TESS_CONTROL_SUBROUTINE: shader = GL_TESS_CONTROL_SHADER; subroutine = true; break; case GL_TESS_EVALUATION_SUBROUTINE: shader = GL_TESS_EVALUATION_SHADER; subroutine = true; break; case GL_GEOMETRY_SUBROUTINE: shader = GL_GEOMETRY_SHADER; subroutine = true; break; case GL_FRAGMENT_SUBROUTINE: shader = GL_FRAGMENT_SHADER; subroutine = true; break; case GL_COMPUTE_SUBROUTINE: shader = GL_COMPUTE_SHADER; subroutine = true; break; default: /* There are no old APIs for this program interface */ return true; } if (subroutine) { old_idx = glGetSubroutineIndex(prog, shader, name); piglit_check_gl_error(GL_NO_ERROR); } if (index != old_idx) { printf("Index inconsistent with the old API: %i vs %i\n", index, old_idx); return false; } else return true; }
bool UniformBlock::Create(GLuint program, const char* blockName, const char** uniformNames, const int* uniformIndices, int uniformCount) { free(_bufferData); _bufferData = NULL; if (glIsBuffer(_buffer)) { glDeleteBuffers(1, &_buffer); } _buffer = 0; _indexRemap.resize(uniformCount, -1); _sizes.resize(uniformCount, -1); _offsets.resize(uniformCount, -1); _types.resize(uniformCount, -1); glBindBuffer(GL_UNIFORM_BUFFER, 0); _blockIndex = glGetUniformBlockIndex(program, blockName); glGetActiveUniformBlockiv(program, _blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &_blockSize); // Get the indices to check which ones are valid. This is reqired to assure that // writing happens at the correct offsets. std::vector<GLuint> indices; indices.resize(uniformCount, 0); glGetUniformIndices(program, uniformCount, uniformNames, indices.data()); vector<GLuint> actualIndices; actualIndices.reserve(uniformCount); // Attention: actualIndices.size() <= uniformCount! int actualIndexPos = 0; for (int k = 0; k < uniformCount; ++k) { if (indices[k] != GL_INVALID_INDEX) { actualIndices.push_back(indices[k]); _indexRemap[uniformIndices[k]] = actualIndexPos++; } else { LOGE("UniformBlock::Create: The uniform '%s' doesn't exist in uniform block '%s'.", uniformNames[k], blockName); } } glGetActiveUniformsiv(program, actualIndices.size(), actualIndices.data(), GL_UNIFORM_OFFSET, _offsets.data()); glGetActiveUniformsiv(program, actualIndices.size(), actualIndices.data(), GL_UNIFORM_SIZE, _sizes.data()); glGetActiveUniformsiv(program, actualIndices.size(), actualIndices.data(), GL_UNIFORM_TYPE, _types.data()); // Allocate an initialize client memory. _bufferData = static_cast<char*>(malloc(_blockSize)); if (_bufferData == NULL) { return false; } memset(_bufferData, 0, _blockSize); glGenBuffers(1, &_buffer); return (GetGLErrorVerbose() == GL_NO_ERROR); }
UniformBufferMetaInfo::UniformBufferMetaInfo( GLint numMaxArrayElements, String bufferName, String arrayName, std::vector<String> memberStrings, Shader* queryShader) : mNumArrayElements(numMaxArrayElements), //mArrayName(arrayName), mMemberStrings(memberStrings), mRequiredBufferSize(0), mNumMemberElements(memberStrings.size() == 0 ? 1 : memberStrings.size() ), mBufferOffsets(0) { LOG<<DEBUG_LOG_LEVEL<<bufferName<<"\n"; GLuint shaderGLProgramHandle = queryShader->getGLProgramHandle(); GLuint uniBlockIndex = GUARD( glGetUniformBlockIndex(shaderGLProgramHandle, bufferName.c_str()) ); //query needed buffer size GUARD( glGetActiveUniformBlockiv( shaderGLProgramHandle, uniBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, & mRequiredBufferSize ) ); //-------------------------------------------------------------------------------- mBufferOffsets = new GLint*[mNumArrayElements]; // const String memberStrings[] = // { // "position","diffuseColor","specularColor","direction", // "innerSpotCutOff_Radians","outerSpotCutOff_Radians","spotExponent","shadowMapLayer" // }; const char** indexQuery_C_StringArray= new const char*[mNumMemberElements]; String* indexQueryStringArray= new String[mNumMemberElements]; GLuint* currentUniformIndices= new GLuint[mNumMemberElements]; for(int arrayElementRunner=0; arrayElementRunner< mNumArrayElements; arrayElementRunner++) { String baseString = arrayName + String("[") + HelperFunctions::toString(arrayElementRunner) + String("]") ; mBufferOffsets[arrayElementRunner]= new GLint[mNumMemberElements]; if(memberStrings.size() != 0) { //we have a structure as array elements; construct the GL referencation strings: for(int memberRunner=0; memberRunner< mNumMemberElements; memberRunner++) { indexQueryStringArray[memberRunner]= String(baseString+ String(".") + memberStrings[memberRunner]); indexQuery_C_StringArray[memberRunner]= indexQueryStringArray[memberRunner].c_str(); } } else { //the array element constist of a single built-in type, i.e. the GL referencation strings //are a single string, beeing the base string: indexQuery_C_StringArray[0]= baseString.c_str(); } //first, get indices of current lightsource members: GUARD( glGetUniformIndices( shaderGLProgramHandle, mNumMemberElements, indexQuery_C_StringArray, currentUniformIndices ) ); //second, get offset in buffer for those members, indentified by the queried indices: GUARD( glGetActiveUniformsiv( shaderGLProgramHandle, mNumMemberElements, currentUniformIndices, GL_UNIFORM_OFFSET, mBufferOffsets[arrayElementRunner] ) ); // for(int memberRunner=0; memberRunner< mNumMemberElements; memberRunner++) // { // LOG<<DEBUG_LOG_LEVEL << String(indexQuery_C_StringArray[memberRunner])<<" ;\n"; // LOG<<DEBUG_LOG_LEVEL <<"uniform index: "<< currentUniformIndices[memberRunner] <<" ;\n"; // LOG<<DEBUG_LOG_LEVEL <<"uniform offset: "<< mBufferOffsets[arrayElementRunner][memberRunner] <<" ;\n"; // assert( "member should be active in shader, otherwise uniform buffer filling would turn out even more complicated :@" // && ( currentUniformIndices[memberRunner] != GL_INVALID_INDEX) ); // } } //endfor delete[] indexQuery_C_StringArray; delete[] indexQueryStringArray; delete[] currentUniformIndices; }