Question

I am currently learning LWJGL(LightWeight Java Game Library), the OpenGL-Java port, and am trying to figure out how to draw a circle using VBOs.

When I search for code samples concerning my problem (I search OpenGL b/c the syntax of OpenGL & LWJGL are quite similar), all I find is people using glBegin(GL_QUADS) and such, which I don't like due to its poor performance and its insufficiency. I know it uses thing like Math.PI and such(I've taken Geometry, the math is not the hard part in my opinion).

I want to know how I would get the X and Y values I receive from using Math.cos & Math.sin into the VBO, b/c when using glDrawArrays, you have to specify the number of vertices.

Was it helpful?

Solution

You seem to have a lot of this mixed up. LWJGL and openGL really have nothing to do with this and whether you use glDrawArrays or glBegin doesn't matter.

There is no drawCircle function anywhere in LWJGL, you have to draw your circle using triangles, if you want to be more efficient a triangle fan is better.

Here is a method I wrote which gives you the verticies for a filled arc (specify 0 and 360 for startingAngleDeg and endAngleDeg for a full circle).

public static float[] getFilledArcVertexes(float x, float y, float r, double startingAngleDeg, double endAngleDeg, int slices) {
        if(startingAngleDeg < 0)
            Heatstroke.error("Starting angle cannot be smaller than 0");
        if(endAngleDeg >= 720)
            Heatstroke.error("End angle cannot be greater or equal to than 720");
        if(endAngleDeg < startingAngleDeg)
            Heatstroke.error("End angle cannot be smaller than starting angle");
        int radius = (int) r;

        double arcAngleLength = (endAngleDeg - startingAngleDeg) / 360f;

        float[] vertexes = new float[slices*6+6];

        double initAngle = Math.PI / 180f * startingAngleDeg;
        float prevXA = (float) Math.sin(initAngle) * radius;
        float prevYA = (float) Math.cos(initAngle) * radius;

        for(int arcIndex = 0; arcIndex < slices+1; arcIndex++) {
            double angle = Math.PI * 2 * ((float)arcIndex) / ((float)slices);
            angle += Math.PI / 180f;
            angle *= arcAngleLength;
            int index = arcIndex * 6;
            float xa = (float) Math.sin(angle) * radius;
            float ya = (float) Math.cos(angle) * radius;
            vertexes[index] = x;
            vertexes[index+1] = y;
            vertexes[index+2] = x+prevXA;
            vertexes[index+3] = y+prevYA;
            vertexes[index+4] = x+xa;
            vertexes[index+5] = y+ya;
            prevXA = xa;
            prevYA = ya;
        }

        return vertexes;
    }

This is a pretty badly coded method made by myself in a rush. Make sure you understand it before you use it however, here is a breakdown of how it works:

  1. Work out the initial angle (only applies if drawing an arc)
  2. Loop over every number from 0 to slices, this parameter is the level of detail you want your circle to have, higher means more triangles however once you reach a certain level no more detail will be added and will just eat up cpu time.
  3. Work out the angle in radians
  4. Use Math.sin and Math.cos to work out the x and y values for that particular point on the outside of the circle
  5. Add the appropriate vertexes to the vertexes array

This will return an array of floats that should be used with GL_TRIANGLES, you could try improving it to use GL_TRIANGLE_FAN

OTHER TIPS

//You Can use this small glBegin() code and convert into VBO

double k=0;
    glBegin(GL_POINTS);
    for(k=0;k<=360;k+=0.1){
    glVertex2f((float)(x+r*Math.cos(Math.toRadians(k))),(float)(y-r*Math.sin(Math.toRadians(k))));
    }
    glEnd();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top