예제 #1
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
    }
예제 #2
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
    }