Texture NPOT

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

Texture NPOT

paolofuse
Hi all,
I have a problem with NPOT texture.

Texture texture = TextureIO.newTexture(new File(filename), true);

This code works with POT and NPOT textures:

gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glBindTexture(GL2.GL_TEXTURE_2D, texture.getTextureObject());
gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2d(0, 0);
gl.glVertex2d(0, 0);
gl.glTexCoord2d(1, 0);
gl.glVertex2d(texture.getWidth(), 0);
gl.glTexCoord2d(1, 1);
gl.glVertex2d(texture.getWidth(), texture.getHeight());
gl.glTexCoord2d(0, 1);
gl.glVertex2d(0, texture.getHeight());
gl.glEnd();
gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

This code works only with POT textures:

texture.enable(gl);
texture.bind(gl);
gl.glBegin(GL2.GL_QUADS);
gl.glTexCoord2d(0, 0);
gl.glVertex2d(0, 0);
gl.glTexCoord2d(1, 0);
gl.glVertex2d(texture.getWidth(), 0);
gl.glTexCoord2d(1, 1);
gl.glVertex2d(texture.getWidth(), texture.getHeight());
gl.glTexCoord2d(0, 1);
gl.glVertex2d(0, texture.getHeight());
gl.glEnd();
texture.disable(gl);

I need to use the last code with NPOT textures.
I'm working on a Mac Book Pro with OSX 10.10.5 and an AMD Radeon HD 6490M video card.

Any suggestion?
Thanks in advance.
paolofuse
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

elect
I'd suggest you to avoid deprecated OpenGL
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
Which part of my code is deprecated?
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

elect
This post was updated on .
In reply to this post by elect
paolofuse wrote
Which part of my code is deprecated?
Everything except glBindTexture :s

You should do something similar nowadays

With a 6490m you should have nicely available OpenGL core 4.1
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
Well, ok, I know this. I just wrote a simple test to show a texture. Using VBO the problem still remains.
To do the code work I must do:

TextureData textureData = TextureIO.newTextureData(gl.getGLProfile(), new File(filename), false, null);
IntBuffer buffer = IntBuffer.allocate(1);
gl.glGenTextures(1, buffer);
int textureID = buffer.get(0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, textureData.getPixelFormat(), textureData.getWidth(), textureData.getHeight(), 0, GL2.GL_RGBA, textureData.getPixelType(), textureData.getBuffer());
gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

And then the past code works.
But why I cannot use simply Texture object?
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

elect
paolofuse wrote
Well, ok, I know this. I just wrote a simple test to show a texture. Using VBO the problem still remains.
To do the code work I must do:

TextureData textureData = TextureIO.newTextureData(gl.getGLProfile(), new File(filename), false, null);
IntBuffer buffer = IntBuffer.allocate(1);
gl.glGenTextures(1, buffer);
int textureID = buffer.get(0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, textureData.getPixelFormat(), textureData.getWidth(), textureData.getHeight(), 0, GL2.GL_RGBA, textureData.getPixelType(), textureData.getBuffer());
gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

And then the past code works.
But why I cannot use simply Texture object?
There could be many reasons why it doesnt work as expected, may I see the full code?

You can use the texture object, but you should know what it does in the background, I'd discuss about it after the code, let's see first which are the problems at the begin
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
This is my simple full code:

private Texture texture;
private int textureID;

public void init(GLAutoDrawable drawable)
{
     try
    {
           texture = TextureIO.newTexture(new File(filename), true);

//           TextureData textureData = TextureIO.newTextureData(gl.getGLProfile(), new File(filename), false, null);
//           IntBuffer buffer = IntBuffer.allocate(1);
//           gl.glGenTextures(1, buffer);
//           textureID = buffer.get(0);
//           gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID);
//           gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
//           gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
//           gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, textureData.getPixelFormat(), textureData.getWidth(), textureData.getHeight(), 0, GL2.GL_RGBA, textureData.getPixelType(), textureData.getBuffer());
//           gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
    }
    catch (Exception e)
    {
          e.printStackTrace();
     }
}

public void display(GLAutoDrawable drawable)
{
    GL2 gl = drawable.getGL().getGL2();
    gl.glClearColor(0f, 0f, 0f, 1f);
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

    texture.enable(gl);
    texture.bind(gl);
    texture.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
    texture.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);

//    gl.glEnable(GL2.GL_TEXTURE_2D);
//    gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID);

    gl.glBegin(GL2.GL_QUADS);
    gl.glTexCoord2d(0, 0);
    gl.glVertex2d(0, 0);
    gl.glTexCoord2d(1, 0);
    gl.glVertex2d(texture.getWidth(), 0);
    gl.glTexCoord2d(1, 1);
    gl.glVertex2d(texture.getWidth(), texture.getHeight());
    gl.glTexCoord2d(0, 1);
    gl.glVertex2d(0, texture.getHeight());
    gl.glEnd();

// gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);

    texture.disable(gl);
}

public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
    GL2 gl = drawable.getGL().getGL2();
    gl.glMatrixMode(GL2.GL_PROJECTION );
    gl.glLoadIdentity();
    gl.glOrtho(0, width, 0, height, -1, 1);
    gl.glMatrixMode(GL2.GL_MODELVIEW );
    gl.glLoadIdentity();
}

public void dispose(GLAutoDrawable drawable)
{
}


Don't care if this code is deprecated, I know, but it must work. The commented code works, as wrote before.
Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

elect
Your code relies fully on the old OpenGL

paolofuse wrote
Don't care if this code is deprecated, I know, but it must work. The commented code works, as wrote before.
Thanks
This is the wrong way of thinking, read this why you shouldn't use anymore fixed function pipeline OpenGL.
I would like you to understand your code, because if you do understand it, you can debug it, you can enhance it, you can modify it based on your needs and starting implementing from that.

If you don't understand what does what exactly, as soon as you modify something and it doesn't work anymore, you will be back here.

I can help you, I can write an Hello Texture for you if you want and explain all the passages
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
Ok. Usually I use VBO, FBO and so on, but I want to understand why, with this simple code, taken from the official demo
(https://github.com/sgothel/jogl-demos/blob/master/src/demos/texture/TestTexture.java) I can display only POT texture.

texture.enable(gl);
texture.bind(gl);
gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
TextureCoords coords = texture.getImageTexCoords();

 gl.glBegin(GL2.GL_QUADS);
 gl.glTexCoord2f(coords.left(), coords.bottom());
 gl.glVertex2f(0, 0);
 gl.glTexCoord2f(coords.right(), coords.bottom());
 gl.glVertex2f(1, 0);
 gl.glTexCoord2f(coords.right(), coords.top());
 gl.glVertex2f(1, 1);
 gl.glTexCoord2f(coords.left(), coords.top());
 gl.glVertex2f(0, 1);
 gl.glEnd();
 texture.disable(gl);

If I want to test a feature I use the simplest code possible. And this from demo is that.
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
I post another test with no deprecated/obsolete code:

private Texture texture;
private int[] vexVBO, texVBO;

public void init(GLAutoDrawable drawable)
{
       GL2 gl = drawable.getGL().getGL2();

       try
                {
                        texture = TextureIO.newTexture(new File(filename), true);
                       
                        FloatBuffer vex = Buffers.newDirectFloatBuffer(new float[]{
                            0.0f, 0.0f, 0.0f,
                            texture.getWidth(), 0.0f, 0.0f,
                            texture.getWidth(), texture.getHeight(), 0.0f,
                            0.0f, texture.getHeight(), 0.0f
                        });
                        FloatBuffer tex = Buffers.newDirectFloatBuffer(new float[]{
                            0.0f, 0.0f,
                            1.0f, 0.0f,
                            1.0f, 1.0f,
                            0.0f, 1.0f
                        });
                       
                        vexVBO = new int[1];
                        gl.glGenBuffers(1, vexVBO, 0);
                        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vexVBO[0]);
                        gl.glBufferData(GL2.GL_ARRAY_BUFFER, numVex * 3 * Buffers.SIZEOF_FLOAT, vex, GL2.GL_STATIC_DRAW);
                       
                        texVBO = new int[1];
                        gl.glGenBuffers(1, texVBO, 0);
                        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
                        gl.glBufferData(GL2.GL_ARRAY_BUFFER, numVex * 2 * Buffers.SIZEOF_FLOAT, tex, GL2.GL_STATIC_DRAW);
                }
                catch (Exception e)
                {
                        e.printStackTrace();
                }
}

public void display(GLAutoDrawable drawable)
{
        GL2 gl = drawable.getGL().getGL2();
        gl.glClearColor(1f, 1f, 1f, 1f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        texture.enable(gl);
        texture.bind(gl);
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vexVBO[0]);
        gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0l);
        gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
        gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, 0l);
        gl.glDrawArrays(GL2.GL_TRIANGLE_FAN, 0, 4);
        texture.disable(gl);
}

Again this works only with POT textures.
Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

gouessej
Administrator
In reply to this post by paolofuse
Hi

Please call GLBase.isNPOTTextureAvailable(), it should return true. Otherwise, it's a bug and it would explain why the code only works with POT textures.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

gouessej
Administrator
In reply to this post by paolofuse
You have to call GL.glEnable(GL2.GL_TEXTURE_RECTANGLE_ARB), or you can use GL_ARB_texture_non_power_of_two:
http://stackoverflow.com/a/11363905

