gpt4 book ai didi

java - OpenGL绘图纹理错误

转载 作者:行者123 更新时间:2023-11-29 04:17:23 25 4
gpt4 key购买 nike

我正在使用 LWJGL 并尝试绘制纹理,其渲染代码如下:

public static void main(String[] args) {
GLFWErrorCallback.createPrint(System.err).set();
if (!GLFW.glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE);
window = GLFW.glfwCreateWindow(1280, 720, "Test", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 1280, 0, 720, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glViewport(0, 0, 1920, 1200);
GL11.glClearColor(1.0F, 1.0F, 1.0F, 1.0F);
int x = 0, y = 0;
ByteBuffer imageBuffer = readFile(filename);
IntBuffer w = BufferUtils.createIntBuffer(1);
IntBuffer h = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer image = STBImage.stbi_load_from_memory(imageBuffer, w, h, comp, 0);
int textureId = GL11.glGenTextures();
int glTarget = GL11.GL_TEXTURE_2D;
GL11.glBindTexture(glTarget, textureId);
glTexParameteri(glTarget, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(glTarget, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(glTarget, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
glTexParameteri(glTarget, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
int width = w.get(0);
int height = h.get(0);
/** Send texel data to OpenGL if texture is 2d texture */
if (glTarget == GL11.GL_TEXTURE_2D) {
if(comp.get(0) == 3){
GL11.glTexImage2D(glTarget, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, image);
}
else{
GL11.glTexImage2D(glTarget, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, image);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
}
while (Sgl.window.isAlive()) {
GLFW.glfwPollEvents();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
/* Texture display part */
bind();
GL11.glEnable(glTarget);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0,0);
GL11.glVertex2f(x,y);
GL11.glTexCoord2f(1,0);
GL11.glVertex2f(x+width,y);
GL11.glTexCoord2f(1,1);
GL11.glVertex2f(x+width,y+height);
GL11.glTexCoord2f(0,1);
GL11.glVertex2f(x,y+height);
GL11.glEnd();
GL11.glDisable(glTarget);
/*End texture display part*/
GLFW.glfwSwapBuffers(window);
}
}

问题是窗口是 1280x720 大而图像只有 392x69 但它显示如下:

enter image description here

所以,它是颠倒的,比预期的大得多,而且位置错误。

我做错了什么?

编辑:由于代码的大小,我删除了一些 if 子句。

最佳答案

一个一个地解决你的问题

1. So, it's upside down,

OpenGL 的纹理坐标(不仅是 GL,这通常适用于所有常见的渲染 API)的定义方式是原点将位于您在上传数据时指定的第一个像素。您的图像很可能是按照从左到右,从上到下的约定定义和加载的 - 因此您将分配 (0,0) texcoords 的顶点将显示图像的右上角。

现在,GL 的窗口空间是用数学约定定义的(至少默认情况下),原点在底部 左边。你看到了一些投影矩阵:

GL11.glOrtho(0, 1280, 0, 720, 1, -1);

这会将 x=0 映射到 x_ndc=-1 并将 x=1280 映射到 x_ndc=1 , y=0y_ndc=-1y=720y_ndc=1。 (它将映射刚刚相对于您指定的范围 [1,-1] 翻转的 z 坐标,因此 z=-1z_ndc=-1z=1z_ndc=1,但这与此处无关。)

NDC 是标准化设备坐标,其中(-1,-1) 是视口(viewport)的左下角,(1,1) 分别在右上角。

所以当你现在做的时候:

  GL11.glVertex2f(x,y); // NOTE: x and y are just 0 here
GL11.glTexCoord2f(1,0);

将应用上述转换,并且具有左上角纹素的顶点将最终出现在视口(viewport)的左下角。

2. much bigger than expected

您按如下方式设置视口(viewport)转换:

GL11.glViewport(0, 0, 1920, 1200);

现在,这只是定义了另一个转换,现在从 NDC 到窗口空间。只是 x_ndc=-1 映射到 x_win=0 x_ndc=1x_win=1920 并且 y 分别。

因此,输入坐标 (0,0) 映射到 NDC 中的 (-1,1),并进一步映射到 (0,0) 在窗口空间,它仍然是左下角。 (392,93) 将映射到 NDC 中的 ~(0.3,0.129) 和窗口空间中的 (588,115) - 这是一种方式比您的图片实际大。

它应该仍然适合您的窗口,但从屏幕截图来看,它似乎不适合。可能有几种解释:

  • 您的代码没有完全重现问题,

    I remove some if clauses due to size of the code.

    可能与此无关。

  • 您正在使用操作系统的某些“高 DPI 缩放比例”(如微软所说)或类似功能。您在 GLFW 中指定的窗口大小不是以像素为单位,而是以某些系统和平台特定的单位为单位。 GLFW提供means to query the actual pixel sizes ,您应该使用它来为窗口设置适当的视口(viewport)。
  • ...

3. and at the wrong position

这也是您的 OpenGL 坐标约定不匹配的结果。

4. What am I doing wrong?

您编写的代码使用了已弃用的 OpenGL。您现在依赖于 十年前 已弃用的固定功能管道。这些功能已从 OpenGL 的现代核心配置文件中完全删除。甚至在此之前,glBegin()/glEnd() 的即时模式渲染基本上在20 年前 就被顶点数组取代了。如果您现在正在学习 OpenGL,您真的应该尽量避免学习那些旧东西,并从干净的核心配置文件 OpenGL 上下文开始。

关于java - OpenGL绘图纹理错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51484274/

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