/* * Copyright (c) 2002-2008 LWJGL Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'LWJGL' nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Created by LWJGL. * User: spasi * Date: 2009-12-04 */ package org.lwjgl.test.opengl.shaders; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.*; import java.nio.FloatBuffer; import java.nio.IntBuffer; import static org.lwjgl.opengl.ARBUniformBufferObject.*; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.*; import static org.lwjgl.opengl.GL20.*; final class ShaderUNI extends Shader { final String file; final String source; final int shaderID; final int programID; final int bufferID; final FloatBuffer buffer; final int uniformA_index; final int uniformA_offset; final int uniformB_index; final int uniformB_offset; ShaderUNI(final String shaderFile) { file = shaderFile; source = getShaderText(shaderFile); shaderID = glCreateShader(GL_VERTEX_SHADER); glShaderSource(shaderID, source); glCompileShader(shaderID); printShaderObjectInfoLog(file, shaderID); if ( glGetShaderi(shaderID, GL_COMPILE_STATUS) == GL_FALSE ) ShadersTest.kill("A compilation error occured in a vertex shader."); programID = glCreateProgram(); glAttachShader(programID, shaderID); glLinkProgram(programID); printShaderProgramInfoLog(programID); if ( glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE ) ShadersTest.kill("A linking error occured in a shader program."); final String[] uniformNames = { "uniformA", "uniformB" }; // Get uniform block index and data size final int blockIndex = glGetUniformBlockIndex(programID, "test"); final int blockSize = glGetActiveUniformBlocki(programID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE); System.out.println("blockSize = " + blockSize); // Create uniform buffer object and allocate a ByteBuffer bufferID = glGenBuffers(); glBindBuffer(GL_UNIFORM_BUFFER, bufferID); glBufferData(GL_UNIFORM_BUFFER, blockSize, GL_DYNAMIC_DRAW); buffer = BufferUtils.createFloatBuffer(blockSize); // Attach UBO and associate uniform block to binding point 0 glBindBufferBase(GL_UNIFORM_BUFFER, 0, bufferID); glUniformBlockBinding(programID, blockIndex, 0); // Get uniform information IntBuffer indexes = BufferUtils.createIntBuffer(uniformNames.length); IntBuffer params = BufferUtils.createIntBuffer(uniformNames.length); glGetUniformIndices(programID, uniformNames, indexes); uniformA_index = indexes.get(0); uniformB_index = indexes.get(1); glGetActiveUniforms(programID, indexes, GL_UNIFORM_OFFSET, params); uniformA_offset = params.get(0); uniformB_offset = params.get(1); System.out.println("\nuniformA index = " + uniformA_index); System.out.println("uniformB index = " + uniformB_index); System.out.println("\nuniformA offset = " + uniformA_offset + " - should be 0 for std140"); System.out.println("uniformB offset = " + uniformB_offset + " - should be 16 for std140"); Util.checkGLError(); } void render() { glUseProgram(programID); //* -- std140 layout // Uniform A buffer.put(0, ShadersTest.getSin()).put(1, ShadersTest.getSpecularity() * 8.0f); // Uniform B - str140 alignment at 16 bytes buffer.put(4, 0.0f).put(5, 0.7f).put(6, 0.0f); glBindBuffer(GL_UNIFORM_BUFFER, bufferID); glBufferData(GL_UNIFORM_BUFFER, buffer, GL_DYNAMIC_DRAW); //*/ /* -- non-std140 layout // Uniform A buffer.put(ShadersTest.getSin()).put(ShadersTest.getSpecularity() * 8.0f); buffer.flip(); glBufferSubData(GL_UNIFORM_BUFFER, uniformA_offset, buffer); // Uniform B buffer.clear(); buffer.put(0.0f).put(0.7f).put(0.0f); buffer.flip(); glBufferSubData(GL_UNIFORM_BUFFER, uniformB_offset, buffer); //*/ ShadersTest.renderObject(); glUseProgram(0); } void cleanup() { glDeleteBuffers(bufferID); glDetachShader(programID, shaderID); glDeleteShader(shaderID); glDeleteProgram(programID); } }