JOGL 2 Texture GL_REPEAT Question.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

JOGL 2 Texture GL_REPEAT Question.

Pixelapp


I have a question. When I use GL_REPEAT in my code I get the above picture (my snippet of code is below). I'm expecting not to get spaces between the tiles which are white. You can identify the space which are blue in between the tiles. Why aren't the tiles close to each other "back to back"? Why can I see the blue background?

Moreover, when I need to use GL_CLAMP_TO_EDGE OR GL_CLAMP everything works fine, meaning I get the desired results which is a clamped texture. However; not with GL_REPEAT, I don't get a repeated texture.

Please don't rush into finding a solution; I just want to know, is this a bug or not?

       // Obviously my texture loader method
        private void loadTexture(String[] fnm, GL2 gl) {

                for (count = ZERO; count < NUMTEXTURES; count++) {
                        fileName[count] = folder + fnm[count];

                        try {
                                tex[count] = TextureIO.newTexture(
                                                cl.getResource(fileName[count]), false, null);

                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_MIN_FILTER,
                                                GL2.GL_NEAREST);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_MAG_FILTER,
                                                GL2.GL_NEAREST);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_WRAP_S,
                                                GL2.GL_REPEAT);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_WRAP_T,
                                                GL2.GL_REPEAT);

                        } catch (Exception e) {
                                System.out.println("Error loading texture " + fileName[count]);
                        }

                }
        }

                // Here I set the texture coordinates
                mTexBufferDisplay[0].put(tc[32].left()); // x or s
                mTexBufferDisplay[0].put(3); // y or t

                mTexBufferDisplay[0].put(3); // x or s
                mTexBufferDisplay[0].put(3); // y or t

                mTexBufferDisplay[0].put(3); // x or s
                mTexBufferDisplay[0].put(tc[32].top()); // y or t

                mTexBufferDisplay[0].put(tc[32].left()); // x or s
                mTexBufferDisplay[0].put(tc[32].top()); // y or t

                mTexBufferDisplay[0].position(0);

Thanks in advance.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2 Texture GL_REPEAT Question.

Pixelapp


The project was set up in eclipse, using JDK 7 update 1.

Ok so here is the full code.

package pixelapp.samplecode;
import java.awt.Cursor;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.TextureIO;

public class SampleCode implements GLEventListener
{
       
        // Load Textures
        private static ClassLoader cl;
        private String file[] = {"wlap1.png"
                        };
        private String folder = "pixelapp/samplecode/images/";
        private JFrame myFrame; // Create JFrame object.
        private final int ZERO = 0;
        private int count = ZERO;
        private int acc = ZERO; // Accumulator
        private int NUMTEXTURES = 1; // Number of textures
        private Texture[] tex = new Texture[NUMTEXTURES];
        private String[] fileName = new String[NUMTEXTURES];
        private TextureCoords[] tc = new TextureCoords[NUMTEXTURES];
        private int cubeAcc = 0;

        // To calculate textures
        private final int SQUARE_VERT = 4;
        private float one = 1;
       
        // Display
        private int NUM_CUBES_DISPLAY = 1;
        private final int MAX_NUM_CUBES_DISPLAY = 1;
        private FloatBuffer[] mVertexBufferDisplay = new FloatBuffer[MAX_NUM_CUBES_DISPLAY];
        private FloatBuffer[] mColorBufferDisplay = new FloatBuffer[MAX_NUM_CUBES_DISPLAY];
        private ByteBuffer[] mIndexBufferDisplay = new ByteBuffer[MAX_NUM_CUBES_DISPLAY];
        private FloatBuffer[] mTexBufferDisplay = new FloatBuffer[MAX_NUM_CUBES_DISPLAY];
        private ByteBuffer[] vbbDisplay = new ByteBuffer[MAX_NUM_CUBES_DISPLAY];
        private ByteBuffer[] cbbDisplay = new ByteBuffer[MAX_NUM_CUBES_DISPLAY];
        private ByteBuffer[] tbbDisplay = new ByteBuffer[MAX_NUM_CUBES_DISPLAY];

