OpenGL Draw Around a Circle At Angles - c++

I am trying to draw an image at 45 degree increments in the shape of a circle. I am getting the image from a txt file. I am trying to translate the matrix by 45 degrees but its not working.
This is what I tried but it's not working:
glBegin(GL_LINE_STRIP);
glColor3f(0, 0,0);
for(int ii=0; ii<8; ii++){
float theta = 2*PI * float(ii)/8;
glVertex2f(cx+r*cos(theta), cy+r*sin(theta));
}
glEnd();

You want to draw the shape 8 times in different places, right?
So the program would look like this: (I will not show the exact code but enough to make you understand it)
for(int ii=0; ii<8; ii++) {
push the matrix;
calculate the position/rotation based on ii and change the matrix;
draw the shape;
pop the matrix;
}
And how do you draw the shape? Well, I guess you already know how to draw the shape and you draw the shape like this: (I think you already wrote this code, so I can show it)
glBegin(GL_LINE_STRIP);
for (auto i : floatPairs) {
glVertex2f(i.first, i.second);
}
glEnd();

Related

How to draw cylinder in modern opengl

My question is simple, how do I draw a cylinder in modern OpenGL? I'm using GLFW together with OpenGL 3.x. My thought at first was to create a function that computes the vertex positions at the bottom and at the top as circles and then draw lines between these vertices. But I have no idea how to implement this.. Does anyone have a good solution?
You can do that with a triangle strip and generate a vertex at the bottom then one at the top. That should generate the sides easily. Then just generate the caps with a triangle fan and you are don. To simplify things you can use the modelview matrix to move the cylinder into position where you want. This way you only need to have a circle in the x/y plane or similar so the math is very simple.
For performance consider using precompiled objects and/or vertex arrays.
I have been using this for a while now and I hope it will help people in the future.
struct {
GLfloat x,z, y_start, y_end;
}each_pole; // struct
std::vector<each_pole> each_pole_vector; // vector of structs
//Cylinder with y axis up
GLfloat cylinder_height = 1.0f,
cylinder_radius = 0.5f,
nr_of_points_cylinder = 360.f;
for (int i = 0; i < nr_of_points_cylinder; ++i)
{
GLfloat u = i / (GLfloat)nr_of_points_cylinder;
//Where the cylinder is in the x and z positions (3D space)
each_pole.x = center.x
+ cylinder_radius*cos(2*M_PI*u);
each_pole.z = center.z
+ cylinder_radius*sin(2*M_PI*u);
each_pole.y_start = 0.0f;
each_pole.y_end = cylinder_height;
each_pole_vector.push_back(each_pole);
}
return each_pole_vector;

i have created a circle from lines in opengl but it shows holes at outer edges

I had drawn a circle in opengl using lines.But it shows a pattern of holes at outer edges.
I want to fill this holes without reducing the radius and increasing the number of samples.
This is my code:
void drawcirc(float xi,float yj,float r1,int num1)
{
glClear(GL_COLOR_BUFFER_BIT);
//glBegin(GL_LINES);
glVertex2f(0,0);
for (int i=0;i<=num1;i++)
{
float theta=2.0f*3.141592f*float(i)/float(num1);
float x1=r1*cosf(theta);
float y1=r1*sinf(theta);
glBegin(GL_LINES);
glVertex2f(0,0);
glVertex2f(xi+x1,yj+y1);
glEnd();
sleep(5000);
glFlush();
}
}
then function call drawcirc(0, 0, 0.6, 1250);
what to do? this is my o/p with holes at outer edges.
Okay, well you're not really drawing a circle. GL_LINES will go from point to point until the primitive ends
You draw a line from 0,0 to a point on the rim of the circle + the offset you give the function.
So you're drawing the spokes of a wheel essentially, the holes at the edge are the gaps between the spokes.
AlecTeal already answered what is going on. I give you the fix:
#include <math.h>
void drawFilledCircle(float xi,float yj,float r1,int num1)
{
glBegin(GL_TRIANGLE_FAN);
glVertex2f(0,0);
for(int i = 0; i <= num1; i++)
{
float theta = 2.0f*M_PI * float(i)/float(num1);
float x1 = r1*cosf(theta);
float y1 = r1*sinf(theta);
glVertex2f(xi+x1,yj+y1);
}
glEnd();
}
void drawCircle(float xi,float yj,float r1,int num1)
{
glBegin(GL_LINE_LOOP);
for(int i = 0; i < num1; i++)
{
float theta = 2.0f*M_PI * float(i)/float(num1);
float x1 = r1*cosf(theta);
float y1 = r1*sinf(theta);
glVertex2f(xi+x1,yj+y1);
}
glEnd();
}
A few hints:
Never put glFlush, glClear, sleep or similar into function intended to draw a geometrical shape. You want to be able to call such functions from higher level drawing code and such calls are highly disruptive.
glBegin and glEnd are deprecated, their use has been discouraged for well over 15 years now. Better use vertex arrays.
If you must use glBegin/glEnd put them outside of the loop, not inside it.

OpenGL circle drawing getting an ellipse

I'm trying to draw a circle in opengl, but i can't seem to get the right coordinates, so i always get an ellipsis no matter what method i use. The current code is as follows:
void Ball::Render() {
float center_position_x = _body->GetWorldCenter().x;
float center_position_y = _body->GetWorldCenter().y;
float radius = static_cast<b2CircleShape*>(_body->GetFixtureList()->GetShape())->m_radius;
glBegin(GL_LINE_STRIP);
for(float angle = 0; angle <= 360; ++angle) {
float angleInRadians = glm::radians(angle);
float x = glm::cos(angleInRadians);
float y = glm::sin(angleInRadians);
glVertex3f(x,y,0);
}
glEnd();
}
( I know that code should draw the circle at the origin, but even then it's not a perfect circle, if i understand correctly that should draw a circle at the origin with radius=1 )
The other methods i used were:
http://slabode.exofire.net/circle_draw.shtml
http://www.opengl.org/discussion_boards/showthread.php/167955-drawing-a-smooth-circle
This is my OpenGL window setup code (It's a stub program so i'm starting with hardcoded values):
gluOrtho2D(-10, 15, -10, 15);
Use gluOrtho2D(-WIDOWS_WIDTH, WIDOWS_WIDTH, -WINDOWS_HEIGHT, WINDOWS_HEIGHT);
By the way your are using fixed pipeline in 2013. With a vertex shader this would be much easy to understand.
The aspect ratio of your 2D projection matrix defined by gluOrtho2d must be same as the viewport/window on which you are rendering otherwise you'll notice distortions in the figures you are rendering. You can use the above gluOrtho2d statement or other way of writing it is -
float ar = (float)WindowWidth/WindowHeight;
gluOrtho2D(-1*ar, ar, -1, 1)

OpenGL glTranslatef not working as it should

So I decided to make a 3D Stars kinda thing in C++ with SDL and OpenGL. I created a Point class which holds x, y, and z values. I create an array of Points and fill it with random coordinates. This seems to work but when I do glTranslatef(0,0,0.1f) or something similar, the stars don't come close, they just disappear.
//OpenGL Initialization Code
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0f,640.0/480.0,0.3f,500.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
//Random point generation
for(int i = 0; i < 200000; i++)
{
float randomX = (float)rand()/((float)RAND_MAX/100.0f) - 50.0f;
float randomY = (float)rand()/((float)RAND_MAX/20) - 10.0f;
float randomZ = (float)rand()/((float)RAND_MAX/20) - 20.0f;
points[i] = Point(randomX, randomY,randomZ);
}
//Render
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
for(int i = 0; i < 200000; i++)
{
glVertex3f(points[i]._x, points[i]._y, points[i]._z);
}
glEnd();
glTranslatef(0,0,0.1f);
SDL_GL_SwapBuffers();
SDL_Flip(screen);
What am I doing wrong?
Is that code your render function?
If it is, then you should move the point generation elsewhere so that they get generated only once.
If it is not, then you should move the initialization code to the beginning of the render function. The matrices should be cleared every frame.
If that doesn't work:
Try temporarily disabling depth testing. If they don't disappear and you see lines, you need to adjust your view frustum. Try using gluLookAt
Also, try translating them in the negative z axis. If I remember correctly, in opengl, object-space coordinates are farther away as z decreases. (0 is closer than -1)
I'm not sure why they'ld be disappearing, but in your sample code it should be inert. You load a new Identity matrix at the top for the MODELVIEW matrix, and then translate it after you've rendered. Try moving the glTranslate to right before your glBegin.
I moved the OpenGL initialization code after the code where I init SDL SetVideoMode, it works as it should now.

Camera rotation (OpenGL)

I am having trouble with a camera class I am trying to use in my program. When I change the camera_target of the gluLookAt call, my whole terrain is rotating instead of just the camera rotating like it should.
Here is some code from my render method:
camera->Place();
ofSetColor(255, 255, 255, 255);
//draw axis lines
//x-axis
glBegin(GL_LINES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(100.0f, 0.0f,0.0f);
glEnd();
//y-axis
glBegin(GL_LINES);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f, 100.0f,0.0f);
glEnd();
//z-axis
glBegin(GL_LINES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f, 0.0f,100.0f);
glEnd();
glColor3f(1,1,1);
terrain->Draw();
And the rotate and place methods from my camera class:
void Camera::RotateCamera(float h, float v){
hRadians += h;
vRadians += v;
cam_target.y = cam_position.y+(float)(radius*sin(vRadians));
cam_target.x = cam_position.x+(float)(radius*cos(vRadians)*cos(hRadians));
cam_target.z = cam_position.z+(float)(radius*cos(vRadians)*sin(hRadians));
cam_up.x = cam_position.x-cam_target.x;
cam_up.y = ABS(cam_position.y+(float)(radius*sin(vRadians+PI/2))) ;
cam_up.z = cam_position.z-cam_target.z;
}
void Camera::Place() {
//position, camera target, up vector
gluLookAt(cam_position.x, cam_position.y, cam_position.z, cam_target.x, cam_target.y, cam_target.z, cam_up.x, cam_up.y, cam_up.z);
}
The problem is that the whole terrain is moving around the camera, whereas the camera should just be rotating.
Thanks for any help!
EDIT - Found some great tutorials and taking into account the answers on here, I make a better camera class. Thanks guys
From the POV of the terrain, yes, the camera is rotating. But, since your view is from the POV of the camera, when you rotate the camera, it appears that the terrain is rotating. This is the behavior that gluLookAt() is intended to produce. If there is something else that you expected, you will need to rotate only the geometry that you want rotated, and not try to rotate using gluLookAt().
Update 1: Based on the discussion below, try this:
void Camera::RotateCamera(float h, float v)
{
hRadians += h;
vRadians += v;
cam_norm.x = cos(vRadians) * sin(hRadians);
cam_norm.y = -sin(vRadians);
cam_norm.z = cos(vRadians) * sin(hRadians);
cam_up.x = sin(vRadians) * sin(hRadians);
cam_up.y = cos(vRadians);
cam_up.z = sin(vRadians) * cos(hRadians);
}
void Camera::Place()
{
//position, camera target, up vector
gluLookAt(cam_pos.x, cam_pos.y, cam_pos.z,
cam_pos.x+cam_norm.x, cam+pos.y+cam_norm.y, camp_pos.z+cam_norm.z,
cam_up.x, cam_up.y, cam_up.z);
}
Separating the camera normal (the direction the camera is looking) from the position allows you to independently change the position, pan and tilt... that is, you can change the position without having to recompute the normal and up vectors.
Disclaimer: This is untested, just what I could do on the back of a sheet of paper. It assumes a right handed coordinate system and that pan rotation is applied before tilt.
Update 2: Derived using linear algebra rather than geometry... again, untested, but I have more confidence in this.
Well, rotating the camera or orbiting the terrain around the camera looks essentially the same.
If you want to orbit the camera around a fixed terrain point you have to modify the camera position, not the target.
Should it not be?:
cam_up.x = cam_target.x - cam_position.x;
cam_up.y = ABS(cam_position.y+(float)(radius*sin(vRadians+PI/2))) ;
cam_up.z = cam_target.z - cam_position.z;
Perhaps you should normalize cam_up as well.
HTH