How do I make DEGUG OpenGL a gray / black texture?

I am changing the code of another. They used PNGs which are loaded via BufferedImage. I need to download a TGA, and this is just an 18 byte header and BGR codes. I have textures loaded and running, but instead of a texture I get a gray window. I don't even know how to do it DEBUG.

The textures are loaded into the ByteBuffer:

final static int datasize = (WIDTH*HEIGHT*3) *2; // Double buffer size for OpenGL // not +18 no header
static ByteBuffer buffer = ByteBuffer.allocateDirect(datasize);

FileInputStream fin = new FileInputStream("/Volumes/RAMDisk/shot00021.tga");
FileChannel inc = fin.getChannel();

inc.position(18); // skip header

buffer.clear(); // prepare for read
int ret = inc.read(buffer);
fin.close();

      

I followed this: [how-to-manage-memory-with-texture-in-opengl] [1] ... because I update the texture once per frame, like a video.

Called once:

GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
assert(GL11.GL_NO_ERROR == GL11.glGetError());

      

Called again:

GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, width, height, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, byteBuffer);
assert(GL11.GL_NO_ERROR == GL11.glGetError());

return textureID;

      

The rendering code has not changed and is based on:

GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, this.vertexCount);

      

+3


source to share


4 answers


Thanks to Felix, without calling glTexSubImage2D (leaving the memory valid but uninitialized) I noticed a residual pattern left by default memory. This indicated that the texture was showing, but loading is most likely the problem.

** UPDATE:

The problem with the above code is essentially a buffer. The buffer is 1024 * 1024, but it is only partially filled with a read, leaving the limit

ByteBuffer marker at 2359296 (1024 * 768 * 3) instead of 3145728 (1024 * 1024 * 3). This gives an error:

Number of remaining buffer elements is must be ... at least ...

      

I thought OpenGL needed space to return data, so I doubled the buffer size. The buffer size is doubled to compensate for the error.



final static int datasize = (WIDTH*HEIGHT*3) *2; // Double buffer size for OpenGL // not +18 no header

      

This is wrong, needs a function flip()

(Big THANKS to Reto Koradi for a little hint to rewind the buffer) to put the ByteBuffer in read mode. Since the buffer is only half filled, checking the OpenGL buffer gives an error. The right thing to do is not to double the buffer size; use buffer.position(buffer.capacity())

to fill the buffer before doing flip()

.

final static int datasize = (WIDTH*HEIGHT*3); // not +18 no header

buffer.clear(); // prepare for read
int ret = inc.read(buffer);
fin.close();
buffer.position(buffer.capacity()); // make sure buffer is completely FILLED!
buffer.flip(); // flip buffer to read mode

      

To understand this, it is helpful to hard-code the buffer memory to make sure the OpenGL calls work, isolating the load issue. Then, when the OpenGL calls are correct, focus on loading the buffer. As Felix K suggested, it's good to make sure one texture has been drawn correctly before naming it glTexSubImage2D

multiple times.

+1


source


Make sure you set the texture sampling mode. Especially the minimal filter: glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR). The default is mip mapped (GL_NEAREST_MIPMAP_LINEAR), so if you don't load mip maps you will get a white read result.

So, either tweak the texture, or not mip, or generate them. One way to do this is to call glGenerateMipmap after calling tex img.

(see https://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexParameter.xml ).



This is a very common trap and something that people just know after being bitten a few times.

There is no easy way to debug things like this. There are good tools for debugging gl, for example in xcode, but they won't tell you about the case.

+2


source


Debugging GPU code is always a challenge. I would bet my money on a lot of industry progress in this area as more companies discover the power of the GPU. Until; I will share two of my best friends GPU debuggers:

1) Define a function to print OGL errors:

int printOglError(const char *file, int line)
{
    /* Returns 1 if an OpenGL error occurred, 0 otherwise. */
    GLenum glErr;
    int    retCode = 0;

    glErr = glGetError();
    while (glErr != GL_NO_ERROR) {
        printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    }
    return retCode;
}

#define printOpenGLError() printOglError(__FILE__, __LINE__)

      

And call it after your render draw calls (possible earlier errors will appear as well):

GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, this.vertexCount);
printOpenGLError();

      

This is a warning if you are doing some invalid operation (this may only be your case), but you usually need to find where the error occurs through trial and error.

2) Check out gDEBugger , a freeware with tons of information about GPU memory.

[Edit]: I would also recommend using the openource lib DevIL - it is quite competent at loading various image formats.

+2


source


Some ideas that might be causing the problem:

  • Your texture is located somewhere. I don't know the code of the hole, but I think there is somewhere glDeleteTextures

    and it might cause some problems when called at the wrong time.
  • Is the texture two? If not, this could be a problem depending on your hardware. Older hardware sometimes lacks support for the lack of power of two images .
  • Texture parameters changed between paint calls at some other point (debug parameters with glGetTexParameter )
  • Another assumption is that loading the next image (edit or even the first image) has a loading problem, check if the first image is displayed without loading the next images. If so, then it must be one of the above cases.
+1


source







All Articles