        // Translate
        private int[] translateXDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private int[] translateYDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private int[] translateZDisplay = new int[MAX_NUM_CUBES_DISPLAY];

        // Rotate

        private int[] rotateXDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private byte[] activeXDisplay = new byte[MAX_NUM_CUBES_DISPLAY];

        private int[] rotateYDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private byte[] activeYDisplay = new byte[MAX_NUM_CUBES_DISPLAY];

        private int[] rotateZDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private byte[] activeZDisplay = new byte[MAX_NUM_CUBES_DISPLAY];

        // Scale
        private int[] scaleXDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private int[] scaleYDisplay = new int[MAX_NUM_CUBES_DISPLAY];
        private int[] scaleZDisplay = new int[MAX_NUM_CUBES_DISPLAY];

        private float[] cubeFillerVDisplay = {
                        1f, 1f, 0f,
                        1f, -1, 0f,
                        -1f, -1f, 0f,
                        -1f, 1f, 0f,
                        };

        private float[] cubeFillerCDisplay = {
        one, one, one, one,
         one, one, one, one,
         one, one, one, one,
          one , one, one, one, };

        private byte[] cubeFillerIDisplay = { 1 - 1, 4 - 1, 3 - 1, 1 - 1, 3 - 1,
                        2 - 1, };
       
        private GLCanvas miCanvas;
        private FPSAnimator animator;
       
        public SampleCode()
        {
                // Create JFrame object.
                myFrame = new JFrame("Wavelogy");

                // Close program on Finish.
                myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               
                GLProfile glp = GLProfile.getDefault();
      GLCapabilities caps = new GLCapabilities(glp);
      miCanvas = new GLCanvas(caps);
               
               
               

                // Indicate Canvas to detect the events of OpenGL in this Class.
                miCanvas.addGLEventListener(this);



                miCanvas.setFocusable(true); // To receive key event
                miCanvas.requestFocus();

                // Insert Canvas in the Frame.
                myFrame.add(miCanvas);

                // Hide Cursor
                // Transparent 16 x 16 pixel cursor image.
                BufferedImage cursorImg = new BufferedImage(16, 16,
                                BufferedImage.TYPE_INT_ARGB);

                // Create a new blank cursor.
                Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
                                cursorImg, new Point(0, 0), "blank cursor");

                // Set the blank cursor to the JFrame.
                myFrame.getContentPane().setCursor(blankCursor);

       

       

                // Size of the window
                myFrame.setSize(1280, 600);

                // Eliminates the windows frames look.
                myFrame.setUndecorated(true);

                /**
                 * Full Screen Mode
                 */
                GraphicsEnvironment env = GraphicsEnvironment.

                getLocalGraphicsEnvironment();

                GraphicsDevice device = env.getDefaultScreenDevice();

                device.setFullScreenWindow(myFrame);

                // Renders continuously JOGL2.
                animator = new FPSAnimator(miCanvas, 30);
                animator.add(miCanvas);
                animator.start();

                // Get current classloader
                cl = this.getClass().getClassLoader();
               
                // Display
                // Buffers to be passed to gl*Pointer() functions
                // must be direct, i.e., they must be placed on the
                // native heap where the garbage collector cannot
                // move them.
                //
                // Buffers with multi-byte datatypes (e.g., short, int, float)
                // must have their byte order set to native order

