Reputation: 643
First, I'll start with my code because I've identified which block is causing the issue.
// init
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// BEGINNING OF OFFENDING CODE
BufferedImage image = ImageIO.read(new File("res/button.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
IntBuffer buffer = BufferUtils.createIntBuffer(pixels.length);
for (int pixel : pixels)
buffer.put(pixel);
buffer.flip();
int button = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
//Setup wrap mode
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_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
// END OF OFFENDING CODE
I can't seem to figure out which GL11 call is affecting the rest of the Display and why it would be affecting the rest of the display. From what I understand, all of the calls that follow GL11.glBindTexture
are limited to the bound texture, aren't they?
private static void renderQuad(int x, int y, int width, int height) {
GL11.glPushMatrix();
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x, y);
GL11.glVertex2f(x + width, y);
GL11.glVertex2f(x + width, y + height);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
}
The method used for the red quads.
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
// render textured quad
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
Upvotes: 0
Views: 129
Reputation: 585
First of all, I think there's a problem with your texture loading. I believe the order of the bytes is reversed or something similar, which is why you get the red on black. Here's a working load-texture-from-BufferedImage example taken from my own code:
BufferedImage image = ImageIO.read(new File("<file path>.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
for(int y = 0; y < image.getHeight(); y++){
for(int x = 0; x < image.getWidth(); x++){
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// 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:
int textureID = GL11.glGenTextures(); //Generate texture ID
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
//Send texel data to OpenGL
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
Now, to the actual rendering problem:
For OpenGL, GL_TEXTURE_2D must be enabled or disabled depending on whether or not the polygon you are drawing is textured. If you do not supply texture coordinates for each vertex, then the last texture coords call still holds and is used for each vertex. So, you'll get a quad using one pixel's worth of texture. This is what's causing the black quads - it's taking from one pixel from a corner of your improperly loaded texture. So, your fixed rendering code:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// render textured quad
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
On a side note, you can use simply glEnable() instead of GL11.glEnable() if you do:
import static org.lwjgl.opengl.GL11.*;
instead of simply
import org.lwjgl.opengl.GL11;
Upvotes: 1