I am trying to draw a 6 sided obelisk using opengl.
Below is the code I use to model the bottom surface of the obelisk:
void drawObelisk() {
glColor3f(1.0,1.0,0.0);
glBegin(GL_POLYGON);
for ( x=0.0; x<2.0*pi/3; x=x+inc )
{
glVertex3f(0.3*cos(x),0.3*sin(x),0.0);
}
glEnd();
}
This code is used to render the model:
void myDisplay(void)
{
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
drawObelisk();
glPopMatrix();
glFlush();
}
void SetupRC(void)
{
glClearColor(0.0, 0.0, 1.0, 1.0);
glOrtho(-6.0,6.0,-6.0,6.0,-6.0,6.0);
}
void main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,15);
glutCreateWindow("Test");
glutDisplayFunc(myDisplay);
SetupRC();
glutIdleFunc(idle);
glutMainLoop();
}
For certain reasons the polygon surface that I drew didn't show up on the screen once the model is rendered.
Give this a shot:
#include <GL/glut.h>
#include <math.h>
void drawObelisk()
{
double pi = 3.14159;
double inc = (2*pi) / 6;
glColor3f(1.0,1.0,0.0);
glBegin(GL_POLYGON);
for( double theta = 0.0; theta < 2*pi; theta += inc )
{
double scale = 2.0;
double x = scale * cos( theta );
double y = scale * sin( theta );
glVertex3d(x,y,0.0);
}
glEnd();
}
void myDisplay(void)
{
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-6.0,6.0,-6.0,6.0,-6.0,6.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
drawObelisk();
glPopMatrix();
glFlush();
}
void main( int argc, char** argv )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,15);
glutCreateWindow("Test");
glutDisplayFunc(myDisplay);
glutMainLoop();
}
Things that were wonky:
Missing glutInit() call.
glClear()ing the depth buffer without requesting one via GLUT_DEPTH.
Not switching to GL_MODELVIEW after setting your projection matrix.
Original drawObelisk() for-loop only generated two vertices. GL_POLYGON needs a minimum of three.
Related
I want to know how can I make an animation that represents a rectangle with height increase/decrease in OpenGL. I know I'm supposed to use the glScale and glTranslate functions.
Below, I will attach the code that I've worked with so far, where I managed to apply a pretty basic transition of a rectangle.
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat trans = 0.0;
void init(void)
{
glClearColor(0.2, 0.2, 0.2, 0.2);
glShadeModel(GL_FLAT);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0 , trans, 1.0);
glColor3f(1.0, 1.0, 1.0);
glRectf(-25.0, -25.0, 25.0, 25.0);
glPopMatrix();
glColor3f(0.0, 0.0, 1.0);
glRectf(-15.0, -15.0, 15.0, 15.0);
glutSwapBuffers();
}
void transLeft(void)
{
trans = trans - 0.05;
if (trans < -75)
trans = -75;
glutPostRedisplay();
}
void transRight(void)
{
trans = trans + 0.05;
if (trans > 75)
trans = 75;
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0, 100.0, -100.0, 100.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(transLeft);
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(transRight);
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
So you want to have variable height rectangle (based on what?).
Yes glScale(1.0,zoom,1.0) placed directly before or after the line
glTranslatef(0.0 , trans, 1.0);
In your display(void) function will do this. Where zoom is holding your animation state and is starting with value zoom=1.0 and to change size you just increment/decrement like this: zoom*=1.025 or zoom/=1.025.
However its usually better to interchange your hard-coded rectangle vertexes with variable ones based on parameter or time or whatever you want to change this with. That way you can interpolate between min and max rectangle size with parameter without changing the matrices which might pose a problem with other objects if you not careful And also this way provides more convenient control of the animation. For example you have:
glRectf(-25.0, -25.0, 25.0, 25.0);
And want to animate it to size:
glRectf(-25.0, -35.0, 25.0, 35.0);
over time so you can do this like this:
add some global or static variables holding your rectangle sizes and position and animation state:
// x0, y0beg, y0end, x1,y1beg,y1end
float myrec[]={-25.0, -25.0, -35.0, 25.0, 25.0, 35.0};
float t=0.0; // parameter in range <0.0,1.0>
in display compute your rectangle actual coordinates and render
You can use linear interpolation like this:
glRectf(myrect[0],myrect[1]+((myrect[2]-myrect[1])*t),
myrect[3],myrect[4]+((myrect[5]-myrect[4])*t));
set you t for animation somewhere
Where depends on what you want to achieve... If you have timer or some call that si repeated again and again you can increment the t in it by some step for example:
t+=dt/T;
if (t>1.0) t=1.0; // use t=0.0; if you want to repeat the animation after it finishes
Where dt is the avg time your call is repeated with and T is the time of whole animation finish. I do not use GLUT so I just assume your Display is called repeatedly (for example 60 times per second) and want the animation to finish in 2 sec then:
// dt = 1.0/60
// T = 2.0
t+=(1.0/120.0);
if (t>1.0) t=1.0; // use t=0.0; if you want to repeat the animation after it
You can also use elapsed time (by measuring it by some OS or environment function you have at your disposal I usually use performance timer/counters on windows) from last call instead of dt.
If you have more of such rectangles you can encapsulate this to some function and simply call it with pointer to its myrect values and parameter t for example:
void draw_rect(float *myrec,float t)
{
glRectf(myrect[0],myrect[1]+((myrect[2]-myrect[1])*t),
myrect[3],myrect[4]+((myrect[5]-myrect[4])*t));
}
float rec0[]={-25.0, -25.0, -35.0, 25.0, 25.0, 35.0};
float rec1[]={-15.0, -15.0, -25.0, 15.0, 15.0, 25.0};
float t=0.0; // parameter in range <0.0,1.0>
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0 , trans, 1.0);
glColor3f(1.0, 1.0, 1.0);
draw_rect(rec0,t);
glPopMatrix();
glColor3f(0.0, 0.0, 1.0);
draw_rect(rec1,t);
glutSwapBuffers();
t+=(1.0/120.0);
if (t>1.0) t=0.0;
}
I am trying to make a Chaos Game in c using OpenGL and for some reason I am only creating a triangle and one point right now, when I am expecting to get 60,000 points. I think that this is because of the begin and end statements being inside of a for loop, and if not, then I'm not sure what is wrong. Any help solving the problem would be appreciated!
BTW the chaos game is where you start with one point, and then choose a random point on the triangle and then place a new point halfway between the chosen point and the original point and continue, and in my case I will repeat this 60,000 times. :)
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); //clears all pixels
int choice, i;
float x = 0.15, y = 0.85;
glColor3f (0.0, 0.0, 0.0); //this sets the drawing color to black
glBegin(GL_LINE_LOOP); //The triangle
glVertex3f(0.2, 0.2, 0.0);
glVertex3f(0.5, 0.8, 0.0);
glVertex3f(0.8, 0.2, 0.0);
glVertex3f(0.2, 0.2, 0.0);
glEnd();
glPointSize(3.0); //sets point size
glBegin(GL_POINTS); //this is the original point
glVertex3f(x, y, 0.0);
glEnd();
for(i=0; i<60,000; i++)
{
choice = (rand()%3);
switch(choice)
{
case 0:
x = (x + 0.5)/2; //this is the x1+x2/2 part of the midpoint theorem
y = (y + 0.8)/2; //this is the y1+y2/2 part of the midpoint theorem
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
break;
case 1:
x = (x + 0.8)/2;
y = (y + 0.2)/2;
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
break;
case 2:
x = (x + 0.2)/2;
y = (y + 0.2)/2;
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
default:
break;
}
}
glFlush ();
}
void init (void)
{
glClearColor (1.0, 1.0, 1.0, 0.0); //this sets the background color to white
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition (100, 100);
glutCreateWindow(argv[0]);
init ();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Try replacing 60,000 with 60000. In C, 60,000 evaluates to 0.
For more on the comma operator, see the Wikipedia entry on it.
I've created a program to display a lined cube on a white canvas but I am unsure how to multiple that cube into lets say? 10 x 10.
Another question is how would I go about creating the same cube in a 3D space?
Here's my code:
void drawScene(void)
{
int i, j;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -25.0);
glutWireCube(5.0); // Box.
glColor3f(1.0, 0.0, 0.0);
for(i=5; i<5; i++)
{
for (j = -5; j < 5; j++)
{
glPushMatrix();
glTranslatef(i*5, j*5, -35.0);
glColor3f(1.0, 1.0, 0);
glutSolidCube(5.0);
glColor3f(0.0, 0.0, 1.0);
glutWireCube(5.0);
glPopMatrix();
}
}
glFlush();
}
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void resize (int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10.0, 10.0, -10.0, 10.0, 10.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void KeyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500); /* Size of the Program Window */
glutInitWindowPosition(100,100);
glutCreateWindow("Box.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(KeyInput);
glutMainLoop();
return 0;
}
The glu library has a lot of useful tidbits like gluLookAt( xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup );
You can scale things using glScaled( factor ) / glScalef( factor )
You should poke around Google for some GL 1.X documentation.
Here is how I draw the line and I using mouse to draw the line
static struct
{
GLfloat p[MAX_POINTS][2];
GLuint point_cnt;
} contours [ MAX_CONTOURS ] ;
GLuint point_cnt_mouse;
point_cnt_mouse = contours[contour_cnt].point_cnt;
glColor3f( 0.0, 0.0, 0.0 );
glBegin(GL_LINES);
glLineWidth(5.0);
int i;
int j;
for(i = 0; i <= contour_cnt; i++)
{
GLuint point_cnt;
point_cnt = contours[i].point_cnt;
if (contours[i].point_cnt == 0)
{
glVertex2fv ( P );
glVertex2fv ( P );
}//if
else
{
for(j = 2; j <= point_cnt; j++)
{
glVertex2fv (contours[i].p[j-2]);
glVertex2fv (contours[i].p[j-1]);
}//for
}//else
}//for
if(point_cnt_mouse > 0)
{
glVertex2fv(contours[contour_cnt].p[point_cnt_mouse-1]);
glVertex2fv(P);
}//if
glEnd();
then I use glTexImage2D() to make GL_TEXTURE_2D then
my display is
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix ();
glTranslatef(-4.0, 5.0, -6.0);
//this is box and load texture on it
drawPlane();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void myinit()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
//load png image
drawLogo();
glDisable(GL_DEPTH_TEST);
}
Logo won't show up with lines, why? Can any one tell what is wrong with my code?
Make sure to disable texturing (glDisable(GL_TEXTURE_2D)) before drawing your line(s). And re-enable (glEnable(GL_TEXTURE_2D)) before drawing your texture.
If you're using the default GL_MODULATE texture environment make sure to set the current color to white (glColor3ub(255,255,255)) before drawing with the texture. If you draw the texture after the glColor3f( 0.0, 0.0, 0.0 ) in your line routine then GL_MODULATE will multiply all your texel RGB values by zero, giving you black everywhere.
It looks kind of suspicious to me that your display() function never calls drawLogo().
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix ();
glTranslatef(-4.0, 5.0, -6.0);
//this is box and load texture on it
drawPlane();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
I copied the following code from OpenGL's Redbook (Chapter 4: Display Lists) into my editor (Visual Studio Express Edition 2008), named it list.c and got compilation error.
#include "aux.h"
#include <GL/gl.h>
#include <GL/glu.h>
GLuint listName = 1;
void myinit (void)
{
glNewList (listName, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glBegin (GL_TRIANGLES);
glVertex2f (0.0, 0.0);
glVertex2f (1.0, 0.0);
glVertex2f (0.0, 1.0);
glEnd ();
glTranslatef (1.5, 0.0, 0.0);
glEndList ();
glShadeModel (GL_FLAT);
}
void drawLine (void)
{
glBegin (GL_LINES);
glVertex2f (0.0, 0.5);
glVertex2f (15.0, 0.5);
glEnd ();
}
void display(void)
{
GLuint i;
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
for (i = 0; i < 10; i++)
glCallList (listName);
drawLine ();
glFlush ();
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w,
1.5 * (GLfloat) h/(GLfloat) w);
else
gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, -0.5,
1.5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
auxInitPosition (0, 0, 400, 50);
auxInitWindow (argv[0]);
myinit ();
auxReshapeFunc (myReshape);
auxMainLoop(display);
}
Don't use not aux, nor glaux. They're too old. GLUT is much more easier, while many of people use SDL or SFML (they're more flexible and feature-full than GLUT). You should try SFML - it has lots of features inside, it's lightweight and portable. You should be satisfied using this one =)
Still if you wanna use GLUT, here are your problems:
glutInit() should be called before
any other operations
glutInitDisplayMode() and other
window functions must be called
before any drawing
operations
Here's some sample code:
#include <GL/glut.h >
// rendering function
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glBegin (GL_LINES);
glVertex2f (0.0, 0.5);
glVertex2f (15.0, 0.5);
glEnd ();
glFlush();
}
// some initializations
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int argc, char **argv)
{
// initialize GLUT library
glutInit(&argc, argv);
// set display mode
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// set initial window size
glutInitWindowSize(250,250);
// set initial window position
glutInitWindowPosition(100,100);
// create the window
glutCreateWindow("moofoo");
// do our initialization routines
init();
// set function which will be called each frame
glutDisplayFunc(display);
// enter main rendering loop
glutMainLoop();
return 0;
}
You need to include the Windows header file. Fix:
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
// etc...
I have changed the code placing glutXxx functions instead of auxXxx ones. It compiles but doesn't run, I'd appreciate feedback here:
#include "GL/glut.h"
#include <stdio.h>
//#include <windows.h>
GLuint listName = 1;
void myinit (void)
{
glNewList (listName, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glBegin (GL_TRIANGLES);
glVertex2f (0.0, 0.0);
glVertex2f (1.0, 0.0);
glVertex2f (0.0, 1.0);
glEnd ();
glTranslatef (1.5, 0.0, 0.0);
glEndList ();
glShadeModel (GL_FLAT);
}
void drawLine (void)
{
glBegin (GL_LINES);
glVertex2f (0.0, 0.5);
glVertex2f (15.0, 0.5);
glEnd ();
}
void display(void)
{
GLuint i;
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
for (i = 0; i < 10; i++)
glCallList (listName);
drawLine ();
glFlush ();
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w,
1.5 * (GLfloat) h/(GLfloat) w);
else
gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, -0.5,
1.5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition (100, 100);
glutInitWindowPosition (100,100);
glutInit (&argc, argv);
myinit ();
glutDisplayFunc (display);
glutReshapeFunc (myReshape);
glutMainLoop();
}