                // Initialize polygon transformations
                for (cubeAcc = ZERO; cubeAcc < NUM_CUBES_DISPLAY; cubeAcc++) {
                        translateXDisplay[cubeAcc] = ZERO;
                        translateYDisplay[cubeAcc] = ZERO;
                        translateZDisplay[cubeAcc] = ZERO;

                        rotateXDisplay[cubeAcc] = ZERO;
                        activeXDisplay[cubeAcc] = ZERO;

                        rotateYDisplay[cubeAcc] = ZERO;
                        activeYDisplay[cubeAcc] = ZERO;

                        rotateZDisplay[cubeAcc] = ZERO;
                        activeZDisplay[cubeAcc] = ZERO;

                        scaleXDisplay[cubeAcc] = ZERO;
                        scaleYDisplay[cubeAcc] = ZERO;
                        scaleZDisplay[cubeAcc] = ZERO;
                }

                for (cubeAcc = ZERO; cubeAcc < NUM_CUBES_DISPLAY; cubeAcc++) {
                        vbbDisplay[cubeAcc] = ByteBuffer
                                        .allocateDirect(cubeFillerVDisplay.length * 4);
                        vbbDisplay[cubeAcc].order(ByteOrder.nativeOrder());
                        mVertexBufferDisplay[cubeAcc] = vbbDisplay[cubeAcc].asFloatBuffer();
                        mVertexBufferDisplay[cubeAcc].put(cubeFillerVDisplay);
                        mVertexBufferDisplay[cubeAcc].position(0);

                }

                for (cubeAcc = ZERO; cubeAcc < NUM_CUBES_DISPLAY; cubeAcc++) {
                        cbbDisplay[cubeAcc] = ByteBuffer
                                        .allocateDirect(cubeFillerCDisplay.length * 4);
                        cbbDisplay[cubeAcc].order(ByteOrder.nativeOrder());
                        mColorBufferDisplay[cubeAcc] = cbbDisplay[cubeAcc].asFloatBuffer();
                        mColorBufferDisplay[cubeAcc].put(cubeFillerCDisplay);
                        mColorBufferDisplay[cubeAcc].position(0);

                }

                for (cubeAcc = ZERO; cubeAcc < NUM_CUBES_DISPLAY; cubeAcc++) {
                        mIndexBufferDisplay[cubeAcc] = ByteBuffer
                                        .allocateDirect(cubeFillerIDisplay.length);
                        mIndexBufferDisplay[cubeAcc].put(cubeFillerIDisplay);
                        mIndexBufferDisplay[cubeAcc].position(0);

                }

