Texture loading bug

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

Texture loading bug

ElJojo
Hi,
I'm stuck since few days with texture loading :
        try{
            TextureData pict = TextureIO.newTextureData(GLProfile.getGL2GL3(),
                    new File(texChemin+"picture.jpg"),GL2GL3.GL_RGBA,GL2GL3.GL_RGBA,false,"jpg");
            ByteBuffer pictData=ByteBuffer.allocate(4*pict.getWidth()*pict.getHeight());
            System.out.println(pictData.capacity()+" "+pict.getBuffer().capacity());
            pictData=(ByteBuffer) pict.getBuffer();
            gl.glActiveTexture(GL2GL3.GL_TEXTURE0);
            int[] texID=new int[1];
            gl.glGenTextures(1, texID, 0);
            gl.glBindTexture(GL2GL3.GL_TEXTURE_2D, texID[0]);
            gl.glTexParameterf(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MAG_FILTER, GL2GL3.GL_LINEAR);
            gl.glTexParameterf(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MIN_FILTER, GL2GL3.GL_LINEAR);
            gl.glTexImage2D(GL2GL3.GL_TEXTURE_2D, 0, GL2GL3.GL_RGBA, pict.getWidth(), 
                    pict.getHeight(), 0, GL2GL3.GL_RGBA, GL2GL3.GL_UNSIGNED_BYTE, pictData);
            int loc=gl.glGetUniformLocation(programHandle, "Tex1");
            if(loc>=0) {
                gl.glUniform1i(loc, 0);
            }else{
                System.err.println("Uniform variable Tex1 not found! "+loc);
            }
        }catch(IOException exc) { }
My jpeg is 1920x1080 resolution.
I obtain this error : "java.lang.IndexOutOfBoundsException: Required 8294400 remaining bytes in buffer, only had 6220800"
on the glTexImage2D line.
Thanks for your "lights".
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
Hi

1920x1080*3 = 6220800

Rather use RGB and a smaller byte buffer.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

ElJojo
ok for the RGB but I need RGBA because final user will be able to use png or tga files with(or not) alpha channel and I don't want to lost CPU time and code to detect format.
That's why I load TextureData precising the pixelformat.
I don't understand why it's working in C as I saw example in the "OpenGL 4.0 Shading Language cookbook" (page 107)
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
JPEG does not handle alpha. If you need an alpha channel, you have to modify the texture data before passing them to OpenGL. I assume the example in this book uses an image with an alpha channel.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
In reply to this post by ElJojo
Why not using TextureData.getBuffer()?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
In reply to this post by ElJojo
You should use getInternalFormat() too.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

ElJojo
In reply to this post by gouessej
I know that jpeg doesn't have alpha channel (it's part of my job!) and this is the code in this book :
// Load texture file
const char * texName = "texture/brick1.jpg";
QImage timg =
QGLWidget::convertToGLFormat(QImage(texName,"JPG"));
// Copy file to OpenGL
glActiveTexture(GL_TEXTURE0);
GLuint tid;
glGenTextures(1, &tid);
glBindTexture(GL_TEXTURE_2D, tid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, timg.width(),
timg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, timg.bits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Set the Tex1 sampler uniform to refer to texture unit 
int loc = glGetUniformLocation(programHandle, "Tex1");
if( loc >= 0 )
   glUniform1i(loc, 0);
else
   fprintf(stderr, "Uniform variable Tex1 not found!\n");
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

ElJojo
I tried "pict.getBuffer()" =>same issue because there's no change in size.
I tried "getInternalFormat()" and it's working when I remove GL2GL3.RGBA in the "newTextureData"
Now result is a black Quad : probably a problem with TexCoord...
Do you know how I could crop texture ? I think working with GL_RECTANGLE_ARB instead of GL_TEXTURE2D; is it a good way ?
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
In reply to this post by ElJojo
The conversion of your example probably always returns data with an alpha channel.

Use getBuffer() in order to avoid creating another buffer.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
Do you want to crop texture data or use only a part of the texture?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

ElJojo
I want to show a part of a texture.
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
Why not simply modifying the texture coordinates? You can also use the standard Java APIs to crop an image.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

gouessej
Administrator
In reply to this post by ElJojo
Is that good for you?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Texture loading bug

ElJojo
Thank you for your help.
I want to limit buffer conversions and I need ByteBuffer for one use so I will try with texture coordinates in the vertex shader first.