/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */ static jstring android_glGetTransformFeedbackVarying2 (JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) { jarray _sizeArray = (jarray) 0; jint _sizeBufferOffset = (jint) 0; jarray _typeArray = (jarray) 0; jint _typeBufferOffset = (jint) 0; jint _lengthRemaining; GLsizei *length = (GLsizei *) 0; jint _sizeRemaining; GLint *size = (GLint *) 0; jint _typeRemaining; GLenum *type = (GLenum *) 0; jstring result = 0; GLint len = 0; glGetProgramiv((GLuint)program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len); if (!len) { return _env->NewStringUTF(""); } char* buf = (char*) malloc(len); if (buf == NULL) { jniThrowException(_env, "java/lang/IllegalArgumentException", "out of memory"); return NULL; } size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset); type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset); if (size == NULL) { char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0); size = (GLint *) (_sizeBase + _sizeBufferOffset); } if (type == NULL) { char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0); type = (GLenum *) (_typeBase + _typeBufferOffset); } glGetTransformFeedbackVarying( (GLuint)program, (GLuint)index, (GLsizei)len, NULL, (GLint *)size, (GLenum *)type, (char *)buf ); if (_typeArray) { releasePointer(_env, _typeArray, type, JNI_TRUE); } if (_sizeArray) { releasePointer(_env, _sizeArray, size, JNI_TRUE); } result = _env->NewStringUTF(buf); if (buf) { free(buf); } return result; }
static void CopyShaderState_TransformFeedback(GLuint newProgID, GLuint oldProgID) { #ifdef GL_ARB_transform_feedback3 //FIXME find out what extensions are really needed if (!GLEW_ARB_transform_feedback3) return; GLint bufferMode, numVaryings, maxNameLength; glGetProgramiv(oldProgID, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &bufferMode); glGetProgramiv(oldProgID, GL_TRANSFORM_FEEDBACK_VARYINGS, &numVaryings); glGetProgramiv(oldProgID, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &maxNameLength); if(!numVaryings) return; std::vector<std::string> varyings(numVaryings); std::vector<GLchar*> varyingsPtr(numVaryings); std::string name(maxNameLength, 0); for (int i = 0; i < numVaryings; ++i) { GLsizei nameLength = 0; GLsizei size = 0; GLenum type = 0; glGetTransformFeedbackVarying(oldProgID, i, maxNameLength, &nameLength, &size, &type, &name[0]); name[maxNameLength - 1] = 0; if (nameLength == 0) continue; varyings[i].assign(name.data(), nameLength + 1); varyingsPtr[i] = &varyings[i][0]; } glTransformFeedbackVaryings(newProgID, numVaryings, (const GLchar**)&varyingsPtr[0], bufferMode); #endif }
void run_test(struct get_tests *test) { GLsizei size; GLenum type; GLuint vs; GLuint prog; char vstest[1024]; snprintf(vstest, 1024, vstext, test->glsltype, test->glsltype); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstest); prog = glCreateProgram(); glAttachShader(prog, vs); glBindAttribLocation(prog, 0, "vertex"); glTransformFeedbackVaryings(prog, ARRAY_SIZE(varyings), varyings, GL_INTERLEAVED_ATTRIBS_EXT); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } glGetTransformFeedbackVarying(prog, 0, 0, NULL, &size, &type, NULL); if (size != test->size) { printf("For %s, size %d vs %d\n", test->glsltype, size, test->size); size_and_type_ok = false; } if (type != test->type) { printf("For %s, size %d vs %d\n", test->glsltype, type, test->type); size_and_type_ok = false; } glDeleteProgram(prog); }
void GLSLProgram::setTransformFeedbackVaryings(const std::vector<String>& nameStrings) { // Get program object ID. GLuint programId; if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { //TODO include tessellation stages GLSLShader* glslGpuProgram = getGeometryShader(); if (!glslGpuProgram) glslGpuProgram = getVertexShader(); programId = glslGpuProgram->getGLProgramHandle(); // force re-link GpuProgramManager::getSingleton().removeMicrocodeFromCache(glslGpuProgram->_getHash()); glslGpuProgram->setLinked(false); } else { programId = getGLProgramHandle(); // force re-link GpuProgramManager::getSingleton().removeMicrocodeFromCache(getCombinedHash()); } mLinked = false; // Convert to const char * for GL std::vector<const char*> names; for (uint e = 0; e < nameStrings.size(); e++) { names.push_back(nameStrings[e].c_str()); } // TODO replace glTransformFeedbackVaryings with in-shader specification (GL 4.4) OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(programId, nameStrings.size(), &names[0], GL_INTERLEAVED_ATTRIBS)); #if OGRE_DEBUG_MODE activate(); // Check if varyings were successfully set. GLchar Name[64]; GLsizei Length(0); GLsizei Size(0); GLenum Type(0); // bool Validated = false; for (size_t i = 0; i < nameStrings.size(); i++) { OGRE_CHECK_GL_ERROR( glGetTransformFeedbackVarying(programId, i, 64, &Length, &Size, &Type, Name)); LogManager::getSingleton().stream() << "Varying " << i << ": " << Name << " " << Length << " " << Size << " " << Type; // Validated = (Size == 1) && (Type == GL_FLOAT_VEC3); // std::cout << Validated << " " << GL_FLOAT_VEC3 << std::endl; } #endif }
void piglit_init(int argc, char **argv) { GLuint vs; int i; /* Parse params. */ if (argc != 2) print_usage_and_exit(argv[0]); test_to_run = find_matching_test(argv[0], argv[1]); /* Set up test */ piglit_require_GLSL_version(test_to_run->version); piglit_require_transform_feedback(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, test_to_run->vs); prog = glCreateProgram(); glAttachShader(prog, vs); glBindAttribLocation(prog, 0, "vertex_pos"); glBindAttribLocation(prog, 1, "vertex_num"); glTransformFeedbackVaryings(prog, test_to_run->num_varyings, (const char **) test_to_run->varyings, GL_INTERLEAVED_ATTRIBS_EXT); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } /* Test that GetTransformFeedbackVarying reports the correct * size and type for all of the varyings. */ for (i = 0; i < test_to_run->num_varyings; ++i) { GLsizei size; GLenum type; glGetTransformFeedbackVarying(prog, i, 0, NULL, &size, &type, NULL); if (size != test_to_run->expected_size) { printf("For varying %i, expected size %i, got %i\n", i, test_to_run->expected_size, size); size_and_type_ok = GL_FALSE; } if (type != test_to_run->expected_type) { printf("For varying %i, expected type %i, got %i\n", i, test_to_run->expected_type, type); size_and_type_ok = GL_FALSE; } } glGenBuffers(1, &xfb_buf); glGenQueries(1, &query); glEnable(GL_VERTEX_PROGRAM_TWO_SIDE); }
/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */ static void android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) { jarray _lengthArray = (jarray) 0; jint _lengthBufferOffset = (jint) 0; jarray _sizeArray = (jarray) 0; jint _sizeBufferOffset = (jint) 0; jarray _typeArray = (jarray) 0; jint _typeBufferOffset = (jint) 0; jint _lengthRemaining; GLsizei *length = (GLsizei *) 0; jint _sizeRemaining; GLint *size = (GLint *) 0; jint _typeRemaining; GLenum *type = (GLenum *) 0; length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset); size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset); type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset); if (length == NULL) { char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0); length = (GLsizei *) (_lengthBase + _lengthBufferOffset); } if (size == NULL) { char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0); size = (GLint *) (_sizeBase + _sizeBufferOffset); } if (type == NULL) { char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0); type = (GLenum *) (_typeBase + _typeBufferOffset); } glGetTransformFeedbackVarying( (GLuint)program, (GLuint)index, (GLsizei)bufsize, (GLsizei *)length, (GLint *)size, (GLenum *)type, (char *)name ); if (_typeArray) { releasePointer(_env, _typeArray, type, JNI_TRUE); } if (_sizeArray) { releasePointer(_env, _sizeArray, size, JNI_TRUE); } if (_lengthArray) { releasePointer(_env, _lengthArray, length, JNI_TRUE); } }
void Shader::enableTransformFeedback(int count, const char** varyings, GLenum buffertype) const { glTransformFeedbackVaryings(program, count, varyings, buffertype); glLinkProgram(program);//new linking because some unused varyings could be in use now int length=0; GLsizei size=0; GLenum type=GL_V3F; char var[64]; for(int i=0;i!=count;i++) { glGetTransformFeedbackVarying(program, i, 64, &length, &size, &type, var); if(strcmp(var,varyings[i])) QLOG_ERROR_NOCONTEXT() << "Error, the TransformFeedback varying "<< varyings[i] <<" is erroneous."; } }
/** * Verify that glGetTransformFeedbackVarying() returns the proper * information for all "good" varying names. * * The program should already be linked and stored in the global \c * prog. */ static enum piglit_result test_gets() { unsigned i; unsigned num_good_varyings = count_strings(test->good_varyings); const char **varyings; bool pass = true; if (use_interface_blocks) varyings = prepend_varyings("Blk.", test->good_varyings); else varyings = test->good_varyings; for (i = 0; i < num_good_varyings; i++) { const char *exp_name = varyings[i]; GLsizei exp_length = strlen(exp_name); GLsizei exp_size = test->expected_sizes[i]; GLenum exp_type = test->expected_types[i]; GLsizei length; GLsizei size; GLenum type; char name[100]; glGetTransformFeedbackVarying(prog, i, sizeof(name), &length, &size, &type, name); if (length != exp_length || size != exp_size || type != exp_type || strcmp(name, exp_name) != 0) { pass = false; printf("glGetTransformFeedbackVarying() returned " "unexpected data for varying %u:\n", i); printf(" length: expected %u, got %u\n", exp_length, length); printf(" size: expected %u, got %u\n", exp_size, size); printf(" type: expected %u (%s), got %u (%s)\n", exp_type, piglit_get_gl_enum_name(exp_type), type, piglit_get_gl_enum_name(type)); printf(" name: expected %s, got %s\n", exp_name, name); } } if (use_interface_blocks) free_varyings(varyings); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
static inline void dumpTransformFeedback(StateWriter &writer, GLint program) { GLint transform_feedback_varyings = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings); if (!transform_feedback_varyings) { return; } GLint max_name_length = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length); std::vector<GLchar> name(max_name_length); GLint buffer_mode = GL_INTERLEAVED_ATTRIBS; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &buffer_mode); std::vector<TransformFeedbackAttrib> attribs(transform_feedback_varyings); // Calculate the offsets and strides of each attribute according to // the value of GL_TRANSFORM_FEEDBACK_BUFFER_MODE GLsizei cum_attrib_offset = 0; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; GLsizei length = 0; GLsizei size = 0; GLenum type = GL_NONE; glGetTransformFeedbackVarying(program, slot, max_name_length, &length, &size, &type, &name[0]); attrib.name = &name[0]; const AttribDesc & desc = attrib.desc = AttribDesc(type, size); if (!desc) { return; } attrib.size = desc.arrayStride; switch (buffer_mode) { case GL_INTERLEAVED_ATTRIBS: attrib.offset = cum_attrib_offset; break; case GL_SEPARATE_ATTRIBS: attrib.offset = 0; attrib.stride = desc.arrayStride; break; default: assert(0); attrib.offset = 0; attrib.stride = 0; } cum_attrib_offset += desc.arrayStride; } if (buffer_mode == GL_INTERLEAVED_ATTRIBS) { for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.stride = cum_attrib_offset; } } GLint previous_tbo = 0; glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &previous_tbo); // Map the buffers and calculate how many vertices can they hold // XXX: We currently limit to 1024, or things can get significantly slow. unsigned numVertices = 16*1024; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.map = NULL; if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) { GLint tbo = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo); if (!tbo) { numVertices = 0; continue; } GLint start = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, slot, &start); GLint size = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, slot, &size); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo); if (size == 0) { glGetBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &size); assert(size >= start); size -= start; } unsigned numAttribVertices = calcNumElements(size, attrib.offset, attrib.size, attrib.stride); numVertices = std::min(numVertices, numAttribVertices); attrib.map = (const GLbyte *)attrib.mapping.map(GL_TRANSFORM_FEEDBACK_BUFFER, tbo) + start; } else { attrib.map = attribs[0].map; } } glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, previous_tbo); // Actually dump the vertices writer.beginMember("GL_TRANSFORM_FEEDBACK"); writer.beginArray(); for (unsigned vertex = 0; vertex < numVertices; ++vertex) { writer.beginObject(); for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; if (!attrib.map) { continue; } const AttribDesc & desc = attrib.desc; assert(desc); const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset; dumpAttribArray(writer, attrib.name, desc, vertex_data); } writer.endObject(); } writer.endArray(); writer.endMember(); }
/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */ static jstring android_glGetTransformFeedbackVarying1 (JNIEnv *_env, jobject _this, jint program, jint index, jintArray size_ref, jint sizeOffset, jintArray type_ref, jint typeOffset) { jint _exception = 0; const char * _exceptionType; const char * _exceptionMessage; GLint *size_base = (GLint *) 0; jint _sizeRemaining; GLint *size = (GLint *) 0; GLenum *type_base = (GLenum *) 0; jint _typeRemaining; GLenum *type = (GLenum *) 0; jstring result = 0; GLint len = 0; glGetProgramiv((GLuint)program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len); if (!len) { return _env->NewStringUTF(""); } char* buf = (char*) malloc(len); if (buf == NULL) { jniThrowException(_env, "java/lang/IllegalArgumentException", "out of memory"); return NULL; } if (!size_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "size == null"; goto exit; } if (sizeOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "sizeOffset < 0"; goto exit; } _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset; size_base = (GLint *) _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0); size = size_base + sizeOffset; if (!type_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "type == null"; goto exit; } if (typeOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "typeOffset < 0"; goto exit; } _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset; type_base = (GLenum *) _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0); type = type_base + typeOffset; glGetTransformFeedbackVarying( (GLuint)program, (GLuint)index, (GLsizei)len, NULL, (GLint *)size, (GLenum *)type, (char *)buf ); exit: if (type_base) { _env->ReleasePrimitiveArrayCritical(type_ref, type_base, _exception ? JNI_ABORT: 0); } if (size_base) { _env->ReleasePrimitiveArrayCritical(size_ref, size_base, _exception ? JNI_ABORT: 0); } if (_exception != 1) { result = _env->NewStringUTF(buf); } if (buf) { free(buf); } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } if (result == 0) { result = _env->NewStringUTF(""); } return result; }
/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */ static void android_glGetTransformFeedbackVarying__III_3II_3II_3II_3BI (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jintArray length_ref, jint lengthOffset, jintArray size_ref, jint sizeOffset, jintArray type_ref, jint typeOffset, jbyteArray name_ref, jint nameOffset) { jint _exception = 0; const char * _exceptionType; const char * _exceptionMessage; GLsizei *length_base = (GLsizei *) 0; jint _lengthRemaining; GLsizei *length = (GLsizei *) 0; GLint *size_base = (GLint *) 0; jint _sizeRemaining; GLint *size = (GLint *) 0; GLenum *type_base = (GLenum *) 0; jint _typeRemaining; GLenum *type = (GLenum *) 0; char *name_base = (char *) 0; jint _nameRemaining; char *name = (char *) 0; if (!length_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "length == null"; goto exit; } if (lengthOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "lengthOffset < 0"; goto exit; } _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset; length_base = (GLsizei *) _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0); length = length_base + lengthOffset; if (!size_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "size == null"; goto exit; } if (sizeOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "sizeOffset < 0"; goto exit; } _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset; size_base = (GLint *) _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0); size = size_base + sizeOffset; if (!type_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "type == null"; goto exit; } if (typeOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "typeOffset < 0"; goto exit; } _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset; type_base = (GLenum *) _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0); type = type_base + typeOffset; if (!name_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "name == null"; goto exit; } if (nameOffset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "nameOffset < 0"; goto exit; } _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset; name_base = (char *) _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0); name = name_base + nameOffset; glGetTransformFeedbackVarying( (GLuint)program, (GLuint)index, (GLsizei)bufsize, (GLsizei *)length, (GLint *)size, (GLenum *)type, (char *)name ); exit: if (name_base) { _env->ReleasePrimitiveArrayCritical(name_ref, name_base, _exception ? JNI_ABORT: 0); } if (type_base) { _env->ReleasePrimitiveArrayCritical(type_ref, type_base, _exception ? JNI_ABORT: 0); } if (size_base) { _env->ReleasePrimitiveArrayCritical(size_ref, size_base, _exception ? JNI_ABORT: 0); } if (length_base) { _env->ReleasePrimitiveArrayCritical(length_ref, length_base, _exception ? JNI_ABORT: 0); } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } }
void GL3PlusRenderToVertexBuffer::bindVerticesOutput(Pass* pass) { VertexDeclaration* declaration = mVertexData->vertexDeclaration; size_t elemCount = declaration->getElementCount(); if (elemCount == 0) return; // Get program object ID. GLuint programId = 0; if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLSeparableProgram* separableProgram = GLSLSeparableProgramManager::getSingleton().getCurrentSeparableProgram(); GLSLShader* glslGpuProgram = 0; if ((glslGpuProgram = separableProgram->getGeometryShader())) programId = glslGpuProgram->getGLProgramHandle(); //TODO include tessellation stages else // vertex program programId = separableProgram->getVertexShader()->getGLProgramHandle(); } else { GLSLMonolithicProgram* monolithicProgram = GLSLMonolithicProgramManager::getSingleton().getActiveMonolithicProgram(); programId = monolithicProgram->getGLProgramHandle(); } // Store the output in a buffer. The buffer has the same // structure as the shader output vertex data. // Note: 64 is the minimum number of interleaved // attributes allowed by GL_EXT_transform_feedback so we // are using it. Otherwise we could query during // rendersystem initialisation and use a dynamic sized // array. But that would require C99. size_t sourceBufferIndex = mTargetBufferIndex == 0 ? 1 : 0; // Bind and fill vertex arrays + buffers. reallocateBuffer(sourceBufferIndex); reallocateBuffer(mTargetBufferIndex); // GL3PlusHardwareVertexBuffer* sourceVertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[mSourceBufferIndex].getPointer()); // GL3PlusHardwareVertexBuffer* targetVertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[mTargetBufferIndex].getPointer()); //TODO GL4+ glBindTransformFeedback // Dynamically determine shader output variable names. std::vector<String> nameStrings; std::vector<const GLchar*> names; for (uint e = 0; e < elemCount; e++) { const VertexElement* element = declaration->getElement(e); String name = getSemanticVaryingName(element->getSemantic(), element->getIndex()); nameStrings.push_back(name); } // Convert to const char * for GL for (uint e = 0; e < elemCount; e++) { names.push_back(nameStrings[e].c_str()); } //TODO replace glTransformFeedbackVaryings with in-shader specification (GL 4.4) OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(programId, elemCount, &names[0], GL_INTERLEAVED_ATTRIBS)); if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLSeparableProgram* separableProgram = GLSLSeparableProgramManager::getSingleton().getCurrentSeparableProgram(); separableProgram->activate(); } else { OGRE_CHECK_GL_ERROR(glLinkProgram(programId)); } #if OGRE_DEBUG_MODE // Check if program linking was successful. GLint didLink = 0; OGRE_CHECK_GL_ERROR(glGetProgramiv(programId, GL_LINK_STATUS, &didLink)); logObjectInfo(String("RVB GLSL link result : "), programId); if (glIsProgram(programId)) { glValidateProgram(programId); } logObjectInfo(String("RVB GLSL validation result : "), programId); // Check if varyings were successfully set. GLchar Name[64]; GLsizei Length(0); GLsizei Size(0); GLenum Type(0); // bool Validated = false; for (size_t i = 0; i < elemCount; i++) { OGRE_CHECK_GL_ERROR(glGetTransformFeedbackVarying( programId, i, 64, &Length, &Size, &Type, Name )); std::cout << "Varying " << i << ": " << Name <<" "<< Length <<" "<< Size <<" "<< Type << std::endl; // Validated = (Size == 1) && (Type == GL_FLOAT_VEC3); // std::cout << Validated << " " << GL_FLOAT_VEC3 << std::endl; } #endif }
bool initProgram() { bool Validated = true; std::array<GLuint, shader::MAX> ShaderName; compiler Compiler; ShaderName[shader::VERT_TRANSFORM] = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERT_SHADER_SOURCE_TRANSFORM, "--version 150 --profile core"); ShaderName[shader::VERT_FEEDBACK] = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERT_SHADER_SOURCE_FEEDBACK, "--version 150 --profile core"); ShaderName[shader::FRAG_FEEDBACK] = Compiler.create(GL_FRAGMENT_SHADER, getDataDirectory() + FRAG_SHADER_SOURCE_FEEDBACK, "--version 150 --profile core"); Validated = Validated && Compiler.check(); // Create program if(Validated) { ProgramName[program::TRANSFORM] = glCreateProgram(); glAttachShader(ProgramName[program::TRANSFORM], ShaderName[shader::VERT_TRANSFORM]); glBindAttribLocation(ProgramName[program::TRANSFORM], semantic::attr::POSITION, "Position"); // These two approaches behave the same way #if 1 GLchar const * Strings[] = {"gl_Position", "block.Color"}; glTransformFeedbackVaryings(ProgramName[program::TRANSFORM], 2, Strings, GL_SEPARATE_ATTRIBS); #else // OpenGL 4.0 GLchar const * Strings[] = {"gl_Position", "gl_NextBuffer", "VertColor"}; glTransformFeedbackVaryings(ProgramName[program::TRANSFORM], 3, Strings, GL_INTERLEAVED_ATTRIBS); #endif glLinkProgram(ProgramName[program::TRANSFORM]); Validated = Validated && Compiler.checkProgram(ProgramName[program::TRANSFORM]); char Name[64]; memset(Name, 0, 64); GLsizei Length(0); GLsizei Size(0); GLenum Type(0); glGetTransformFeedbackVarying( ProgramName[program::TRANSFORM], 0, 64, &Length, &Size, &Type, Name); Validated = Validated && (Size == 1) && (Type == GL_FLOAT_VEC4); } // Get variables locations if(Validated) { UniformMVP = glGetUniformLocation(ProgramName[program::TRANSFORM], "MVP"); Validated = Validated && (UniformMVP >= 0); } // Create program if(Validated) { ProgramName[program::FEEDBACK] = glCreateProgram(); glAttachShader(ProgramName[program::FEEDBACK], ShaderName[shader::VERT_FEEDBACK]); glAttachShader(ProgramName[program::FEEDBACK], ShaderName[shader::FRAG_FEEDBACK]); glBindAttribLocation(ProgramName[program::FEEDBACK], semantic::attr::POSITION, "Position"); glBindAttribLocation(ProgramName[program::FEEDBACK], semantic::attr::COLOR, "Color"); glBindFragDataLocation(ProgramName[program::FEEDBACK], semantic::frag::COLOR, "Color"); glLinkProgram(ProgramName[program::FEEDBACK]); Validated = Validated && Compiler.checkProgram(ProgramName[program::FEEDBACK]); } return Validated && this->checkError("initProgram"); }
bool initProgram() { bool Validated = true; std::array<GLuint, shader::MAX> ShaderName; compiler Compiler; ShaderName[shader::VERT_TRANSFORM] = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERT_SHADER_SOURCE_TRANSFORM, "--version 150 --profile core"); ShaderName[shader::VERT_FEEDBACK] = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERT_SHADER_SOURCE_FEEDBACK, "--version 150 --profile core"); ShaderName[shader::FRAG_FEEDBACK] = Compiler.create(GL_FRAGMENT_SHADER, getDataDirectory() + FRAG_SHADER_SOURCE_FEEDBACK, "--version 150 --profile core"); Validated = Validated && Compiler.check(); if(Validated) { ProgramName[program::TRANSFORM] = glCreateProgram(); glAttachShader(ProgramName[program::TRANSFORM], ShaderName[shader::VERT_TRANSFORM]); glBindAttribLocation(ProgramName[program::TRANSFORM], semantic::attr::POSITION, "Position"); GLchar const * Strings[] = {"gl_Position", "block.Color"}; glTransformFeedbackVaryings(ProgramName[program::TRANSFORM], 2, Strings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(ProgramName[program::TRANSFORM]); Validated = Validated && Compiler.check_program(ProgramName[program::TRANSFORM]); char Name[64]; memset(Name, 0, 64); GLsizei Length(0); GLsizei Size(0); GLenum Type(0); glGetTransformFeedbackVarying( ProgramName[program::TRANSFORM], 0, 64, &Length, &Size, &Type, Name); Validated = Validated && (Size == 1) && (Type == GL_FLOAT_VEC4); } // Get variables locations if(Validated) { TransformUniformMVP = glGetUniformLocation(ProgramName[program::TRANSFORM], "MVP"); GLint ActiveUniforms(0); glGetProgramiv(ProgramName[program::TRANSFORM], GL_ACTIVE_UNIFORMS, &ActiveUniforms); char Name[64]; memset(Name, 0, 64); GLsizei Length(0); GLsizei Size(0); GLenum Type(0); for(GLint i = 0; i < ActiveUniforms; ++i) { glGetActiveUniform( ProgramName[program::TRANSFORM], i, 64, &Length, &Size, &Type, Name); GLint Location = glGetUniformLocation(ProgramName[program::TRANSFORM], Name); if(TransformUniformMVP == Location) { Validated = Validated && (Size == 1) && (Type == GL_FLOAT_MAT4); Validated = Validated && (TransformUniformMVP >= 0); } } } // Create program if(Validated) { ProgramName[program::FEEDBACK] = glCreateProgram(); glAttachShader(ProgramName[program::FEEDBACK], ShaderName[shader::VERT_FEEDBACK]); glAttachShader(ProgramName[program::FEEDBACK], ShaderName[shader::FRAG_FEEDBACK]); glBindAttribLocation(ProgramName[program::FEEDBACK], semantic::attr::POSITION, "Position"); glBindAttribLocation(ProgramName[program::FEEDBACK], semantic::attr::COLOR, "Color"); glBindFragDataLocation(ProgramName[program::FEEDBACK], semantic::frag::COLOR, "Color"); glLinkProgram(ProgramName[program::FEEDBACK]); Validated = Validated && Compiler.check_program(ProgramName[program::FEEDBACK]); } return Validated && this->checkError("initProgram"); }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint vs = 0, gs = 0; int i; prog = glCreateProgram(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gstext); glAttachShader(prog, vs); glAttachShader(prog, gs); /* check that invalid_varying_names fail to link */ for (i = 0; i < ARRAY_SIZE(invalid_varying_names); i++) { glTransformFeedbackVaryings(prog, 1, &invalid_varying_names[i], GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (piglit_link_check_status_quiet(prog)) { printf("%s is not valid but it was allowed.\n", invalid_varying_names[i]); pass = false; } } /* check that valid_varying_names link properly */ glTransformFeedbackVaryings(prog, ARRAY_SIZE(valid_varying_names), valid_varying_names, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); printf("Transform feedback varyings failed to link properly" " with valid names.\n"); piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); for (i = 0; i < ARRAY_SIZE(valid_varying_names); i++) { char varName[50]; GLsizei nameLength = 0, varSize = 0; GLenum varType = GL_NONE; glGetTransformFeedbackVarying( prog, i, sizeof(varName), &nameLength, &varSize, &varType, varName); printf("Name: %s\t\tType: %s\n", varName, piglit_get_gl_enum_name(varType)); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }