【问题标题】:LWJGL Why does my geometry sometimes render incorrectly?LWJGL 为什么我的几何图形有时渲染不正确?
【发布时间】:2017-07-24 20:01:44
【问题描述】:

我使用 LWJGL 和 GLFW 在 java 中制作了一个简单的 opengl 应用程序。 我创建了一个用于渲染纹理框的类。它创建顶点位置、纹理坐标,并使用 VBO。该框使用GL_TRIANGLES 渲染。 当我启动程序进行测试时,有时: - 输出正确,我看到正确渲染的框。 - 有一个非常大的、奇怪的(白色/灰色)三角形从盒子里伸出来。 - 盒子完全变形了,就像有很多完全随机的三角形。

当我不更改任何代码时,每次结果仍然不同。但有时框 渲染正确。

我很确定我的顶点纹理坐标是正确的。 很难找出问题所在。我重新创建了 box 类,因此它使用GL_QUADS 渲染它(当然还重新考虑了顶点/纹理坐标)。 但后来我仍然得到同样的奇怪行为。

难的是每次程序运行的结果都不一样,而代码没有被编辑。

这里有一些图片,其中一张完全正确:

现在我再次运行程序,我得到了这个:

等等……

有人知道会发生什么吗? 这就是我渲染盒子的方式:

texture.bind();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

glBindBuffer(GL_ARRAY_BUFFER, vboId);
glVertexPointer(3, GL_FLOAT, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, texId);
glTexCoordPointer(2, GL_FLOAT, 0, 0);

glDrawArrays(GL_TRIANGLES, 0, vertices.length);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

Texture.unbind();

如果有人知道导致结果变化的原因,它已经可以提供帮助。

我的盒子类的代码:

package shapes;

import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_COORD_ARRAY;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY;
import static org.lwjgl.opengl.GL11.glDisable;
import static org.lwjgl.opengl.GL11.glDisableClientState;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL11.glTexCoordPointer;
import static org.lwjgl.opengl.GL11.glVertexPointer;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL15.glBindBuffer;
import static org.lwjgl.opengl.GL15.glBufferData;
import static org.lwjgl.opengl.GL15.glGenBuffers;

import java.nio.FloatBuffer;

import main.Geometry;

import org.lwjgl.BufferUtils;

import textures.Texture;

public class TriangleBox extends Geometry {

    private float sizeX;
    private float sizeY;
    private float sizeZ;

    private short[] indices;
    private float[] texCoords;

    private int vboId;
    private int texId;
    private int indId;

    private Texture texture;

    /**
     * Creates a beam figure (a bar)
     * 
     * @param widthX
     * @param heightY
     * @param depthZ
     */
    public TriangleBox(float widthX, float heightY, float depthZ, Texture tex) {

        this.sizeX = widthX;
        this.sizeY = heightY;
        this.sizeZ = depthZ;

        this.setTexture(tex);
        this.createVertices();
        this.createVBO();
    }

    public void setTexture(Texture tex) {

        this.texture = tex;
    }

