OpenGL - сложность с построением фигур - PullRequest
0 голосов
/ 06 февраля 2020

Я начинаю работу над простой системой пакетирования фигур для моего 3D-движка, которая позволит мне рисовать линии и прямоугольники и т. Д. c ... с меньшим количеством вызовов для рисования. Я думаю, что у меня есть основополагающие идеи c по большей части, но у меня возникают проблемы, когда я пытаюсь нарисовать несколько объектов (в настоящее время это просто линии с толщиной, которую вы можете указать).

Вот снимок экрана, чтобы показать вам, что я имею в виду: 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, когда я делаю sh пакет. Если массивы данных вершин не должны были увеличиваться в размере, я буду помещать их в буфер для их соответствующих VBO, также как и для буфера элементов, в противном случае, если они должны были расти, я повторно буферизирую VBO, чтобы соответствовать.

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

private ArrayList<Integer> shapeIndices;
private int indexCount;

Когда я использую мой отладчик в IDEA, данные вершин кажутся совершенно правильными в массивах, которые я строю, но когда я исследую их в RenderDo c, это неправильно. Я не понимаю, что я делаю не так, чтобы получить эти результаты, и, очевидно, первые две вершины выглядят совершенно нормально даже для второго прямоугольника, но остальные совершенно не правы. 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);
}

Я думаю, что я только что объяснил это, насколько мне известно, любая проницательность будет с благодарностью. Я уже проверил и определил, что я включаю необходимые массивы вершин и т. Д. c ... и отображаю правильное количество индексов (12): correct index count

Спасибо так много для того, чтобы взглянуть на это для меня.

1 Ответ

0 голосов
/ 07 февраля 2020

Я понял это, немного подумав об этом. Это было связано с тем, как я указывал индексы. Я использовал правильное количество индексов, но указал их неправильно. Для аргументов, чтобы построить треугольник, первый будет иметь индекс числа 0, а с четырьмя вершинами индексы будут 1,2,3 и 2,3,1 (например). Однако для каждого нового треугольника я начинал подсчет индекса со старого счетчика плюс шесть, что имеет смысл для адресации массива, но поскольку каждый прямоугольник определял только четыре вершины, я указывал индексы на несуществующие данные. Таким образом, вместо использования indexCount + = 3 каждый раз, когда я нажимаю индексы, я получу текущее количество вершин вместо этого и построю свои индексы из этого.

...