N1ghtk1n9
N1ghtk1n9

Reputation: 89

LWJGL Circle program create's an oval-like shape

I'm trying to draw a circle in LWJGL, but when I draw I try to draw it, it makes a shape that's more like an oval rather than a circle. Also, when I change my circleVertexCount 350+, the shape like flips out. I'm really not sure how the code works that creates the vertices(I have taken Geometry and I know the basic trig ratios). I haven't really found that good of tutorials on creating circles. Here's my code:

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(This is my main problem) LWJGL Oval Figure

400 Vertex Count - I removed this image, it's bugged out, should be a tiny sliver cut out from the right, like a secant

500 Vertex Count Circle - 500 Vertices

Each 100, it removes more and more of the circle, and so on.

Upvotes: 0

Views: 800

Answers (1)

Alex - GlassEditor.com
Alex - GlassEditor.com

Reputation: 15507

One of your problems is this:

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;
}

You are using a different value for angle for the x and y position of each vertex.

You could try this instead:

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;
}

The reason part of your circle was being cut out at higher vertex counts was the i < 400 in your for loops, so I have changed it to i <= circleVertexCount.

Another problem is that your window is not square, and you are not using a shader (or the deprecated built in matrices) to correct this. This means that one unit up looks a different length than one unit right, resulting in an oval instead of a circle. To fix this you could multiply your vertex x position by your display height divided by your display width, preferably in a shader.

Upvotes: 1

Related Questions