Программа LWJGL Circle создает овальную форму

Я пытаюсь нарисовать круг в LWJGL, но когда я пытаюсь нарисовать его, он создает форму, которая больше похожа на овал, чем на круг. Кроме того, когда я меняю свой круг VertexCount 350+, форма, как будто, переворачивается. Я действительно не уверен, как работает код, который создает вершины (я взял Geometry, и я знаю основные триггерные отношения). Я действительно не нашел столько хороших уроков по созданию кругов. Вот мой код:

public class Circles {

// Setup variables
private int WIDTH = 800;
private int HEIGHT = 600;
private String title = "Circle";

private float fXOffset;

private int vbo = 0;
private int vao = 0;

int circleVertexCount = 300;

float[] vertexData = new float[(circleVertexCount + 1) * 4];

public Circles() {
    setupOpenGL();
    setupQuad();

    while (!Display.isCloseRequested()) {
        loop();
        adjustVertexData();
        Display.update();
        Display.sync(60);
    }

    Display.destroy();
}

public void setupOpenGL() {
    try {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); 
        Display.setTitle(title);
        Display.create();

    } catch (LWJGLException e) {
        e.printStackTrace();
        System.exit(-1);
    }

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
}

public void setupQuad() {
    float r = 0.1f;
    float x;
    float y;
    float offSetX = 0f;
    float offSetY = 0f;
    double theta = 2.0 * Math.PI;

    vertexData[0] = (float) Math.sin(theta / circleVertexCount) * r + offSetX;
    vertexData[1] = (float) Math.cos(theta / circleVertexCount) * r + offSetY;

    for (int i = 2; i < 400; i += 2) {
        double angle = theta * i / circleVertexCount;
        x = (float) Math.cos(angle) * r;
        vertexData[i] = x + offSetX;
    }

    for (int i = 3; i < 404; i += 2) {
        double angle = Math.PI * 2 * i / circleVertexCount;
        y = (float) Math.sin(angle) * r;
        vertexData[i] = y + offSetY;
    }

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

    vao = glGenVertexArrays();
    glBindVertexArray(vao);

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

    glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);

}

public void loop() {
    glClear(GL_COLOR_BUFFER_BIT); 

    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);

    glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData.length / 2);

    glDisableVertexAttribArray(0);
    glBindVertexArray(0);
}

public static void main(String[] args) {
    new Circles();
}

private void adjustVertexData() {
    float newData[] = new float[vertexData.length];
    System.arraycopy(vertexData, 0, newData, 0, vertexData.length);

    if(Keyboard.isKeyDown(Keyboard.KEY_W)) {
        fXOffset += 0.05f;
    } else if(Keyboard.isKeyDown(Keyboard.KEY_S)) {
        fXOffset -= 0.05f;
    }

    for(int i = 0; i < vertexData.length; i += 2) {
        newData[i] += fXOffset;
   }

    FloatBuffer newDataBuffer = BufferUtils.createFloatBuffer(newData.length);
    newDataBuffer.put(newData);
    newDataBuffer.flip();

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferSubData(GL_ARRAY_BUFFER, 0, newDataBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}

300 Vertex Count (это моя главная проблема)LWJGL Овальная фигура

400 Vertex Count - Я удалил это изображение, оно вылезло, должно быть крошечный осколок справа, как секущий

500 вершинКруг - 500 вершин

Каждые 100 он удаляет все больше и больше круга и так далее.

1 ответ

Решение

Одна из ваших проблем заключается в следующем:

for (int i = 2; i < 400; i += 2) {
    double angle = theta * i / circleVertexCount;
    x = (float) Math.cos(angle) * r;
    vertexData[i] = x + offSetX;
}

for (int i = 3; i < 404; i += 2) {
    double angle = Math.PI * 2 * i / circleVertexCount;
    y = (float) Math.sin(angle) * r;
    vertexData[i] = y + offSetY;
}

Вы используете другое значение угла для положения x и y каждой вершины.

Вы можете попробовать это вместо этого:

for (int i = 0; i <= circleVertexCount; i++) {
    double angle = i * theta / circleVertexCount;
    x = (float) Math.cos(angle) * r;
    y = (float) Math.sin(angle) * r;
    vertexData[i * 2] = x + offSetX;
    vertexData[i * 2 + 1] = y + offSetY;
}

Причиной того, что часть вашего круга была вырезана при большем числе вершин, была i < 400 в ваших циклах, поэтому я изменил его на i <= circleVertexCount,

Другая проблема заключается в том, что ваше окно не квадратное, и вы не используете шейдер (или устаревшие встроенные матрицы) для исправления этого. Это означает, что одна единица вверх выглядит иначе, чем одна единица вправо, что приводит к овалу вместо круга. Чтобы исправить это, вы могли бы умножить свою позицию вершины х на высоту вашего дисплея, деленную на ширину вашего дисплея, предпочтительно в шейдере.

Другие вопросы по тегам