PDA

View Full Version : Code to draw shapes



annette
10-13-2011, 10:33 AM
Hi,
I'm a newbie at coding in openGL. Can someone please take a look at this code and tell me what I'm doing wrong? I've been playing with it and moving things around. So far, it's only the triangle shape that is showing when I compile it. The line, circle and arc are not showing. Thanks.


#include <Windows.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>


GLsizei winWidth = 400, winHeight = 300;
const float PI = 3.14159265f;
const float Radius = 4;
const float numPoints = 24;
float t, dt; /* angle */
int n = 30; /* # of segments */
int i;
float x = 2;
float y = 2;
float r = 2;
float t0 = 30;
float sweep = 40;


void drawCircle( float Radius, int numPoints )
{
glBegin( GL_LINE_STRIP );
for( int i=0; i<numPoints; i++ )
{
float Angle = i * (2.0*PI/numPoints);
float X = cos( Angle )*Radius;
float Y = sin( Angle )*Radius;
glVertex2f( X, Y );
}
glEnd();
}




void drawTriangle()
{
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 1, 0);
glEnd();
}


void drawArc(float x, float y, float r, float t0, float sweep)
{

t = t0 * PI/180.0; /* radians */
dt = sweep * PI/(180*n); /* increment */

glBegin(GL_LINE_STRIP);
glColor3f(0.1, 0.2, 0.3);

for(i=0; i<=n; i++, t += dt)
glVertex2f(x + r*cos(t), y + r*sin(t));

glEnd();
}



void DrawLine( )
{
glBegin(GL_LINES);
glVertex2i( 0, 0);
glVertex2i( 10, 10);
glEnd();

}


void drawFace()
{

drawArc(x, y, r, t0, sweep);
drawCircle( Radius, numPoints );

}

void init(void)
{
glClearColor (0.0, 0.0, 1.0, 0.0);

glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, winWidth, 0.0, winHeight);
}


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin( GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2i(50, 50);
glVertex2i(100, 50);
glVertex2i(75, 100);
glEnd();

glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_LINES);
glVertex2i( 0, 0);
glVertex2i( 10, 10);
glEnd();

glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_LINE_STRIP);
glColor3f(0.1, 0.2, 0.3);

for(i=0; i<=n; i++, t += dt)
glVertex2f(x + r*cos(t), y + r*sin(t));

glEnd();



glBegin( GL_LINE_STRIP );
for( int i=0; i<numPoints; i++ )
{
float Angle = i * (2.0*PI/numPoints);
float X = cos( Angle )*Radius;
float Y = sin( Angle )*Radius;
glVertex2f( X, Y );
}
glEnd();


glFlush(); /* Single buffered, so needs a flush. */
}



int main (int argc, char** argv)
{
glutInit (&amp;argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (350, 100);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Facial Expression Program");


init();
glutDisplayFunc (display);
glutMainLoop ( );
}

carsten neumann
10-13-2011, 03:54 PM
Please use [ code][ /code] (without the space after '[') around source code snippets.

You are not calling drawFace() (or drawArc(), etc.) from your display function.
Oh, wait, you copied their function bodies into display() - please try to avoid posting code from the middle of a debugging session where you (pseudo) randomly moved around code, it makes it much harder to find any problem.
For example you now have:



glBegin(GL_LINE_STRIP);
glColor3f(0.1, 0.2, 0.3);
for(i=0; i<=n; i++, t += dt)
glVertex2f(x + r*cos(t), y + r*sin(t));
glEnd();


which uses dt without ever initializing it (that happened at the beginning of drawArc(), but you never call that any more). Which probably prevents it from being drawn.
FWIW I ran your program and the short line



glBegin(GL_LINES);
glVertex2i( 0, 0);
glVertex2i( 10, 10);
glEnd();


does show up in the bottom corner (it's small since you only go 10 pixel to the right and up).

drawTriangle() will draw a 1 pixel triangle so it's really hard to see. For drawArc() I did not quite understand the arguments, but I can get it to draw a tiny arc when changing display() to this:



void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);

drawTriangle();
drawArc(100, 100, 30, 0, 10);

drawCircle(100, 1000);

glFlush(); /* Single buffered, so needs a flush. */
}


As an aside, is there a reason all your variables are global ones, even loop counters like 'i'? This is a style of coding that will not scale to the size your program will end up being if you want to render facial expressions.

annette
10-14-2011, 07:33 AM
Carsten,
Thanks for the reply. I am new at coding in openGL so I'm still learning. I removed all the variables from the global section and rewrote and restructured some of the code. I still can't get my circle function to work. The triangle, arc and lines are displaying fine but I need to re-position them. How do I go about that, please. Is the something I am doing wrong with the circle function?
Thanks.
I could not locate [ code][ /code] among the menu options so I typed it. Sorry if the code looks unreadable again.



//Faical Expression Recogntion Project
//October 12, 2011


#include <Windows.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>


GLsizei winWidth = 400, winHeight = 300;
const float PI = 3.14159265;


#define MY_CIRCLE_LIST 1


void init(void)
{
glClearColor (0.0, 0.0, 1.0, 0.0);
glMatrixMode (GL_PROJECTION);
gluOrtho2D (0.0, winWidth, 0.0, winHeight);
glShadeModel (GL_SMOOTH);
}



