fr.ign.cogit.geoxygene.appli.render.texture.BinaryGradientTexture.java Source code

Java tutorial

Introduction

Here is the source code for fr.ign.cogit.geoxygene.appli.render.texture.BinaryGradientTexture.java

Source

/*******************************************************************************
 * This file is part of the GeOxygene project source files.
 * 
 * GeOxygene aims at providing an open framework which implements OGC/ISO
 * specifications for the development and deployment of geographic (GIS)
 * applications. It is a open source contribution of the COGIT laboratory at the
 * Institut Gographique National (the French National Mapping Agency).
 * 
 * See: http://oxygene-project.sourceforge.net
 * 
 * Copyright (C) 2005 Institut Gographique National
 * 
 * This library 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 2.1 of the License, or any later version.
 * 
 * This library 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
 * along with this library (see file LICENSE if present); if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *******************************************************************************/

package fr.ign.cogit.geoxygene.appli.render.texture;

import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_REPEAT;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameteri;

import java.net.URL;
import java.nio.ByteBuffer;

import org.apache.log4j.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

import fr.ign.cogit.geoxygene.appli.gl.BinaryGradientImage;
import fr.ign.cogit.geoxygene.appli.gl.BinaryGradientImage.GradientPixel;
import fr.ign.cogit.geoxygene.util.gl.BasicTexture;
import fr.ign.cogit.geoxygene.util.gl.GLTexture;

/**
 * @author JeT BinaryGradient texture returns the coordinates equal to the
 *         provided point. It contains a BinaryGradientImage and gives texture
 *         as a floating point texture to the GPU
 */
public class BinaryGradientTexture extends BasicTexture {

    private static final Logger logger = Logger.getLogger(BinaryGradientTexture.class.getName()); // logger

    public static final String gradientUVMinUniformVarname = "uvMinGradientTexture";
    public static final String gradientUVRangeUniformVarname = "uvRangeGradientTexture";
    private BinaryGradientImage binaryGradientImage = null;

    private String samplerUniformVarName;

    /**
     * Constructor
     */
    public BinaryGradientTexture() {
        super();
    }

    /**
     * Constructor with an image to read
     * 
     * @param _tex_url : the texture location
     */
    public BinaryGradientTexture(final URL _tex_url) {
        this();
        this.setTextureFilename(_tex_url);
    }

    /**
     * Constructor with an image in memory
     * 
     * @param binaryGradientImage
     */
    public BinaryGradientTexture(BinaryGradientImage binaryGradientImage) {
        this();
        this.binaryGradientImage = binaryGradientImage;
        this.textureId = -1;
    }

    /**
     * @return the textureSlot
     */
    public int getTextureSlot() {
        return this.textureSlot;
    }

    /**
     * @return the uniformVarName
     */
    public String getUniformVarName() {
        return this.samplerUniformVarName;
    }

    /**
     * @param textureSlot
     *            the textureSlot to set
     */
    public void setTextureSlot(String uniformVarName, int textureSlot) {
        this.samplerUniformVarName = uniformVarName;
        this.textureSlot = textureSlot;
    }

    /**
     * @return the generated texture id
     */
    public final Integer getTextureId() {
        if (this.textureId < 0) {
            GL13.glActiveTexture(this.textureSlot);
            BinaryGradientImage gradientImage = this.getBinaryGradientImage();

            int width = gradientImage.getWidth();
            int height = gradientImage.getHeight();
            // 16 = 4 floats (float = 4 bytes) = 16
            ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 16);
            double uMin = gradientImage.getuMin();
            double vMin = gradientImage.getvMin();
            double uRange = gradientImage.getuMax() - gradientImage.getuMin();
            double vRange = gradientImage.getvMax() - gradientImage.getvMin();
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    GradientPixel pixel = gradientImage.getPixel(x, y);
                    buffer.putFloat((float) ((pixel.uTexture - uMin) / uRange));
                    buffer.putFloat((float) ((pixel.vTexture - vMin) / vRange));
                    // System.err.println("uvTexture = "
                    // + (float) ((pixel.uTexture - uMin) / uRange) + "x"
                    // + (float) ((pixel.vTexture - vMin) / vRange));
                    if (pixel.vGradient != null) {
                        buffer.putFloat((float) pixel.vGradient.x);
                        buffer.putFloat((float) pixel.vGradient.y);
                    } else {
                        // TODO: !! compute gradient !!
                        buffer.putFloat(0f);
                        buffer.putFloat(0f);
                    }
                }
            }

            buffer.rewind();

            // You now have a ByteBuffer filled with the color data of each
            // pixel.
            // Now just create a texture ID and bind it. Then you can load it
            // using
            // whatever OpenGL method you want, for example:

            this.textureId = glGenTextures(); // Generate texture ID
            glBindTexture(GL_TEXTURE_2D, this.textureId); // Bind texture ID

            glTexImage2D(GL_TEXTURE_2D, 0, GL30.GL_RGBA32F, width, height, 0, GL11.GL_RGBA, GL11.GL_FLOAT, buffer);
            // Setup texture scaling filtering
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            // Return the texture ID so we can bind it later again
        }
        return this.textureId;
    }

    /**
     * @return the textureImage
     */
    public final BinaryGradientImage getBinaryGradientImage() {
        return this.binaryGradientImage;
    }

    /**
     * @param _tex_url
     *            the url of the texture to set
     */
    public final void setTextureFilename(final URL _tex_url) {
        super.setTextureURL(_tex_url);
        this.textureId = -1;
        this.binaryGradientImage = null;
    }

    /**
     * initialize the texture rendering
     */
    @Override
    public boolean initializeRendering(int programId) {
        Integer texIndex = this.getTextureId();
        if (texIndex == null) {
            GL11.glDisable(GL_TEXTURE_2D);
            return false;
        }
        glEnable(GL_TEXTURE_2D);
        GL13.glActiveTexture(this.textureSlot);
        glBindTexture(GL_TEXTURE_2D, texIndex);
        // vMin has a special value '-1' = out of polygon
        // consider that vMin is always equal to zero
        float uMin = (float) (double) this.binaryGradientImage.getuMin();
        float vMin = 0;
        float uRange = (float) (this.binaryGradientImage.getuMax() - this.binaryGradientImage.getuMin());
        float vRange = (float) (double) (this.binaryGradientImage.getvMax());
        GL20.glUniform2f(GL20.glGetUniformLocation(programId, gradientUVMinUniformVarname), uMin, vMin);
        GL20.glUniform2f(GL20.glGetUniformLocation(programId, gradientUVRangeUniformVarname), uRange, vRange);
        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.ign.cogit.geoxygene.appli.gl.Texture#finalizeRendering()
     */
    @Override
    public void finalizeRendering() {

    }

    public void setTextureImage(BinaryGradientImage gradientImage) {
        this.binaryGradientImage = gradientImage;
        this.textureId = -1;
        // this.textureId = GLTools.loadTexture(this.textureImage);

    }

}