/* 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;
}
Esempio n. 2
0
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);
}
Esempio n. 4
0
    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
    }
Esempio n. 5
0
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.";
	}
}
Esempio n. 8
0
/**
 * 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);
    }
}
Esempio n. 12
0
    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);
}