    protected void createVertices() {

        vertices = new float[] { 
                //Bottom
                0, 0, 0,    
                1, 0, 0,    
                0, 0, 1,    

                0, 0, 1,    
                1, 0, 0,    
                1, 0, 1,    

                //Top
                0, 1, 0,    
                1, 1, 0,    
                0, 1, 1,    

                0, 1, 1,    
                1, 1, 0,    
                1, 1, 1,    

                //Front
                0, 1, 1,    
                1, 1, 1,    
                0, 0, 1,    

                0, 0, 1,    
                1, 1, 1,    
                1, 0, 1,    

                //Back
                1, 1, 0,    
                0, 1, 0,    
                1, 0, 0,    

                1, 0, 0,    
                0, 1, 0,    
                0, 0, 0,    

                //Left
                0, 1, 0,    
                0, 1, 1,    
                0, 0, 0,    

                0, 0, 0,    
                0, 1, 1,
                0, 0, 1,

                //Right
                1, 1, 1,
                1, 1, 0,
                1, 0, 1,

                1, 0, 1,
                1, 1, 0,
                1, 0, 0,
        };

        texCoords = new float[] { 
                // Bottom
                0f,     .33f,
                .25f,   .33f,
                0f,     .66f,

                0f,     .66f,
                .25f,   .33f,
                .25f,   .66f,

                // Top
                .75f,   .33f,
                .50f,   .33f,
                .75f,   .66f,

                .75f,   .66f,
                .50f,   .33f,
                .50f,   .66f,

                // Front  
                0f,     1f  ,
                .25f,   1f  ,
                0f,     .66f,

                0f,     .66f,
                .25f,   1f  ,
                .25f,   .66f,

                // Back
                .25f,   0f  ,
                0f,     0f  ,
                .25f,   .33f,

                .25f,   .33f,
                0f,     0f  ,
                0f,     .33f,

                // Left
                .75f,   .33f,
                .75f,   .66f,
                1f,     .33f,

                1f,     .33f,
                .75f,   .66f,
                1f,     .66f,

                // Right
                .50f,   .66f,
                .50f,   .33f,
                .25f,   .66f,

                .25f,   .66f,
                .50f,   .33f,
                .25f,   .33f
        };
    }

    public void createVBO() {

        FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertices.length);
        vertexBuffer.put(vertices);
        vertexBuffer.flip();

        FloatBuffer texCoordBuffer = BufferUtils.createFloatBuffer(texCoords.length);
        texCoordBuffer.put(texCoords);
        texCoordBuffer.flip();

        vboId = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);

        texId = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, texId);
        glBufferData(GL_ARRAY_BUFFER, texCoordBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    public void render() {

        texture.bind();

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnable(GL_TEXTURE_2D);

        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, texId);
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        glDrawArrays(GL_TRIANGLES, 0, vertices.length);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisable(GL_TEXTURE_2D);

        Texture.unbind();
    }
}

顶点着色器:

#version 120

attribute vec3 position;

void main() {

    gl_Position = vec4(position.x, position.y, position.z, 1.0);
}

片段着色器

#version 120

void main() {

    gl_FragColor = gl_Color; //vec4(0.1, 1.0, 1.0, 1.0);
}

【问题讨论】:

  • 你有 texture.bind() 和 Texture.unbind(),这意味着你在两个不同的事情上调用这些方法。应该是这样吗?
  • @BillHorvathII 是的,应该是这样的。
  • 听起来好像没有初始化。正如 Rabbid76 所问的那样,您能在设置视图和投影的位置显示代码吗?
  • 现在我添加了 Box 类的代码。当然我不希望人们检查所有顶点/纹理坐标...
  • 我用来翻转盒子的代码被删除了,它只是在游戏循环中的一行glRotatef(),可以看到盒子的四面八方。现在我只有一个游戏循环,它每帧调用 box.render()。

标签: java debugging opengl rendering lwjgl


【解决方案1】:

由于在图片中您从不同角度展示了盒子,我最好的猜测仍然是,顶点有问题。所以也许你每次运行它都没有得到不同的结果,但实际上只是从不同的角度看到相同的结果,这使得物体因为面部剔除或其他原因看起来不同。

尝试渲染一个四边形(更容易确定正确的顶点),看看是否仍然得到相同的结果。

【讨论】:

  • 我更改了代码,所以它不会扭转局面,但每次运行仍然有另一个结果。渲染单个四边形或三角形时,没有(可见的)问题。如果顶点有问题,那么每次运行的结果至少都是一样的。
  • 是的。好吧,在这个阶段,我假设屏幕上渲染的每个对象都是由顶点定义的。因此,如果出现一些奇怪的东西,这意味着有不合适的顶点。假设您在定义四边形时正确地设置了它们,并且假设您没有故意在着色器中更改它们,那么我能想到的唯一其他操作顶点的地方是在变换和投影它们时。因此,正如 Rappid 指出的那样,查看您的投影和转换代码会很有帮助。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 2014-10-06
  • 2016-06-21
相关资源
最近更新 更多