org.spout.engine.filesystem.resource.ClientTexture.java Source code

Java tutorial

Introduction

Here is the source code for org.spout.engine.filesystem.resource.ClientTexture.java

Source

/*
 * This file is part of Spout.
 *
 * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
 * Spout is licensed under the Spout License Version 1.
 *
 * Spout is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * In addition, 180 days after any changes are published, you can use the
 * software, incorporating those changes, under the terms of the MIT license,
 * as described in the Spout License Version 1.
 *
 * Spout is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License,
 * the MIT license and the Spout License Version 1 along with this program.
 * If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
 * License and see <http://spout.in/licensev1> for the full license, including
 * the MIT license.
 */
package org.spout.engine.filesystem.resource;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import org.spout.api.Spout;
import org.spout.api.render.Texture;
import org.spout.engine.SpoutClient;
import org.spout.engine.SpoutRenderer;

public class ClientTexture extends Texture {
    int textureID = -1;

    public ClientTexture(int[] colors, int width, int height) {
        super(colors, width, height);
    }

    public ClientTexture(BufferedImage baseImage) {
        super(baseImage.getRGB(0, 0, baseImage.getWidth(), baseImage.getHeight(), null, 0, baseImage.getWidth()),
                baseImage.getWidth(), baseImage.getHeight());
    }

    @Override
    public Texture subTexture(int x, int y, int w, int h) {
        throw new UnsupportedOperationException("TODO: Reimplement this");
    }

    public int getTextureID() {
        if (!isLoaded()) {
            throw new IllegalStateException("Cannot use an unloaded texture");
        }
        return textureID;
    }

    @Override
    public void bind() {
        if (!isLoaded()) {
            throw new IllegalStateException("Cannot bind an unloaded texture!");
        }
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
        SpoutRenderer.checkGLError();
    }

    public void unload() {
        if (!isLoaded()) {
            throw new IllegalStateException("Cannot delete an unloaded texture!");
        }

        GL11.glDeleteTextures(textureID);
        SpoutRenderer.checkGLError();
        textureID = -1;
    }

    class WriteGPUTask implements Runnable {
        int width, height;
        int[] image;

        public WriteGPUTask(int width, int height, int[] image) {
            this.width = width;
            this.height = height;
            this.image = image;
        }

        @Override
        public void run() {
            textureID = GL11.glGenTextures();
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
            SpoutRenderer.checkGLError();

            /*if (((Client) Spout.getEngine()).getRenderMode() != RenderMode.GL30) {
                
               //Use Mipmaps
               GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
            }*/

            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0);
            SpoutRenderer.checkGLError();
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
            SpoutRenderer.checkGLError();

            //Bilinear Filter the closest mipmap
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
            SpoutRenderer.checkGLError();
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
            SpoutRenderer.checkGLError();

            //Wrap the texture
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
            SpoutRenderer.checkGLError();
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
            SpoutRenderer.checkGLError();

            ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4);
            for (int y = 0; y < height; y++) {

                for (int x = 0; x < width; x++) {
                    Color pixel = new Color(image[y * width + x], true);
                    buffer.put((byte) pixel.getRed()); // Red component
                    buffer.put((byte) pixel.getGreen()); // Green component
                    buffer.put((byte) pixel.getBlue()); // Blue component
                    buffer.put((byte) pixel.getAlpha()); // Alpha component. Only for RGBA
                }
            }

            buffer.flip();
            //if (((Client) Spout.getEngine()).getRenderMode() == RenderMode.GL30) {
            //   GL30.glGenerateMipmap(textureID);
            //}

            GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA,
                    GL11.GL_UNSIGNED_BYTE, buffer);
            SpoutRenderer.checkGLError();

            //EXTFramebufferObject.glGenerateMipmapEXT(GL11.GL_TEXTURE_2D); //Not sure if this extension is supported on most cards. 
        }
    }

    @Override
    public void writeGPU() {
        if (isLoaded()) {
            throw new IllegalStateException("Cannot load an already loaded texture!");
        }
        ((SpoutClient) Spout.getEngine()).getScheduler()
                .enqueueRenderTask(new WriteGPUTask(getWidth(), getHeight(), this.image));
    }

    @Override
    public boolean isLoaded() {
        return textureID != -1;
    }
}