OpenGL-构造形状的困难

问题描述 投票:0回答:1

我正在为我的3D引擎开发一个简单的图形处理系统,这将使我能够以更少的绘制调用次数绘制线条和矩形等。我想我已经基本了解了基本概念,但是尝试绘制多个对象时遇到了问题(当前仅是可以指定粗细的线)。

以下是屏幕截图,向您展示我的意思:primitive issue

我正在使用带有glDrawElements的索引渲染,并且使用两个VBO表示顶点数据-一个用于位置,一个用于颜色。我通过指定起点和终点来为我的塑形棒构造一条线,如下所示:

    shapeRenderer.begin();
    shapeRenderer.setViewMatrix(viewMatrix);
    shapeRenderer.setProjectionMatrix(projectionMatrix);

    shapeRenderer.setCurrentColour(0, 1f, 0);
    shapeRenderer.drawLine(2, 2, 5, 2);

    shapeRenderer.setCurrentColour(0, 1f, 1f);
    shapeRenderer.drawLine(2, 5, 5, 5);
    shapeRenderer.end();

第一行,在屏幕快照中以绿色表示,显示效果非常好。如果我只画一条线,那完全没问题。如果我只画第二行,它也将完美显示。

当我调用drawLine时,将执行以下代码,用于计算方向和法线:

private Vector2f temp2fA = new Vector2f();
private Vector2f temp2fB = new Vector2f();
private Vector2f temp2fDir = new Vector2f();
private Vector2f temp2fNrm = new Vector2f();
private Vector2f temp2fTMP = new Vector2f();
private boolean flip = false;

public void drawLine(float xStart, float yStart, float xEnd, float yEnd){
    resetLineStates();

    temp2fA.set(xStart, yStart);
    temp2fB.set(xEnd, yEnd);

    v2fDirection(temp2fA, temp2fB, temp2fDir);
    v2fNormal(temp2fDir, temp2fNrm);

    float halfThickness = currentLineThickness / 2;

    //System.out.println("new line called");

    v2fScaleAndAdd(temp2fB, temp2fNrm, -halfThickness, temp2fTMP);
    pushVertex(temp2fTMP);

    v2fScaleAndAdd(temp2fB, temp2fNrm, halfThickness, temp2fTMP);
    pushVertex(temp2fTMP);

    v2fScaleAndAdd(temp2fA, temp2fNrm, halfThickness, temp2fTMP);
    pushVertex(temp2fTMP);

    v2fScaleAndAdd(temp2fA, temp2fNrm, -halfThickness, temp2fTMP);
    pushVertex(temp2fTMP);

    //System.out.println(indexCount + " before rendering.");

    int index = indexCount;

    pushIndices(index, index + 1, index + 3);
    pushIndices(index + 1, index + 2, index + 3);


    //System.out.println(indexCount + " after rendering.");
}
private void resetLineStates(){
    temp2fA.set(0);
    temp2fB.set(0);
    temp2fDir.set(0);
    temp2fNrm.set(0);
    temp2fTMP.set(0);
}

pushIndices是以下功能:

private void pushIndices(int i1, int i2, int i3){
    shapeIndices.add(i1);
    shapeIndices.add(i2);
    shapeIndices.add(i3);
    indexCount += 3;
}

[pushVertex的工作原理如下:

private void pushVertex(float x, float y, float z){
    shapeVertexData[vertexDataOffset] = x;
    shapeColourData[vertexDataOffset] = currentShapeColour.x;

    shapeVertexData[vertexDataOffset + 1] = y;
    shapeColourData[vertexDataOffset + 1] = currentShapeColour.y;

    shapeVertexData[vertexDataOffset + 2] = z;
    shapeColourData[vertexDataOffset + 2] = currentShapeColour.z;

    //System.out.println("\tpushed vertex: " + data.x + ", " + data.y + ", 0");

    vertexDataOffset += 3;
}

我正在使用以下字段来存储顶点数据,等等-当我刷新批处理时,所有这些都子缓冲到VBO。如果顶点数据数组的大小不必增加,我将使用元素缓冲区将它们子缓冲到其各自的VBO,同样,如果它们必须增加,则我将重新缓冲VBO以使其适合。

private float[] shapeVertexData;
private float[] shapeColourData;
private int vertexDataOffset;

private ArrayList<Integer> shapeIndices;
private int indexCount;

当我在IDEA中使用调试器时,顶点数据在我正在构建的数组中看起来完全正确,但是当我在RenderDoc中进行探索时,这是错误的。我不明白我为得到这些结果做错了什么,很明显,即使对于第二个矩形,前两个顶点看起来也很好,但是其他两个顶点是完全错误的。renderdoc vs IDEA debugger

我确信我的着色器不是问题,因为它们很简单,但是这里是:shape_render.vs(顶点着色器):

#version 330

layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aColour;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

flat out vec3 shapeFill;

void main(){
    shapeFill = aColour;
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(aPosition.x, aPosition.y, 0.0, 1.0);
}

[shape_render.fs(片段着色器):

#version 330
layout (location = 0) out vec4 fragColour;

in vec3 shapeFill;

void main(){
    fragColour = vec4(shapeFill, 1);
}

我想我已经尽我所能解释了它,任何见解将不胜感激。我已经检查并确定要启用必要的顶点数组等,并渲染正确数量的索引(12):correct index count

非常感谢您帮我看看。

java graphics 3d lwjgl
1个回答
0
投票

我想了一会儿以后才知道。这与我指定索引的方式有关。我使用了正确数量的索引,但是未正确指定它们。为了构造一个三角形,第一个三角形的索引计数为0,对于四个顶点,索引将分别为1,2,3和2,3,1。但是,对于每个新三角形,我都是从旧计数加6开始的索引计数,这对于寻址数组是有意义的,但是由于每个矩形仅指定了四个顶点,因此我将索引指向不存在的数据。因此,我不再每次推入索引时都使用indexCount + = 3,而是获取当前的顶点数,并从中建立索引。

© www.soinside.com 2019 - 2024. All rights reserved.