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); }
public virtual void bindBufferBase(int target, int bindingPoint, int buffer) { proxy.bindBufferBase(target, bindingPoint, buffer); }