void drawLine()
{
glBegin(GL_LINES);
glVertex2i(150, 150);
glVertex2i(200, 200);

glVertex2i(140, 140);
glVertex2i(100, 100);
glEnd();
}



void drawTriangle()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin( GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2i(50, 50);
glVertex2i(100, 50);
glVertex2i(75, 100);

glColor3f(1.0, 1.0, 0.0);
glVertex2i(70, 70);
glVertex2i(120, 70);
glVertex2i(95, 120);
glEnd();

}



void drawCircle( float Radius, float numPoints )
{
float Angle;
int i;

glNewList(MY_CIRCLE_LIST, GL_COMPILE);
glPushMatrix();
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
glColor3f(0.0f, 1.0f, 0.0f);
glLineWidth(1.0f);

glBegin( GL_LINE_LOOP );

for( i = 0; i<numPoints; i++)
{
Angle = i * (2.0*PI/numPoints); // use 360 instead of 2.0*PI if
float X = cos( Angle )*Radius; // you use d_cos and d_sin
float Y = sin( Angle )*Radius;
glVertex2f( X, Y );
}
glEnd();
glEnable(GL_TEXTURE_2D);
glPopMatrix();
glEndList();

}



void drawArc(float x, float y, float r, float t0, float sweep)
{

float t, dt; /* angle */
int n = 30; /* # of segments */
int i;

t = t0 * PI/180.0; /* radians */
dt = sweep * PI/(180*n); /* increment */

glBegin(GL_LINE_STRIP);
glColor3f(0.1, 0.2, 0.3);

for(i=0; i<=n; i++, t += dt)
glVertex2f(x + r*cos(t), y + r*sin(t));

glEnd();
}




void display(void)
{


glClear(GL_COLOR_BUFFER_BIT);

drawTriangle();
drawLine();

drawCircle(100, 1000);
drawArc(5, 5, 270, 60, 60);

glFlush(); /* Single buffered, so needs a flush. */
}



int main (int argc, char** argv)
{
glutInit (&amp;argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (350, 100); // Position the initial Window's top-left corner
glutInitWindowSize (winWidth, winHeight); // Set the initial Window's width and height
glutCreateWindow ("Facial Expression Program");// Create window with the given title

init(); // Our own OpenGL initialization
glutDisplayFunc (display); // Register callback handler for window re-paint event
glutMainLoop ( ); // Enter infinitely event-processing loop
}

carsten neumann
10-14-2011, 08:35 AM
I could not locate [ code][ /code] among the menu options so I typed it.


that's what I do, didn't know there was a menu...



void drawCircle( float Radius, float numPoints )
{
float Angle;
int i;

glNewList(MY_CIRCLE_LIST, GL_COMPILE);
glPushMatrix();
glLoadIdentity();
glDisable(GL_TEXTURE_2D);

// SNIP

glEnable(GL_TEXTURE_2D);
glPopMatrix();
glEndList();
}


Your drawCircle() function does not draw anything, it only compiles a display list. To execute the drawing commands stored in the display list you need to use glCallList().

Why are you creating a display list in the first place? If the function does not draw a circle the way you want adding the complication of display lists is not going to make it easier. First make your drawing function work, then you can worry about using display lists.
The first argument to glNewList should be a number that was allocated by a preceding call to glGenLists(), not one you pick.

You don't need the calls to glEnable/glDisable with GL_TEXTURE_2D. There are no textures used anywhere in the code you posted.

annette
10-14-2011, 12:11 PM
My final code without the GL_TEXTURE_2D works. See below. Thanks a lot.



void circle(GLint x, GLint y, GLint radius)
{
float angle;

glColor3f(0.0f, 1.0f, 0.0f);
//glLineWidth(1.0f);
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 100; i++)
{
angle = i*2*PI/100;
glVertex2f(x + (cos(angle) * radius), y + (sin(angle) * radius));
}
glEnd();

}




I have another problem, Any time I try to reposition any of the shapes, I end up with a blank screen. I figured out that the problem is with GL_LoadIdentity();

So if I type:


glLoadIdentity();
//Move 0.2 on the x axis.
glTranslatef(0.2, 0.0, 0.0);
//Half the size of the object on the x and y axis
glScaled(0.5, 0.5, 0);
//Rotate 30 degrees around the Z axis.
glRotatef(30.0, 0, 0, 1.0);
.
.
.

my code does not work. I get a blank screen.

annette
10-14-2011, 12:58 PM
I figured out why my screen was blank. It was not GL_LoadIdentity(); I didn't put the right values in GL_Translatef() and GL_Rotate() and that caused the shape to move away from the screen. I still haven't been able to reposition the objects yet but I'm working on that too. Any help will be appreciated. Thanks.

ugluk
10-15-2011, 02:01 PM
Anette, stop using the glRotate*, glTranslate* ... commands, they are obsolete. Start using shaders. There's a tut for modern opengl somwhere (google for it); do the exercises it contains then go to

http://library.nu

download some more reading material and do the exercises in them.

annette
10-17-2011, 07:31 AM
Thanks for the references. I'll take a look at them. Thanks again.