Exemplo n.º 1
0
        public override void initShaderProgram(IRenderingEngine re, int shaderProgram)
        {
            int blockIndex = re.getUniformBlockIndex(shaderProgram, uniformBlockName);

            // The uniform block might have been eliminated by the shader compiler
            // if it was not used at all.
            if (blockIndex >= 0)
            {
                re.setUniformBlockBinding(shaderProgram, blockIndex, bindingPoint);
            }

            if (data == null)
            {
                int previousOffset = -1;
                foreach (ShaderUniformInfo shaderUniformInfo in shaderUniformInfos)
                {
                    int index  = re.getUniformIndex(shaderProgram, shaderUniformInfo.Name);
                    int offset = re.getActiveUniformOffset(shaderProgram, index);

                    // Nvidia workaRound: the offset of the first uniform is returned as 1 instead of 0.
                    if (offset == 1)
                    {
                        offset = 0;
                    }

                    shaderUniformInfo.Offset = offset;

                    // An unused uniform has the same offset as its previous uniform.
                    // An unused uniform should not be copied into the UBO buffer,
                    // otherwise it would overwrite the previous uniform value.
                    if (offset < 0 || offset == previousOffset)
                    {
                        shaderUniformInfo.setUnused();
                    }

                    //if (log.DebugEnabled)
                    {
                        Console.WriteLine(string.Format("Uniform {0}", shaderUniformInfo));
                    }

                    previousOffset = offset;
                }

                // The size returned by
                //    glGetActiveUniformBlock(program, blockIndex, ARBUniformBufferObject.GL_UNIFORM_BLOCK_DATA_SIZE)
                // is not reliable as the driver is free to reduce array sizes when they
                // are not used in the shader.
                // Use a dummy element of the structure to find the total structure size.
                int lastOffset;
                if (endOfUBO.Offset <= 0 || !endOfUBO.Used)
                {
                    // If the endOfUBO uniform has been eliminated by the shader compiler,
                    // estimate the end of the buffer by using the offset of the boneMatrix uniform.
                    lastOffset = boneMatrix.Offset + boneMatrix.MatrixSize * 4 * 4 * SIZEOF_FLOAT;
                }
                else
                {
                    lastOffset = endOfUBO.Offset;
                }
                bufferSize = lastOffset + 4;

                //if (log.DebugEnabled)
                {
                    Console.WriteLine(string.Format("UBO Structure size: {0:D} (including endOfUBO)", bufferSize));
                }

                buffer = re.genBuffer();
                re.bindBuffer(IRenderingEngine_Fields.RE_UNIFORM_BUFFER, buffer);

                data = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
                // Initialize the buffer to 0's
                for (int i = 0; i < bufferSize; i++)
                {
                    data.put(i, (sbyte)0);
                }
                re.setBufferData(IRenderingEngine_Fields.RE_UNIFORM_BUFFER, bufferSize, data, IRenderingEngine_Fields.RE_DYNAMIC_DRAW);

                // On AMD hardware, the buffer data has to be set (setBufferData) before calling bindBufferBase
                re.bindBufferBase(IRenderingEngine_Fields.RE_UNIFORM_BUFFER, bindingPoint, buffer);

                startUpdate = 0;
                endUpdate   = bufferSize;
            }

            base.initShaderProgram(re, shaderProgram);
        }
Exemplo n.º 2
0
 public virtual void bindBufferBase(int target, int bindingPoint, int buffer)
 {
     proxy.bindBufferBase(target, bindingPoint, buffer);
 }