i need to draw a square using c (openGL),
i only have 1 coordinate which is the center of the square (lets say 0.5,0.5) and i need to draw a square ABCD with each side 0.2 length (AB,BC,CD,DA),
I tried using the next function but it does not draw anything for some reson,
void drawSquare(double x1,double y1,double radius)
{
glColor3d(0,0,0);
glBegin(GL_POLYGON);
double locationX = x1;
double locationY = x2;
double r = radius;
for(double i=0; i <= 360 ; i+=0.1)
{
glVertex2d(locationX + radius*i, locationY + radius*i);
}
glEnd();
}
can someone please tell me why its not working\point me to the right direction (i do not want to draw polygon with 4 coordinated normally, but with only 1 coordinate with a givven radius,
thanks!
Your code will not even draw a circle. If anything, it will draw a diagonal line extending out of the view area very quickly. A circle plot would need to use sine and cosine, based on the radius and angle.
I have not tried this code, but it needs to be more like this to draw a square.
void drawSquare(double x1, double y1, double sidelength)
{
double halfside = sidelength / 2;
glColor3d(0,0,0);
glBegin(GL_POLYGON);
glVertex2d(x1 + halfside, y1 + halfside);
glVertex2d(x1 + halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 + halfside);
glEnd();
}
There are no normals defined: perhaps I should have travelled counter-clockwise.
Simple way to draw a square is to use GL_QUADS and the four vertices for the four corners of the square. Sample code is below-
glBegin(GL_QUADS);
glVertex2f(-1.0f, 1.0f); // top left
glVertex2f(1.0f, 1.0f); // top right
glVertex2f(1.0f, -1.0f); // bottom right
glVertex2f(-1.0f, -1.0f); // bottom left
glEnd();
Since in the case you have to draw square from the mid point which is interaction of two diagonals of square. You use the following facts and draw the same.
length of diagonal = x*square root of 2 (x=side of square)
diagonals of a square are perpendicular
diagonals of a square are the same length
If your point is at 0.5,0.5 which coordinate of interaction point, and side is 0.2. So you can easily determine the point coordinate of four corners as in the figure given below and code it accordingly.
Related
The goal
I'm trying to implement an orthographic camera for 2D rendering with OpenGL.
The issue
Nothing is drawn to the screen.
The setup
Each frame I am updating the camera using this call:
updateCamera(&gCamera, -10.0f, 10.0f, 0.0f, 10.0f, 1.0f, -1.0f);
The updateCamera method has the following declaration:
void updateCamera(Camera* cam, float top, float bottom, float left, float right, float zFar, float zNear);
The camera struct simply has a float opm[4][4] member which represents the matrix.
The updateCamera method has the following implementation:
cam->opm[0][0] = 2.0f / (right - left);
cam->opm[1][1] = 2.0f / (top - bottom);
cam->opm[2][2] = -2.0f / (zFar - zNear);
cam->opm[3][0] = -(right + left) / (right - left);
cam->opm[3][1] = -(top + bottom) / (top - bottom);
cam->opm[3][2] = -(zFar + zNear) / (zFar - zNear);
cam->opm[3][3] = 1.0f;
Everything is drawn correctly if I use an identity matrix instead of the one above. Perhaps there is an issue in my calculation of the matrix?
The problem lies in the definition of the vertices and the call to updateCamera.
The triangle is so small that it is not drawn with those parameters.
Using the following draw call:
updateCamera(&gCamera, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f);
everything works.
Use an identity matrix first to find out if drawing works - then add scaling and translation.
I am trying to find the screen coordinates from the opengl coordinates(projected in 3D space) I have used glproject call for this purpose,i have used rotation and translation to in my code
At certain point after performing some transformation, i called glproject api to get the screen coordinate of a particular projected point P(x,y,z)
glproject(x,y,z,modelMatrix,projectionmatrix,viewport,*x_s,*y_s,*z_s);
I am able to get x screen coordinate correctly in x_s , but y coordinates are different
The only change in y which is not in x is when initially i called the glperspective to set fovy(The field of view angle, in degrees, in the y-direction). gluPerspective(60.0f, Width/Height,0.0001f,1000.0f);
Let me Rephrase the question I have created a 3D point on screen and now i am getting the 2d(x,y) coordinates of that point through GLproject they come different from the mouse coordinates What could be the possible solution to get correct coordinates.
Here is the code snippet
#include<GL/glut.h> /* Header File For The GLUT Library */
GLint Window; /* The number of our GLUT window */
float tmp_x,tmp_y,tmp_z;
GLfloat w = 1200; /* Window size. Global for use in rotation routine */
GLfloat h = 1200;
GLint prevx, prevy; /* Remember previous x and y positions */
GLfloat xt=1.0,yt=1.0,zt=1.0; /* translate */
int width = 1600;
int height = 1200;
//This function will set windowing transformation
void transform(GLfloat Width , GLfloat Height )
{
glViewport(0,0, (GLfloat)Width, (GLfloat)Height);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, Width/Height,0.0001f,1000.0f);
glTranslatef(0.0, 0.0, -15.0f); /* Centre and away the viewer */
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
GLvoid draw_room()
{
int i;
glPushMatrix();
glShadeModel(GL_SMOOTH);
glLineWidth(1.0);
glPointSize(4.0); /* Add point size, to make it clear */
glBegin(GL_POINTS); /* start drawing the cube.*/
glColor3f(0.0f,0.0f,1.0f); /* Set The Color To Orange*/
glColor3f(1.0f,0.0f,0.0f); /* Set The Color To Orange*/
glVertex3f(3.1f,2.1f,2.1f);
glEnd(); /* Done Drawing The Cube*/
glEnable(GL_DEPTH_TEST);
}
//OpenGl Display callback Function It call init room
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
printf("%f %f %f\n",xt,yt,zt);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(xt,yt, zt);
draw_room();
glPopMatrix();
glutSwapBuffers(); /* Swap buffers */
glFlush();
}
GLvoid Mouse( int b , int s, int xx, int yy)
{
double a1,a2,a3;
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
//gluProject(xt+3.1f,yt+2.1f,zt+2.1f, modelview, projection, viewport, &a1, &a2, &a3);
gluProject(3.1f,2.1f,2.1f, modelview, projection, viewport, &a1, &a2, &a3);
printf("Mouse: %d %d\n",xx,yy); // Both Print are giving different coordinaes.
printf("Unproject %f %f %f\n",a1,a2,a3);
switch (b) {
case GLUT_LEFT_BUTTON: /* only stash away for left mouse */
prevx = xx - w/2;
prevy = h/2 - yy;
break;
case GLUT_MIDDLE_BUTTON:
break;
case GLUT_RIGHT_BUTTON:
break;
}
}
What could be the possible solution for this?
OpenGL uses lower left corner of screen as coordinate system orign. Window system usually uses upper left corner as coordinate system orign. You need to handle this difference. Example:
printf("Mouse: %d %d\n",xx,yy);
printf("Unproject %f %f %f\n",a1,viewport[1]-a2,a3);
A side issue:
gluPerspective(60.0f, Width/Height,0.0001f,1000.0f);
You have a very large ratio between your near and far plane distance. This is very bad for depth resolution. As a general rule you should set the near clip plane distance as far as possible, as the scene allows. The far clip plane for a projection as created by gluPerspective should be set as near as possible (it's also possible to set the far clipping plane to infinity if the projection matrix is built slightly different).
Anyway, your low depth resolution will have a negative impact on your mouse pointer screen position back projection.
Let me Rephrase the question I have created a 3D point on screen and now i am getting the 2d(x,y) coordinates of that point through GLproject they come different from the mouse coordinates What could be the possible solution to get correct coordinates.
Most window systems put the pointer coordinate system origin to the upper left. OpenGL sets the viewport coordinate system origin into the lower left. So you'll have to invert the mouse position in the window along the Y=Up axis.
O
position 2
O Y
object ( x,y,z )
position 1
I want rotate object according to fix point (x,y,z) with Q angle. With opengl, how can I do that ?
Object goes from position 1 to position 2 .
I know Q, (x,y,z).
I have done :
glPushMAtrix ()
glTranslatef ( -x, -y, -z ) ;
glRotatef ( Q, 1.0f, 0.0f, 0.0f );
glCylinder ( /*argument*/ )
glPopMatriX ()
If you are rotating in 3D space and know only object, angle and the center of rotation, then your task is undefined. In 3D space you can rotate only around some axis, not point.
From your code example you are rotating around X axis. Let me guess that's what you really want.
To achieve this you should translte orign of coordinate system to the center of rotation, perform rotation and translate coordinate system back.
glTranslatef(-x, -y, -z);
glRotatef(Q, 1.0, 0.0, 0.0);
glTranslatef(x, y, z);
// draw the object
If you know the initial and final position of your object, then you can calculate the axis of rotation. (Since 3 points always define a plane and its normal.) In vector notation it should look this way (May be wrong in axis direction. If object rotates on opposite direction change the sign of axis or angle).
axis = vec(center_of_rotation - initial_position, center_of_rotation - final_position)
Or a little bit more "for dummies"
float X1[3]; // initial position
float X2[3]; // final position
float O[3]; // orign of rotation
float OX1[3]; OX1[0] = X1[0] - O[0]; OX1[1] = X1[1] - O[1]; OX1[2] = X1[2] - O[2];
float OX2[3]; OX2[0] = X2[0] - O[0]; OX2[1] = X2[1] - O[1]; OX2[2] = X2[2] - O[2];
float axis[3]; // vector product OX1 and OX2
axis[0] = OX1[1]*OX2[2]-OX1[2]*OX2[1];
axis[1] = OX1[2]*OX2[0]-OX1[0]*OX2[2];
axis[2] = OX1[0]*OX2[1]-OX1[1]*OX2[0];
i want to create a 800X600 window that just show some circle and be able to manipulate pixels of the form every milisecond and show the result to the user. there is no interaction between user and form(no click, no dblclick,…) it just shows some circles with one color and lines with different pixel colors(each line may have different pixel colors)
also i want to be able to change the coordination system, i mean change it from top-left to the center of the window. could anyone help me do that with some sample code? links? tutorial?
OpenGL doesn't have a built-in circle function, but it does have line functions, and you can simulate a circle using polygons. To draw lines, you can do something like this:
glBegin (GL_LINES);
// First line segment
glVertex2f (x0, y0);
glVertex2f (x1, y1);
// Second line segment
glVertex2f (x2, y2);
glVertex2f (x3, y3);
glEnd ();
To draw a circle, you can write a loop to draw a triangle fan. Something like:
glBegin (GL_TRIANGLE_FAN);
// Center point
glVertex2f (cx, cy);
for (segment = 0; segment < maxSegments; segment++)
{
double angle = delta * segment;
double x = cx + cos (angle) * radius;
double y = cy + sin (angle) * radius;
glVertex2f (x, y);
}
glEnd ();
In this case, delta is 2 * pi / maxSegments, and maxSegments is the number of segments you want in your circle approximation.
I am trying to make a few effects in a C+GL game. So far I draw all my sprites as a quad, and it works.
However, I am trying to make a large ring appear at times, with a texture following that ring, as it takes less memory than a quad with the ring texture inside.
The type of ring I want to make is not a round-shaped GL mesh ring (the "tube" type) but a "paper" 2D ring. That way I can modify the "width" of the ring, getting more of the effect than a simple quad+ring texture.
So far all my attempts have been...kind of ridiculous, as I don't understand GL's coordinates too well (and I can't really understand the available documentation...I am just a designer with no coder help or background. A n00b, basically).
glBegin(GL_POLYGON);
for(i = 0;i < 360; i += 10){
glTexCoord2f(0, 0);
glVertex2f(Cos(i)*(H-10),Sin(i)*H);
glTexCoord2f(0, HP);
glVertex2f(Sin(i)*(H-10),Cos(i)*(H-10));
glTexCoord2f(WP, HP);
glVertex2f(Cos(i)*H,Sin(i)*(H-10));
glTexCoord2f(WP, 0);
glVertex2f(Sin(i)*H,Cos(i)*H);
}
glEnd();
This is my last attempt, and it seems to generate a "sunburst" from the right edge of the circle instead of a ring. It's an amusing effect but definitely not what I want. Other results included the circle looking exactly the same as the quad textured (aka drawing a sprite literally) or something that looked like a pop-art filter, by working on this train of thought.
Seems like my logic here is entirely flawed, so, what would be the easiest way to obtain such a ring? No need to reply in code, just some guidance for a non-math-skilled user...
Edit: A different way to word what I want, would be a sequence of rotated rectangles connected to each other, forming a low-resolution ring.
So you want an annulus? That is, the area between two circles with the same center but different radii? I'd try a quad strip like this:
glBegin(GL_QUAD_STRIP);
for(i = 0; i <= 360; i += 10){
glTexCoord2f(WP*i/360, 0);
glVertex2f(Cos(i)*(H-10),Sin(i)*(H-10));
glTexCoord2f(WP*i/360, HP);
glVertex2f(Cos(i)*H,Sin(i)*H);
}
glEnd();
Each quad is a 10-degree sector of the ring. Note that if you want to draw N quads in a strip, it takes 2*(N+1) points, so we draw a total of 2*(36+1) = 74 points.
The post here on the OpenGL forums seems to do what you want. An overview of the approach:
If you want a circle filed with a
texture, you can use triangle fan.
First, draw the vertex at the center
of the circle. Then draw the vertex on
the contour of the circle, use
cos(angle)*radius for x and
sin(angle)*radius for y. Since texture
coordinates s and t are in the range
[0 1] => s = (cos(angle)+1.0)*0.5 and
t = (sin(angle)+1.0)*0.5 . The texture
coordinate for the vertex at the
center of the circle is (0.5,0.5).
GLvoid draw_circle(const GLfloat radius,const GLuint num_vertex)
{
GLfloat vertex[4];
GLfloat texcoord[2];
const GLfloat delta_angle = 2.0*M_PI/num_vertex;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBegin(GL_TRIANGLE_FAN);
//draw the vertex at the center of the circle
texcoord[0] = 0.5;
texcoord[1] = 0.5;
glTexCoord2fv(texcoord);
vertex[0] = vertex[1] = vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
for(int i = 0; i < num_vertex ; i++)
{
texcoord[0] = (std::cos(delta_angle*i) + 1.0)*0.5;
texcoord[1] = (std::sin(delta_angle*i) + 1.0)*0.5;
glTexCoord2fv(texcoord);
vertex[0] = std::cos(delta_angle*i) * radius;
vertex[1] = std::sin(delta_angle*i) * radius;
vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
}
texcoord[0] = (1.0 + 1.0)*0.5;
texcoord[1] = (0.0 + 1.0)*0.5;
glTexCoord2fv(texcoord);
vertex[0] = 1.0 * radius;
vertex[1] = 0.0 * radius;
vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
glEnd();
glDisable(GL_TEXTURE_2D);
}