1 /* 2 * Copyright (c) 2002-2008 LWJGL Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'LWJGL' nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /* 33 * Created by LWJGL. 34 * User: spasi 35 * Date: 2009-12-04 36 */ 37 38 package org.lwjgl.test.opengl.shaders; 39 40 import org.lwjgl.BufferUtils; 41 import org.lwjgl.opengl.*; 42 43 import java.nio.FloatBuffer; 44 import java.nio.IntBuffer; 45 46 import static org.lwjgl.opengl.ARBUniformBufferObject.*; 47 import static org.lwjgl.opengl.GL11.*; 48 import static org.lwjgl.opengl.GL15.*; 49 import static org.lwjgl.opengl.GL20.*; 50 51 final class ShaderUNI extends Shader { 52 53 final String file; 54 final String source; 55 56 final int shaderID; 57 final int programID; 58 59 final int bufferID; 60 final FloatBuffer buffer; 61 62 final int uniformA_index; 63 final int uniformA_offset; 64 65 final int uniformB_index; 66 final int uniformB_offset; 67 ShaderUNI(final String shaderFile)68 ShaderUNI(final String shaderFile) { 69 file = shaderFile; 70 source = getShaderText(shaderFile); 71 72 shaderID = glCreateShader(GL_VERTEX_SHADER); 73 glShaderSource(shaderID, source); 74 glCompileShader(shaderID); 75 76 printShaderObjectInfoLog(file, shaderID); 77 78 if ( glGetShaderi(shaderID, GL_COMPILE_STATUS) == GL_FALSE ) 79 ShadersTest.kill("A compilation error occured in a vertex shader."); 80 81 programID = glCreateProgram(); 82 83 glAttachShader(programID, shaderID); 84 glLinkProgram(programID); 85 86 printShaderProgramInfoLog(programID); 87 88 if ( glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE ) 89 ShadersTest.kill("A linking error occured in a shader program."); 90 91 final String[] uniformNames = { "uniformA", "uniformB" }; 92 93 // Get uniform block index and data size 94 final int blockIndex = glGetUniformBlockIndex(programID, "test"); 95 final int blockSize = glGetActiveUniformBlocki(programID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE); 96 97 System.out.println("blockSize = " + blockSize); 98 99 // Create uniform buffer object and allocate a ByteBuffer 100 bufferID = glGenBuffers(); 101 glBindBuffer(GL_UNIFORM_BUFFER, bufferID); 102 glBufferData(GL_UNIFORM_BUFFER, blockSize, GL_DYNAMIC_DRAW); 103 buffer = BufferUtils.createFloatBuffer(blockSize); 104 105 // Attach UBO and associate uniform block to binding point 0 106 glBindBufferBase(GL_UNIFORM_BUFFER, 0, bufferID); 107 glUniformBlockBinding(programID, blockIndex, 0); 108 109 // Get uniform information 110 IntBuffer indexes = BufferUtils.createIntBuffer(uniformNames.length); 111 IntBuffer params = BufferUtils.createIntBuffer(uniformNames.length); 112 113 glGetUniformIndices(programID, uniformNames, indexes); 114 uniformA_index = indexes.get(0); 115 uniformB_index = indexes.get(1); 116 117 glGetActiveUniforms(programID, indexes, GL_UNIFORM_OFFSET, params); 118 uniformA_offset = params.get(0); 119 uniformB_offset = params.get(1); 120 121 System.out.println("\nuniformA index = " + uniformA_index); 122 System.out.println("uniformB index = " + uniformB_index); 123 124 System.out.println("\nuniformA offset = " + uniformA_offset + " - should be 0 for std140"); 125 System.out.println("uniformB offset = " + uniformB_offset + " - should be 16 for std140"); 126 127 Util.checkGLError(); 128 } 129 render()130 void render() { 131 glUseProgram(programID); 132 133 //* -- std140 layout 134 // Uniform A 135 buffer.put(0, ShadersTest.getSin()).put(1, ShadersTest.getSpecularity() * 8.0f); 136 // Uniform B - str140 alignment at 16 bytes 137 buffer.put(4, 0.0f).put(5, 0.7f).put(6, 0.0f); 138 139 glBindBuffer(GL_UNIFORM_BUFFER, bufferID); 140 glBufferData(GL_UNIFORM_BUFFER, buffer, GL_DYNAMIC_DRAW); 141 //*/ 142 143 /* -- non-std140 layout 144 // Uniform A 145 buffer.put(ShadersTest.getSin()).put(ShadersTest.getSpecularity() * 8.0f); 146 buffer.flip(); 147 glBufferSubData(GL_UNIFORM_BUFFER, uniformA_offset, buffer); 148 // Uniform B 149 buffer.clear(); 150 buffer.put(0.0f).put(0.7f).put(0.0f); 151 buffer.flip(); 152 glBufferSubData(GL_UNIFORM_BUFFER, uniformB_offset, buffer); 153 //*/ 154 155 ShadersTest.renderObject(); 156 157 glUseProgram(0); 158 } 159 cleanup()160 void cleanup() { 161 glDeleteBuffers(bufferID); 162 163 glDetachShader(programID, shaderID); 164 165 glDeleteShader(shaderID); 166 glDeleteProgram(programID); 167 } 168 169 }