I have written the following code to print the Koch curve using OpenGL. But I am getting an inverted output. What modifications are required to invert the output in OpenGL? Also, is there any other formula to find the vertex coordinates of the equilateral triangle of the Koch curve?
#include<iostream>
#include<GL/glut.h>
#define COS 0.5
#define SIN 0.866
int x1=10,x2=550,y1=200,y2=200;
void myinit()
{
glClearColor(0.0,1.0,0.0,1.0);
glColor3f(0.0,0.0,1.0);
glPointSize(3.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,640,0,480);
}
void koch(int x1, int y1, int x2, int y2, int m)
{
int x[5],y[5],xx,yy,lx,ly;
lx=(x2-x1)/3;
ly=(y2-y1)/3;
x[0]=x1;
y[0]=y1;
x[4]=x2;
y[4]=y2;
x[1]=x[0]+lx;
y[1]=y[0]+ly;
x[3]=x[0]+2*lx;
y[3]=y[0]+2*ly;
xx=x[3]-x[1];
yy=y[3]-y[1];
x[2]=xx*(COS)+yy*(SIN);
y[2]=-xx*(SIN)+yy*(COS);
x[2]=x[1]+x[2];
y[2]=y[1]+y[2];
if(m>0)
{
koch(x[0],y[0],x[1],y[1],m-1);
koch(x[1],y[1],x[2],y[2],m-1);
koch(x[2],y[2],x[3],y[3],m-1);
koch(x[3],y[3],x[4],y[4],m-1);
}
else
{
glBegin(GL_LINES);
glVertex2d(x[0],y[0]);
glVertex2d(x[1],y[1]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[1],y[1]);
glVertex2d(x[2],y[2]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[2],y[2]);
glVertex2d(x[3],y[3]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[3],y[3]);
glVertex2d(x[4],y[4]);
glEnd();
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
koch(x1,y1,x2,y2,2);
glEnd();
glFlush();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutCreateWindow("Grllp");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}
Related
This program is able to create a window and locate my mouse when it is on the window, however the display function does seem to work. What am I missing here?
float pointSize = 10.0f;
bool leftBottState;
float xvalue;
float yvalue;
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
}
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
glEnd();
glFlush();
}
void mouse(int button, int state, int x, int y)
{
y = 600 - y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
leftBottState = true;
}
else
{
leftBottState = false;
}
}
void motion(int x, int y)
{
if (leftBottState)
{
std::cout << "LEFt bUTTON " << std::endl;
xvalue = x;
yvalue = y;
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("test");
glutMotionFunc(motion);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return(0);
}
You're using a double buffered window (see glutInitDisplayMode).
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
Therefore you must call glutSwapBuffers to swaps the buffers after rendering the scene:
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
glEnd();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
// glFlush();
glutSwapBuffers();
}
Note, a glBegin \ glEnd sequence delimits the vertices of a primitive. I recommend to call this instructions in the same function, immediately before and after specifying the vertices.
glClear clears the buffers and thus the entire scene. If you want to draw the points permanently, you have to remove the glClear instruction from the display function.
glClear(GL_COLOR_BUFFER_BIT);
I am trying to write a simple program that moves a Sphere around a Ellipse in OpenGL. I thought that if I set translate coordinates to the same as the Ellipse coordinates it would simulate motion.
This is the code I already have:
#include "stdafx.h"
#include <windows.h>
#include <GL/Gl.h>
#include <GL/GLU.h>
#include <GL/glut.h>
#include <math.h>
const float eRad = 6.5;
void drawSphere(void)
{
float x = 0.5;
float y = 0.4;
float z = 0.0;
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
// Draw the Ellipse
glColor3d(1.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (float i = 0; i <= eRad; i += 0.1)
{
glVertex2f(x*cos(i), y*sin(i));
}
glEnd();
//Draw the Sphere
glColor3d(1.0, 1.0, 0.0);
glPushMatrix();
glTranslatef(0.5, 0, 0);
glutWireSphere(0.15, 30, 30);
glPopMatrix();
glFlush();
}
void animation(void)
{
float x = 0.2;
float y = 0.1;
float z = 0.0;
for (float i = 0; i <= eRad; i += 0.1)
{
glTranslated(x*cos(i), y*sin(i), z);
}
drawSphere();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Moving Sphere Test");
glutDisplayFunc(drawSphere);
glutIdleFunc(animation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 600, 600);
glutMainLoop();
}
The issue I am having is that the Ellipse is drawn in and so is the sphere, but its just staying at one point on the ellipse. So what am I doing wrong?
Yes, you need to use the functions correctly. The animation happens in glutDisplayFunc, the state setting can happen in glutIdleFunc(It does not have to). The gultTimerFunc() callback is what you want to be called every frame. I made a few modifications to your code. But you might want to use the GLUT correctly.
const float eRad = 6.5;
static float iter = 0.0;
void drawSphere(void)
{
float x = 0.5;
float y = 0.4;
float z = 0.0;
glMatrixMode(GL_PROJECTION | GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
// Draw the Ellipse
glColor3d(1.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (float i = 0; i <= eRad; i += 0.1)
{
glVertex2f(x*cos(i), y*sin(i));
}
glEnd();
//Draw the Sphere
glColor3d(1.0, 1.0, 0.0);
glPushMatrix();
glTranslatef(x*cos(iter), y*sin(iter), 0);
glutWireSphere(0.15, 30, 30);
glPopMatrix();
glFlush();
}
void animation(void)
{
iter = (iter < 6.5) ? iter+0.0001 : 0.0;
}
void Timer(int value) {
glutTimerFunc(33, Timer, 0);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Moving Sphere Test");
glutDisplayFunc(drawSphere);
glutIdleFunc(animation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 600, 600);
Timer(0);
glutMainLoop();
}
I'm a complete novice in OpenGL and have started following a book on this topic. The first program that they demonstrate is the Sierpinski Gasket program. Here's what the code looks like in the book:
#include<GL/glut.h>
#include<stdlib.h>
void myinit()
{
//attributes
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(1.0,0.0,0.0); //draw in red
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
}
void display()
{
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glClear(GL_COLOR_BUFFER_BIT); //clear the window
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++){
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop();
return 0;
}
However, when I compile the program it only displays a window completely filled with white and nothing else. Why isn't the above code working the way it should?
Swap glFlush() for glutSwapBuffers():
#include<GL/glut.h>
void display()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT); //clear the window
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glColor3f(1.0,0.0,0.0); //draw in red
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++)
{
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
glFlush() won't actually swap the back/front buffers requested by GLUT_DOUBLE. You need glutSwapBuffers() for that.
here is my code
#include "stdafx.h"
#include <GL/glut.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <math.h>
#define pi 3.14;
float angle=3;
void reshape(int w, int h)
{
if(h==0) h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,w,0,h,-1,1);
}
void display(void)
{
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(angle++,0,1.0,1.0);
glBegin(GL_POLYGON);
glVertex2f(10,10);
glVertex2f(30,20);
glVertex2f(30,30);
glVertex2f(10,30);
glEnd();
glRotatef(angle++,0,1.0,1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(300,300);
int segments=20;
GLfloat angle=0;
for(int i=0;i<=segments; i++)
{
angle=i*2*pi; angle=angle / (segments);
glVertex2f(300+cos(angle)*30,300+sin(angle)*30);
}
glEnd();
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc , argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow("first");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutMainLoop();
return(0);
}
here the problems are
cannot see the rotation correctly just blinking the rectangle. Don't know is it rotating or not.
2.the circle is not rotating even there is code for rotation. why?
3.what change I made if I want only rectangle or circle is rotated?
1. cannot see the rotation correctly just blinking the rectangle.
You're probably running waaaaay too fast. Use a timer callback to issue glutPostRedisplay()s every 16ms or so.
2. the circle is not rotating even there is code for rotation. why?
glRotatef(angle++,0,1.0,1.0);
^^^
You're rotating outside the X/Y plane and exceeding the depth limits of your glOrtho() call resulting in clipped fragment. Bump your nearVal/farVal to accommodate:
glOrtho(0,w,0,h,-1000,1000);
3. what change I made if I want only rectangle or circle is rotated?
Remove one of the glRotatef()s.
All together:
#include <GL/glut.h>
#include <cmath>
using namespace std;
const double pi = 3.14159;
float angle=3;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho(-w,w,-h,h,-1000,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDepthMask(GL_TRUE);
//glRotatef(angle++,0,1.0,1.0);
glBegin(GL_POLYGON);
glVertex2f(10,10);
glVertex2f(30,20);
glVertex2f(30,30);
glVertex2f(10,30);
glEnd();
glRotatef(angle++,0,1.0,1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(300,300);
const int segments=20;
for(int i=0;i<=segments; i++)
{
const GLfloat angle = ( i*2*pi ) / (float)segments;
glVertex2f(300+cos(angle)*30,300+sin(angle)*30);
}
glEnd();
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main(int argc, char** argv)
{
glutInit(&argc , argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow("first");
glutDisplayFunc(display);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return(0);
}
I am trying to draw a simple square wherever I press the left mouse button using opengl/glut. My program runs perfectly except for the part where it does not draw the square where I click the left mouse button :). Can someone point out what I am doing wrong?
#include <stdlib.h>
#include <glut.h>
GLsizei WIDTH = 1300, HEIGHT = 700;
GLsizei MOUSEx, MOUSEy;
GLfloat SIDE=1;
GLfloat RED[3] = {1,0,0};
GLfloat GREEN[3] = {0,1,0};
GLfloat BLUE[3] = {0,0,1};
GLfloat WHITE[3] = {1,1,1};
GLfloat BLACK[3] = {0,0,0};
GLfloat YELLOW[3] = {1,1,0};
GLfloat CYAN[3] = {0,1,1};
GLfloat MAGENTA[3] = {1,0,1};
void drawSquare(int x, int y)
{
glColor3fv(YELLOW);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void drawSquare1()
{
int x=0,y=0;
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0,-5);
drawSquare1();
glFlush();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
WIDTH=w;
HEIGHT=h;
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1);
}
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (WIDTH, HEIGHT);
glutInitWindowPosition (10, 10);
glutCreateWindow ("New Window");
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutMouseFunc(mouse);
//glutMotionFunc(drawSquare);
glutMainLoop ();
return 0;
}
In short words: OpenGL is not a scene graph. That means that those drawing commands issued in the mouse handler don't create some kind of "persistency".
Instead clicking the mouse you should store the position in a list/array and draw the squares from the values in that list in the display function.
I am fresh to this Coding But I done it.
Here is My Code It will Work.
#include <GL/glut.h>
GLsizei MOUSEx=0, MOUSEy=0;
GLfloat SIDE=50;
GLfloat BLUE[3] = {0,0,1};
void drawSquare1()
{
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(MOUSEx, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy+SIDE,0);
glVertex3f(MOUSEx, MOUSEy+SIDE,0);
glEnd();
glFlush();
}
void display(void)
{
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawSquare1();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho(0.0,1368,768,0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void spindisplay(void)
{
glutPostRedisplay();
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
//drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1); // To Exit the Program
}
}
int main(int argc, char **argv)
{ glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1366,768);
glutInitWindowPosition(0,0);
glutCreateWindow("Moving squares");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutIdleFunc(spindisplay);
glutMainLoop();
}
Below is the sample code taken from OpenGL Projects. Try to execute this and I think the problem with your drawing squares in OpenGL would be solve easily. If any question kindly ask.
#include<stdlib.h>
#include<glut.h>
GLsizei wh=500,ww=500;
GLfloat size=3.0;
void display()
{
glFlush();
}
void myInit()
{
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
}
void myReshape(GLsizei w,GLsizei h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,w,h);
ww=w;
wh=h;
}
void drawSquare(int x,int y)
{
y=wh-y;
glBegin(GL_POLYGON);
glVertex2f(x+size,y+size);
glVertex2f(x-size,y+size);
glVertex2f(x-size,y-size);
glVertex2f(x+size,y-size);
glEnd();
glFlush();
}
void size_menu(int id)
{
switch(id)
{
case 2: size=size*2;
break;
case 3:if(size>1) size=size/2;
break;
}
glutPostRedisplay();
}
void top_menu(int id)
{
switch(id)
{
case 1:exit(0);break;
}
glutPostRedisplay();
}
void myMouse(int button,int state,int x,int y)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
drawSquare(x,y);
if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
exit(0);
}
int main(int argc,char **argv)
{
int sub_menu;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("Hierarchical Menus to Draw Squares");
glutDisplayFunc(display);
myInit();
glutMouseFunc(myMouse);
sub_menu=glutCreateMenu(size_menu);
glutAddMenuEntry("Increase Square Size",2);
glutAddMenuEntry("Decrease Square Size",3);
glutCreateMenu(top_menu);
glutAddMenuEntry("Quit",1);
glutAddSubMenu("Resize",sub_menu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutReshapeFunc(myReshape);
glClear(GL_COLOR_BUFFER_BIT);
glutMainLoop();
return 0;
}