PDA

View Full Version : Drawing multiple circles in OpenGL



jhodara
03-08-2018, 03:31 PM
Hi all,

I am fairly new to the world of OpenGL, and I am trying to draw a few circles in 2D. These circles are static right now, but will start moving later on. I can't seem to get it to work and I would really appreciate some help here.
Here's what I have so far:

1. I create a vector of vertices for a generic circle centered at (0,0) of radius 1:



const size_t nVertices = 100;
float vertices[3*nVertices];
const float twoPi = 8.0f*atan(1.0f);
const size_t nSides = nVertices-2;
for (size_t i = 1; i < nVertices; i++)
{
vertices[3*i ] = cos(i*twoPi/nSides);
vertices[3*i+1] = sin(i*twoPi/nSides);
vertices[3*i+2] = 0.0f;
}


These vertices are pushed to the GPU before entering the time loop.

2. I create a bunch of circles with a given location and radius. Note that these are defined in world coordinates (x and y from 0 to 2000). I would like to fit the entire world into my square window. Hence, I have two uniforms for the mapping:



shader.use();
shader.setFloat("worldScreenRatio", 2.0f/2000.0f);
shader.setVec3f("shiftWorldCenter", -2000.0f/2.0f, -2000.0f/2.0f, 0.0f);


3. In the display function, I have:



shader.use();
glBindVertexArray(vao);
for(const auto circle : circles) {
shader.setFloat("radius", circle->GetrRadius());
shader.setVec3f("location", circle->GetLocation());
glDrawArrays( GL_TRIANGLE_FAN, 0, nVertices);
}


4. Finally, the vertex shader is as follows:



#version 330 core
layout (location = 0) in vec3 aPos;
uniform vec3 location;
uniform float radius;
uniform float worldScreenRatio;
uniform vec3 shiftWorldCenter;

void main()
{
gl_Position = vec4(worldScreenRatio*vec3(radius*aPos + location + shiftWorldCenter), 1.0);
}


I created 3 circles in the corners of my world (1900,1900), (100, 1900) and (100, 100) and tried to display them. Unfortunately, I am getting this strange results instead of my circles (see attached figure).

Am I missing something? It seems to work just fine when I don't use the worldScreenRatio and specify locations between -1 and 1. I don't understand what I am doing wrong here.

Thank you for your help, please let me know if you need extra information regarding this case.

Joachim

GClements
03-08-2018, 04:39 PM
1. I create a vector of vertices for a generic circle centered at (0,0) of radius 1:



const size_t nVertices = 100;
float vertices[3*nVertices];
const float twoPi = 8.0f*atan(1.0f);
const size_t nSides = nVertices-2;
for (size_t i = 1; i < nVertices; i++)
{
vertices[3*i ] = cos(i*twoPi/nSides);
vertices[3*i+1] = sin(i*twoPi/nSides);
vertices[3*i+2] = 0.0f;
}


I don't see you setting the first vertex, which should be the centre of the circle. Well, it should at least be inside the circle. If it's left unset, you'd get the results shown in your image: the centre of the fan will be at some essentially-random point which is likely to be way off screen.

But if you just want to draw circles, you'd probably be better off drawing squares with a fragment shader which discards fragments outside of the unit circle (x2+y2>1).

jhodara
03-09-2018, 01:42 PM
I don't see you setting the first vertex, which should be the centre of the circle. Well, it should at least be inside the circle. If it's left unset, you'd get the results shown in your image: the centre of the fan will be at some essentially-random point which is likely to be way off screen.

But if you just want to draw circles, you'd probably be better off drawing squares with a fragment shader which discards fragments outside of the unit circle (x2+y2>1).

Arg! That was it, thank you!