public static void init(GL2 gl) throws OpenGLException { // permutation setup permutation = new int[256]; for (int i = 0; i < 256; i++) { permutation[i] = i; } Random rand = new Random(); for (int i = 255; i > 0; i--) { int index = rand.nextInt(i + 1); int tmp = permutation[i]; permutation[i] = permutation[index]; permutation[index] = tmp; } byte[] permutationBytes = new byte[256 * 4]; int count = 0; for (int i = 0; i < 255; i++) { permutationBytes[count++] = (byte) (0xFF & permutation[i]); permutationBytes[count++] = (byte) (0xFF & permutation[i]); permutationBytes[count++] = (byte) (0xFF & permutation[i]); permutationBytes[count++] = (byte) (0xFF & permutation[i]); } ByteBuffer permBuff = ByteBuffer.wrap(permutationBytes); permutationTexture = new Texture2D(gl, Format.RGBA, Datatype.INT8, 256, 1, permBuff); permutationTexture.setWrapModeOne(gl, WrapMode.REPEAT, TextureWrapCoordinate.S); permutationTexture.setWrapModeOne(gl, WrapMode.CLAMP, TextureWrapCoordinate.T); permutationTexture.enableInterpolation(gl, false); // gradient setup gradients = new int[][] { {1, 1, 0}, {-1, 1, 0}, {1, -1, 0}, {-1, -1, 0}, {1, 0, 1}, {-1, 0, 1}, {1, 0, -1}, {-1, 0, -1}, {0, 1, 1}, {0, -1, 1}, {0, 1, -1}, {0, -1, -1}, {1, 1, 0}, {0, -1, 1}, {-1, 1, 0}, {0, -1, -1} }; float[] gradientBytes = new float[16 * 4]; for (int i = 0; i < 16; i++) { gradientBytes[i * 4] = gradients[i][0]; gradientBytes[i * 4 + 1] = gradients[i][1]; gradientBytes[i * 4 + 2] = gradients[i][2]; gradientBytes[i * 4 + 3] = 1; } FloatBuffer gradBuff = FloatBuffer.wrap(gradientBytes); gradientTexture = new Texture2D(gl, Format.RGBA, Datatype.FLOAT16, 16, 1, gradBuff); // gradientTexture.setWrapModeOne(gl, WrapMode.REPEAT, TextureWrapCoordinate.S); // gradientTexture.setWrapModeOne(gl, WrapMode.CLAMP, TextureWrapCoordinate.T); gradientTexture.setWrapModeAll(gl, WrapMode.REPEAT); gradientTexture.enableInterpolation(gl, false); }
/** * Destroys this framebuffer object. * * <p>The owned textures are also destroyed, so copy any you need first! */ public void releaseGPUResources(GL2 gl) { /* Release textures. */ for (Texture2D tex : mColorTextures) { tex.releaseGPUResources(gl); } if (mDepthTexture != null) { mDepthTexture.releaseGPUResources(gl); } /* Destroy the FBO itself. */ if (mHandle >= 0) { int names[] = new int[1]; names[0] = mHandle; gl.glDeleteFramebuffers(1, names, 0); mHandle = -1; } }
/** * Creates a new FBO with the passed attributes and number of render targets. * * @param gl The OpenGL context in which this FBO lives. * @param format The format for data in the color textures. * @param datatype The datatype for data in the color textures. * @param width The width of the renderable viewport and all the textures. * @param height The height of the renderable viewport and all the textures. * @param colorTextureCount The number of associated color textures/render targets. May specify 0 * if you don't care about color output. It is an error to request 0 color textures and no * depth buffer. * @param makeDepthTexture True if a depth texture should be created. False if you don't need a * depth buffer. It is an error to request 0 color textures and no depth buffer. * @param rectTextures If true, the created textures will be rectangular textures. If false, they * will be regular 2D textures, which requires GL_EXT_texture_non_power_of_two if `width` and * `height` aren't powers of two. */ public FramebufferObject( GL2 gl, Texture2D.Format format, Texture2D.Datatype datatype, int width, int height, int colorTextureCount, boolean makeDepthTexture, boolean rectTextures) throws OpenGLException { /* Sanity check. */ if (colorTextureCount == 0 && !makeDepthTexture) { throw new OpenGLException( "It is not valid to make an FBO with no color buffers and no depth buffer."); } int maxColorTextures[] = new int[1]; gl.glGetIntegerv(GL2.GL_MAX_COLOR_ATTACHMENTS, maxColorTextures, 0); if (colorTextureCount > maxColorTextures[0]) { throw new OpenGLException( "Cannot create an FBO with " + colorTextureCount + " render targets. Your graphics card only supports " + maxColorTextures[0] + "."); } mWidth = width; mHeight = height; /* Create OpenGL FBO. */ int names[] = new int[1]; gl.glGenFramebuffers(1, names, 0); mHandle = names[0]; /* Remember previous FBO binding, and then bind this one. */ int previousBinding[] = new int[1]; gl.glGetIntegerv(GL2.GL_FRAMEBUFFER_BINDING, previousBinding, 0); gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, mHandle); /* Create and attach color textures. */ mColorTextures = new Texture2D[colorTextureCount]; for (int i = 0; i < colorTextureCount; ++i) { mColorTextures[i] = new Texture2D(gl, format, datatype, width, height, null, rectTextures); gl.glFramebufferTexture2D( GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0 + i, mColorTextures[i].getTextureTarget(), mColorTextures[i].getHandle(), 0); } /* Create and attach depth texture, if requested. */ if (makeDepthTexture) { mDepthTexture = new Texture2D(gl, Format.DEPTH, Datatype.INT32, width, height, null, rectTextures); gl.glFramebufferTexture2D( GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, mDepthTexture.getTextureTarget(), mDepthTexture.getHandle(), 0); } /* Make sure everything is set up properly. */ int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER); if (status != GL2.GL_FRAMEBUFFER_COMPLETE) { throw new OpenGLException("Framebuffer incomplete: " + status + "."); } /* Restore whatever FBO was bound before this function was called. */ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, previousBinding[0]); }
public static void unbind(GL2 gl) { permutationTexture.unbind(gl); gradientTexture.unbind(gl); }
public static void bind(GL2 gl, int textureUnit1, int textureUnit2) throws OpenGLException { permutationTexture.bind(gl, textureUnit1); gradientTexture.bind(gl, textureUnit2); }