You should have read the documentation:
" Further more, GL_ARB_texture_rectangle (RECT) will be attempted on OSX w/ ATI drivers. If NPOT is not available or RECT not chosen, the Texture class will simply upload a non-pow2-sized image into a standard pow2-sized texture (without any special scaling)."
http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/util/texture/Texture.html
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

elect
In reply to this post by paolofuse
paolofuse wrote
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0l);
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, 0l);

Again this works only with POT textures.
Thanks.
These calls are still deprecated..

In modern OpenGL you decide what your data represents, either vertex position, normal, color, texture coordinates or whatever.

I'll write a small example. Just tell me which kind of image are you uploading
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
In reply to this post by gouessej
I read the documentation.
The documentation says that the Texture class with texture.enable(gl) should call gl.glEnable(GL2. GL_TEXTURE_RECTANGLE_ARB), or I misunderstood?
However if I call manually gl.glEnable(GL2.GL_TEXTURE_RECTANGLE_ARB) it doesn't work. This is the code:

public void display(GLAutoDrawable drawable)
{
        GL2 gl = drawable.getGL().getGL2();
        gl.glClearColor(1f, 1f, 1f, 1f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        gl.glEnable(GL2.GL_TEXTURE_RECTANGLE_ARB);
        gl.glBind(GL2.GL_TEXTURE_RECTANGLE_ARB, texture.getTextureOjbect());
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vexVBO[0]);
        gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0l);
        gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
        gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, 0l);
        gl.glDrawArrays(GL2.GL_TRIANGLE_FAN, 0, 4);
        gl.glDisable(GL2.GL_TEXTURE_RECTANGLE_ARB);
}

The other solution is to use GL_ARB_texture_non_power_of_two, but I cannot find any example about it.
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
In reply to this post by elect
elect I'm uploading a PNG image. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

gouessej
Administrator
In reply to this post by paolofuse
You misunderstood the documentation. Please call GLBase.isNPOTTextureAvailable(), I need to know if your problem is caused by a JOGL bug. You must enable this extension before creating the texture.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
GLBase.isNPOTTextureAvailable() return true. How can I enable this extension?
Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

gouessej
Administrator
Call gl.glEnable(GL2.GL_TEXTURE_RECTANGLE_ARB) before calling TextureIO.newTexture().
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

paolofuse
private Texture texture;
private int[] vexVBO, texVBO;

public void init(GLAutoDrawable drawable)
{
       GL2 gl = drawable.getGL().getGL2();

       try
                {
                        // enable GL_TEXTURE_RECTANGLE_ARB
                        gl.glEnable(GL2.GL_TEXTURE_RECTANGLE_ARB);

                        texture = TextureIO.newTexture(new File(filename), true);
                       
                        FloatBuffer vex = Buffers.newDirectFloatBuffer(new float[]{
                            0.0f, 0.0f, 0.0f,
                            texture.getWidth(), 0.0f, 0.0f,
                            texture.getWidth(), texture.getHeight(), 0.0f,
                            0.0f, texture.getHeight(), 0.0f
                        });
                        FloatBuffer tex = Buffers.newDirectFloatBuffer(new float[]{
                            0.0f, 0.0f,
                            1.0f, 0.0f,
                            1.0f, 1.0f,
                            0.0f, 1.0f
                        });
                       
                        vexVBO = new int[1];
                        gl.glGenBuffers(1, vexVBO, 0);
                        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vexVBO[0]);
                        gl.glBufferData(GL2.GL_ARRAY_BUFFER, numVex * 3 * Buffers.SIZEOF_FLOAT, vex, GL2.GL_STATIC_DRAW);
                       
                        texVBO = new int[1];
                        gl.glGenBuffers(1, texVBO, 0);
                        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
                        gl.glBufferData(GL2.GL_ARRAY_BUFFER, numVex * 2 * Buffers.SIZEOF_FLOAT, tex, GL2.GL_STATIC_DRAW);
                }
                catch (Exception e)
                {
                        e.printStackTrace();
                }
}

public void display(GLAutoDrawable drawable)
{
        GL2 gl = drawable.getGL().getGL2();
        gl.glClearColor(1f, 1f, 1f, 1f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        texture.enable(gl);
        texture.bind(gl);
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vexVBO[0]);
        gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0l);
        gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, texVBO[0]);
        gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, 0l);
        gl.glDrawArrays(GL2.GL_TRIANGLE_FAN, 0, 4);
        texture.disable(gl);
}

Enabling GL_TEXTURE_RECTANGLE_ARB makes no work both POT and NPOT textures.
Reply | Threaded
Open this post in threaded view
|

Re: Texture NPOT

gouessej
Administrator
Please fill a bug report, provide the image file you use and mention this test https://github.com/sgothel/jogl-demos/blob/master/src/demos/texture/TestTexture.java. Don't forget to mention the configuration of your machine, the version of Java, ...
Julien Gouesse | Personal blog | Website
12