Java tutorial
/* * Copyright (c) 2015 Sam Johnson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.samrj.devil.gl; import com.samrj.devil.io.MemStack; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL33; /** * Abstract OpenGL texture class. * * @author Samuel Johnson (SmashMaster) * @param <T> This texture's own type. */ public abstract class Texture<T extends Texture<T>> extends DGLObj { public final int id, target, binding; private boolean deleted; private boolean hasMipmaps; private long vramUsage; Texture(int target, int binding) { DGL.checkState(); id = GL11.glGenTextures(); this.target = target; this.binding = binding; } abstract T getThis(); /** * @return Whether this texture is bound to the currently active texture channel. */ public final boolean isBound() { return !deleted && GL11.glGetInteger(binding) == id; } final int tempBind() { int oldID = GL11.glGetInteger(binding); if (oldID != id) GL11.glBindTexture(target, id); return oldID; } final void tempUnbind(int oldID) { if (oldID == id) return; GL11.glBindTexture(target, oldID); } final void setVRAMUsage(long bits) { if (bits < 0) throw new IllegalArgumentException(); if (deleted) return; if (hasMipmaps) bits *= 2; Profiler.addUsedVRAM(bits - vramUsage); vramUsage = bits; } /** * Binds this OpenGL texture to whichever texture unit is currently active. * * @return This texture. */ public final T bind() { if (deleted) throw new IllegalStateException("Cannot bind deleted texture."); GL11.glBindTexture(target, id); return getThis(); } /** * Temporarily activates the given texture unit, binds this texture to it, * then activates whichever unit was active before this method was called. * * @param texture The OpenGL texture unit enum to bind to. * @return This texture. */ public final T bind(int texture) { if (deleted) throw new IllegalStateException("Cannot bind deleted texture."); if (texture < GL13.GL_TEXTURE0) throw new IllegalArgumentException(); int old = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE); GL13.glActiveTexture(texture); bind(); GL13.glActiveTexture(old); return getThis(); } /** * Unbinds any texture currently bound to the current texture unit. Might * not be this texture! Manage your texture state carefully. * * @return This texture. */ public final T unbind() { if (isBound()) GL11.glBindTexture(target, 0); return getThis(); } @Override final void delete() { Profiler.removeUsedVRAM(vramUsage); GL11.glDeleteTextures(id); deleted = true; } /** * Sets the given parameter to the given int for this texture. The texture * must be bound. * * @param param The OpenGL texture parameter to set. * @param value The value to set the parameter to. * @return This texture. */ public final T parami(int param, int value) { if (!isBound()) throw new IllegalStateException("Texture must be bound."); GL11.glTexParameteri(target, param, value); return getThis(); } // public final T paramiv(int param, int... values) // { // if (!isBound()) throw new IllegalStateException("Texture must be bound."); // long address = MemStack.wrapi(values); // GL11.nglTexParameteriv(target, param, address); // MemStack.pop(); // return getThis(); // } /** * Sets the given parameter to the given float for this texture. The texture * must be bound. * * @param param The OpenGL texture parameter to set. * @param value The value to set the parameter to. * @return This texture. */ public final T paramf(int param, float value) { if (!isBound()) throw new IllegalStateException("Texture must be bound."); GL11.glTexParameterf(target, param, value); return getThis(); } // public final T paramfv(int param, float... values) // { // if (!isBound()) throw new IllegalStateException("Texture must be bound."); // long address = MemStack.wrapf(values); // GL11.nglTexParameterfv(target, param, address); // MemStack.pop(); // return getThis(); // } public final T swizzle(int r, int g, int b, int a) { if (!isBound()) throw new IllegalStateException("Texture must be bound."); long address = MemStack.wrapi(r, g, b, a); GL11.nglTexParameteriv(target, GL33.GL_TEXTURE_SWIZZLE_RGBA, address); MemStack.pop(); return getThis(); } /** * Generates mipmaps for this texture. * * @return This texture. */ public final T generateMipmap() { int oldID = tempBind(); GL30.glGenerateMipmap(target); if (!hasMipmaps) setVRAMUsage(vramUsage * 2); hasMipmaps = true; tempUnbind(oldID); return getThis(); } }