gpt4 book ai didi

java - Java OpenGL 中的纹理四边形问题

转载 作者:行者123 更新时间:2023-12-01 13:16:03 25 4
gpt4 key购买 nike

首先,我将从我的代码开始,因为我已经确定了哪个 block 导致了问题。

// 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

这就是没有纹理四边形的情况下的样子。

This is how things are supposed to look before the button.

这就是我使用有问题的代码(使用纹理四边形)进行渲染时发生的情况。

What I'm getting

这就是我使用有问题的代码(没有纹理四边形)进行渲染时发生的情况。

What I get when I comment out the code for the button

作为引用,这是纹理

What the button should look like

<小时/>

我似乎无法弄清楚哪个 GL11 调用正在影响显示器的其余部分以及为什么它会影响显示器的其余部分。据我了解,GL11.glBindTexture 之后的所有调用都仅限于绑定(bind)纹理,不是吗?

<小时/>

编辑:附加渲染代码

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();
}

用于红色四边形的方法。

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();

最佳答案

首先,我认为您的纹理加载存在问题。我相信字节的顺序是相反的或类似的,这就是为什么你会得到黑色的红色。这是一个取 self 自己的代码的有效 load-texture-from-BufferedImage 示例:

     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);

现在,讨论实际的渲染问题:

对于 OpenGL,必须启用或禁用 GL_TEXTURE_2D,具体取决于您正在绘制的多边形是否有纹理。如果您不为每个顶点提供纹理坐标,则最后一个纹理坐标调用仍然保留并用于每个顶点。因此,您将使用一个像素的纹理获得一个四边形。这就是导致黑色四边形的原因 - 它是从不正确加载的纹理的一角获取一个像素。所以,你的固定渲染代码:

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();

顺便说一句,如果您这样做,您可以简单地使用 glEnable() 而不是 GL11.glEnable():

import static org.lwjgl.opengl.GL11.*;

而不是简单地

import org.lwjgl.opengl.GL11;

关于java - Java OpenGL 中的纹理四边形问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22462309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com