                for (cubeAcc = ZERO; cubeAcc < NUM_CUBES_DISPLAY; cubeAcc++) {
                        tbbDisplay[cubeAcc] = ByteBuffer.allocateDirect(SQUARE_VERT * 2 * 4);
                        tbbDisplay[cubeAcc].order(ByteOrder.nativeOrder());
                        mTexBufferDisplay[cubeAcc] = tbbDisplay[cubeAcc].asFloatBuffer();

                }
        }

        /**
         * @param args
         */
        public static void main(String[] args) {
                new SampleCode();

        }

        @Override
        public void init(GLAutoDrawable drawable)
        {
                GL2 gl = drawable.getGL().getGL2(); // Initialize the variable GL

                // >>
                gl.glClearDepth(1.0f); // Set depth's clear-value to farthest
                gl.glEnable(GL2.GL_DEPTH_TEST); // Enables depth-buffer for hidden
                                                                                // surface removal
                gl.glDepthFunc(GL2.GL_LEQUAL); // The type of depth testing to do
                gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);   // nice perspective view, avoid texture distortion.
                gl.glShadeModel(GL2.GL_SMOOTH); // Enable smooth shading of color
                gl.glDisable(GL2.GL_DITHER); // Disable dithering for better performance

                // sky color background
                gl.glClearColor(0.17f, 0.65f, 0.92f, 0.0f);
                gl.glEnable(GL2.GL_CULL_FACE);
               
               
                // Set up the lighting for Light-1
              // Ambient light does not come from a particular direction. Need some ambient
              // light to light up the scene. Ambient's value in RGBA
              float[] lightAmbientValue = {0.5f, 0.5f, 0.5f, 1.0f};
              // Diffuse light comes from a particular location. Diffuse's value in RGBA
              float[] lightDiffuseValue = {1.0f, 1.0f, 1.0f, 1.0f};
              // Diffuse light location xyz (in front of the screen).
              float lightDiffusePosition[] = {0.0f, 0.0f, 2.0f, 1.0f};

              gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_AMBIENT, lightAmbientValue, 0);
              gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, lightDiffuseValue, 0);
              gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, lightDiffusePosition, 0);
              gl.glEnable(GL2.GL_LIGHT1); // Enable Light-1
              gl.glEnable(GL2.GL_LIGHTING);
               
             
              gl.glEnable(GL2.GL_COLOR_MATERIAL); // Enable light for colors
               

                loadTexture(file, gl); // for the billboard

                // Align textures to edges
                for (count = ZERO; count < NUMTEXTURES; count++) {
                        tc[count] = tex[count].getImageTexCoords();
                }

        }

        private void loadTexture(String[] fnm, GL2 gl) {

                for (count = ZERO; count < NUMTEXTURES; count++) {
                        fileName[count] = folder + fnm[count];

                        try {
                                tex[count] = TextureIO.newTexture(
                                                cl.getResource(fileName[count]), false, null);

                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_MIN_FILTER,
                                                GL2.GL_NEAREST);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_MAG_FILTER,
                                                GL2.GL_NEAREST);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_WRAP_S,
                                                GL2.GL_REPEAT);
                                tex[count].setTexParameterf(gl, GL2.GL_TEXTURE_WRAP_T,
                                                GL2.GL_REPEAT);

                        } catch (Exception e) {
                                System.out.println("Error loading texture " + fileName[count]);
                        }

                }
        }
        @Override
        public void dispose(GLAutoDrawable drawable)
        {
                // TODO Auto-generated method stub
               
        }

        @Override
        public void display(GLAutoDrawable drawable)
        {
                GL2 gl = drawable.getGL().getGL2(); // Initialize the variable GL

                /*
                 * By default, OpenGL enables features that improve quality but reduce
                 * performance. One might want to tweak that especially on software
                 * renderer.
                 */
                gl.glDisable(GL2.GL_DITHER);

                // >>
                gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);

                /*
                 * Usually, the first thing one might want to do is to clear the screen.
                 * The most efficient way of doing this is to use glClear().
                 */

                gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

                /*
                 * Now we're ready to draw some 3D objects
                 */

                gl.glMatrixMode(GL2.GL_MODELVIEW);
                gl.glLoadIdentity();
                gl.glTranslatef(0, 0, -5.2f);

                gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
                gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
                gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
               
                // Display
                mTexBufferDisplay[0].put(tc[0].left()); // x or s
                mTexBufferDisplay[0].put(3); // y or t

                mTexBufferDisplay[0].put(3); // x or s
                mTexBufferDisplay[0].put(3); // y or t

                mTexBufferDisplay[0].put(3); // x or s
                mTexBufferDisplay[0].put(tc[0].top()); // y or t

                mTexBufferDisplay[0].put(tc[0].left()); // x or s
                mTexBufferDisplay[0].put(tc[0].top()); // y or t

                mTexBufferDisplay[0].position(0);
               
                gl.glActiveTexture(GL2.GL_TEXTURE0);
                gl.glEnable(GL2.GL_TEXTURE_2D);
                // do not draw the transparent parts of the texture
                gl.glEnable(GL2.GL_BLEND);
                gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
                // don't show source alpha parts in the destination
                // determine which areas of the polygon are to be rendered
                gl.glEnable(GL2.GL_ALPHA_TEST);
                gl.glAlphaFunc(GL2.GL_GREATER, 0); // only render if alpha > 0
               
                // Display
                for (acc = ZERO; acc < NUM_CUBES_DISPLAY; acc++)
                {
                        tex[0].bind(gl);


                        gl.glPushMatrix();

                        // Transformations
                        if (rotateXDisplay[acc] != 0)
                                gl.glRotatef(rotateXDisplay[acc], activeXDisplay[acc], 0, 0);
                        if (rotateYDisplay[acc] != 0)
                                gl.glRotatef(rotateYDisplay[acc], 0, activeYDisplay[acc], 0);
                        if (rotateZDisplay[acc] != 0)
                                gl.glRotatef(rotateZDisplay[acc], 0, 0, activeZDisplay[acc]);

                        gl.glScalef(scaleXDisplay[acc] + one, scaleYDisplay[acc] + one,
                                        scaleZDisplay[acc] + one);

                        gl.glTranslatef(translateXDisplay[acc], 0, 0);
                        gl.glTranslatef(0, translateYDisplay[acc], 0);
                        gl.glTranslatef(0, 0, translateZDisplay[acc]);

                        gl.glFrontFace(GL2.GL_CCW);
                        gl.glVertexPointer(3, GL2.GL_FLOAT, 0, mVertexBufferDisplay[acc]);
                        gl.glEnable(GL2.GL_TEXTURE_2D);
                        gl.glColorPointer(4, GL2.GL_FLOAT, 0, mColorBufferDisplay[acc]);
                        gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, mTexBufferDisplay[0]);
                        gl.glDrawElements(GL2.GL_TRIANGLES, cubeFillerIDisplay.length,
                                        GL2.GL_UNSIGNED_BYTE, mIndexBufferDisplay[acc]);

                        // Transformations
                        if (rotateXDisplay[acc] != 0)
                                gl.glRotatef(-1 * rotateXDisplay[acc], activeXDisplay[acc], 0, 0);
                        if (rotateYDisplay[acc] != 0)
                                gl.glRotatef(-1 * rotateYDisplay[acc], 0, activeYDisplay[acc], 0);
                        if (rotateZDisplay[acc] != 0)
                                gl.glRotatef(-1 * rotateZDisplay[acc], 0, 0, activeZDisplay[acc]);

                        gl.glScalef(-1 * scaleXDisplay[acc] + one, -1 * scaleYDisplay[acc]
                                        + one, -1 * scaleZDisplay[acc] + one);

                        gl.glTranslatef(-1 * translateXDisplay[acc], 0, 0);
                        gl.glTranslatef(0, -1 * translateYDisplay[acc], 0);
                        gl.glTranslatef(0, 0, -1 * translateZDisplay[acc]);

                        gl.glPopMatrix();

                }

               
        }

        public void reshape(GLAutoDrawable drawable, int x, int y, int width,
                        int height) {
                GL2 gl = drawable.getGL().getGL2(); // Initialize the variable GL

                if (height == 0) {
                        height = 1; // to avoid division by 0 in aspect ratio below
                }

                float ratio = (float) width / height;

                gl.glViewport(0, 0, width, height);

                /*
                 * Set our projection matrix. This doesn't have to be done each time we
                 * draw, but usually a new projection needs to be set when the viewport
                 * is resized.
                 */

                gl.glMatrixMode(GL2.GL_PROJECTION);
                gl.glLoadIdentity();
                gl.glFrustum(-ratio, ratio, -1, 1, 1, 300);

        }

}

Any ideas, anybody?
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2 Texture GL_REPEAT Question.

gouessej
Administrator
In reply to this post by Pixelapp
Hi

There is no bug in JOGL 2.0 in these features, I use some of them in my mesh optimizer.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2 Texture GL_REPEAT Question.

Pixelapp
So how come I get those results? That's not a response!
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2 Texture GL_REPEAT Question.

Pixelapp
Can someone at least give me a code (20 lines or so) with a GL_REPEAT texture displaying correctly on a square? I would be able to take it from there.

Does anyone has GL_REPEAT code?

Thanks in advance.