I am trying to generate the Sierpinski Gasket using a function that draws dot patterns and will generate the gasket.
But when I compile and run the program it displays nothing but black screen. What's causing the problem?
Here is my code:
#include <Windows.h>
#include <gl/GL.h>
#include <glut.h>
void myInit(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
class GLintPoint {
public:
GLint x, y;
};
int random(int m) {
return rand() % m;
}
void drawDot(GLint x, GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void Sierpinski(void) {
GLintPoint T[3] = {{ 10, 10 }, {300, 30}, {200, 300}};
int index = random(3);
GLintPoint point = T[index];
for (int i = 0; i < 1000; i++)
{
index = random(3);
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot(point.x, point.y);
}
glFlush();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 150);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(drawDot);
myInit();
glutMainLoop();
}
If you want to draw black dots on a white background, then you have to clear glClear the background:
glClear( GL_COLOR_BUFFER_BIT );
Note, glClearColor sets the color which is used to clear the view port, but doesn't clear anything itself.
Your code should look somehow like this:
void drawDot(GLint x, GLint y)
{
glVertex2i(x, y);
}
void Sierpinski(void) {
GLintPoint T[3] = {{ 10, 10 }, {300, 30}, {200, 300}};
int index = random(3);
GLintPoint point = T[index];
glClearColor(1.0, 1.0, 1.0, 1.0); // set up white clear color
glClear( GL_COLOR_BUFFER_BIT ); // clear the back ground (white)
glMatrixMode( GL_MODELVIEW );
glPushMatrix(); // setup model matrix
glScalef( 1.5f, 1.5f, 1.0f ); // scale the point distribution
glColor3f( 0.0f, 0.0f, 0.0f ); // set black draw color
glPointSize( 5.0f ); // set the size of the points
glBegin(GL_POINTS);
for (int i = 0; i < 1000; i++)
{
index = random(3);
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot(point.x, point.y);
}
glEnd();
glPopMatrix(); // reset model matrix
glFlush();
}
Related
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 trying to code a camera with glTranslate/glRotate. To implement the look-up / look-down functions I need all the objects in my rendering space to rotate around a point (that is, where the "camera" is at), point which usually differs from the origin. Still, things keep rotating around the origin. Is there a way to specify a different point?
EDIT: Added code
Thanks for your fast reply. It seems that I can't get it working right no matter what, so I've decided to add my code; I'd much appreciate if someone could take a look at it and tell me what changes are needed in order to translate/rotate/translate back.
#include <iostream>
#include <cmath>
#include <GLUT/GLUT.h>
const double roaming_step = .13;
double z_offset = .0;
double y_offset = .0;
double x_offset = .0;
const double angle_step = 1.5;
double angle_xz = .0;
double angle_yz = .0;
bool keyStates[256] = { false };
void drawFloor()
{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glVertex3f(-3.0, -1.0, 3.0);
glVertex3f(-3.0, -1.0, -3.0);
glVertex3f(3.0, -1.0, -3.0);
glVertex3f(3.0, -1.0, 3.0);
glEnd();
}
void drawBalls()
{
glTranslatef(-3.0, -.5, -3.0);
glColor3f(.8, .1, .1);
for(int i = 0; i < 3; i++)
{
glPushMatrix();
glTranslatef(.0, -.5, i * 3);
for(int j = 0; j < 3; j++)
{
glPushMatrix();
glTranslatef(j * 3, .0, .0);
glutSolidSphere(.5, 20, 20);
glPopMatrix();
}
glPopMatrix();
}
}
void keyPressed(unsigned char key, int x, int y)
{
keyStates[key] = true;
}
void keyReleased(unsigned char key, int x, int y)
{
keyStates[key] = false;
}
void keyboardOperations()
{
if(keyStates['w'])
z_offset += roaming_step;
if(keyStates['s'])
z_offset -= roaming_step;
if(keyStates['a'])
x_offset += roaming_step;
if(keyStates['d'])
x_offset -= roaming_step;
if(keyStates['i'])
{
angle_xz -= angle_step;
if(angle_xz < .0)
angle_xz += 360.0;
}
if(keyStates['o'])
{
angle_xz += angle_step;
if(angle_xz >= 360.0)
angle_xz -= 360.0;
}
if(keyStates['u'])
{
angle_yz -= angle_step;
if(angle_yz < .0)
angle_yz += 360.0;
}
if(keyStates['j'])
{
angle_yz += angle_step;
if(angle_yz >= 360.0)
angle_yz -= 360.0;
}
if(keyStates['q'])
exit(0);
}
// I guess it has to be done in this function
// but didn't get how
void camera()
{
glLoadIdentity();
// Forward / Backward
glTranslated(.0, .0, z_offset);
// Left / Right
glTranslated(x_offset, .0, .0);
// XZ Rotation
glRotated(angle_xz, .0, 1.0, .0);
// YZ Rotation
glRotated(angle_yz, 1.0, .0, .0);
}
void display(void)
{
keyboardOperations();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera();
drawFloor();
drawBalls();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
GLdouble aspect = (GLdouble) width / (GLdouble) height;
gluPerspective(60, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("openGLtest3");
glClearColor(.0, .0, .0, .0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutIgnoreKeyRepeat(true);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyReleased);
glutMainLoop();
return 0;
}
In openGL, glRotation fuction takes origin as a reference. In order to rotate around a point (your camera coordinate in this case) you should translate your camera position to the origin (Translate all your objects accordingly) and then apply rotation function.And then you can translate your camera back (with all your objects)
lets say your camera position is (a,b,c) so your code should be something like :
foreach object
{
glPushMatrix();
glTranslate(a,b,c);
glRotate(...);
glTranslate(-a,-b,-c);
//render
glPopMatrix();
}
My OpenGL program is not working properly. Inside the drawScene() function I created two loops. One loop for GL_LINES another loop for GL_POINTS. The GL_LINES loop works fine but GL_POINTS loop doesn't work. Any help appreciated.
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define PI 3.14159265
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 0.0f;
float _cameraAngle = 0.0f;
float x = -1.5;
float y = -0.5;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLineWidth (9.0f);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
double r = 0.5;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glPointSize (7.0f);
glBegin(GL_POINTS);
glColor3f(0.0f, 1.0f, 0.0f);
double r = 1.0;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
//glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glutSwapBuffers();
//glutPostRedisplay();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(60, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("two circle");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Right now, you're declaring the variable r in two places: where you set double r = 0.5; and at double r = 1.0;
Try changing it to:
double r = 0.5;
//First loop
r = 1.0;
//Second loop
I never got the concept down on how to get an animation working in OpenGL. I was working on his project trying to get it to work but never got the skier to move. Trying to figure out how to get this fixed.
#include "../shared/gltools.h" // OpenGL toolkit
#define PI 3.14159265
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
bool lookUp;
bool setback;
bool lookDown;
bool lookLeft;
bool lookRight;
bool walkForward;
bool walkBackward;
bool strafeLeft;
bool strafeRight;
float xTranslation;
float yTranslation;
float zTranslation;
float yRotationAngle;
float zRotationAngle;
float xRotationAngle;
int mouseLastx;
int mouseLasty;
float sunRotationAngle=0;
float sunRadius = 150.0;
float day=0;
float dusk=1;
// Light values and coordinates
GLfloat lightPos[] = { 0.0f, 30.0f, 0.0f, 1.0f };
GLfloat lightPos2[] = { 0.0f, 0.0f, 40.0f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specular2[] = { 0.0f, 1.0f, 0.0f, 1.0f};
GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat diffuse2[] = { 0.0f, 0.3f, 0.0f, 1.0f};
GLloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};
GLfloat spotDir[] = { 0.0f, 0.0f, -1.0f };
void mouseMovement(int x, int y)
{
int mouseDiffx=x-mouseLastx;
int mouseDiffy=y-mouseLasty;
mouseLastx=x;
mouseLasty=y; //set lasty to the current y position
xRotationAngle += (GLfloat) mouseDiffy;
yRotationAngle += (GLfloat) mouseDiffx;
if (xRotationAngle>=90)
xRotationAngle=90;
if (xRotationAngle<=-90)
xRotationAngle=-90;
//cout << "x:" << x << "y:" << y << endl;
}
void drawcabin()
{
glColor3ub(0, 0, 0);
glBegin(GL_TRIANGLES);
//glTranslatef(0,-5,0); // move view left
//glNormal3f(-3,0.7,-1.7);
//glutSolidCube(5.0f);
glNormal3d(0,0.7,0.7);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glNormal3d(2,-1,1);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glTranslatef(0,-5,0); // move view left
glNormal3d(-3,0.7,-1.7);
glEnd();
glColor3ub(185, 0, 0);
glutSolidCube(5.0f);
}
void drawskislope()
{
glColor3ub(0, 0, 0);
glBegin(GL_QUADS);
glTranslatef(0,-5,90); // move view left
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
glVertex3d(10,0,5);
glVertex3d(10,.5,5);
glVertex3d(15,.5,5);
glVertex3d(15,0,5);//small square
glColor3ub(201, 192, 187);
glVertex3d(11.5,.5,5);
glVertex3d(13.5,.5,5);
glVertex3d(13.5,-10,5);
glVertex3d(11.5,-10,5);
//slope start
glTranslatef(0,-5,0); // move view left
// glNormal3d(-3,0.7,-1.7);
glEnd();
}
void drawskier()
{
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
glBegin(GL_QUADS);
glTranslatef(0,-5,0); // move view
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
//Do While loop
// do
// {
// to move skier do a loop and update a in the translate
glTranslatef(0,a,0); // move view
glVertex3d(c,0,5);//10
glVertex3d(c,.1,5);//10
glVertex3d(b,.1,5);//15
glVertex3d(b,0,5);//skis on skier
glNormal3d(0,5,1);
glVertex3d(d,0,5);
glVertex3d(d,1.35,5);
glVertex3d(e,1.35,5);
glVertex3d(e,0,5);//body on skier
glutSwapBuffers;
// }while(b>15); //try to animate
glEnd();
glFlush();
b=b-1;
c=c-1;
d=d-1;
e=e-1;
glutPostRedisplay();
glTranslatef(30,3,0); // move view left
glColor3ub(168, 220, 109);
glutSolidSphere(.5,7,8); //sphere-head
glPushMatrix();
glTranslatef(3.5,-100,2);
glutSolidSphere(25,15,15); //sphere
glPopMatrix();
}
void updatescene()
{
}
///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
GLUquadricObj *pObj; // Quadric Object
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
GLfloat horizontalMovement=1;
GLfloat verticalMovement=0;
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
if (lookDown)
{
xRotationAngle+=1;
if (xRotationAngle>=90)
xRotationAngle=90;
}
if (lookUp)
{
xRotationAngle-=1;
if (xRotationAngle<=-90)
xRotationAngle=-90;
}
if (lookRight)
{
yRotationAngle+=1;
if (yRotationAngle>=360)
yRotationAngle=0;
}
if (lookLeft)
{
yRotationAngle-=1;
if (yRotationAngle<=-360)
yRotationAngle=0;
}
if (walkForward)
{
zTranslation+=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation-=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation-=verticalMovement;
}
if (walkBackward)
{
zTranslation-=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation+=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation+=verticalMovement;
}
if (strafeRight)
{
zTranslation+=cos((yRotationAngle+90)*PI/180);
xTranslation-=sin((yRotationAngle+90)*PI/180);
}
if (strafeLeft)
{
zTranslation-=cos((yRotationAngle+90)*PI/180);
xTranslation+=sin((yRotationAngle+90)*PI/180);
}
if (setback)
{
zTranslation=0;
xTranslation=0;
yTranslation=0;
}
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(xRotationAngle,1,0,0);
glRotatef(zRotationAngle,0,0,1);
glRotatef(yRotationAngle,0,1,0);
glTranslatef(xTranslation,yTranslation,zTranslation);
//glRotatef(-15,1,0,0);
//glRotatef(90,0,1,0);
glTranslatef(0,-0.50,-10);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
sunRotationAngle++;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(0,0,0);
glLineWidth(2);
//snow
glColor3ub(255, 255, 255);
glBegin(GL_QUADS);
glNormal3f(0,1,0);
for (int i=-100;i<=200;i+=10) //x
for (int j=-100;j<=200;j+=10)//z
{
float y1=(-j)*.25;
float y2=(-j+10)*.25;
glVertex3d(i+10,y2,-100);
glVertex3d(i,y2,-100);
glVertex3d(i,y1,-100);
glVertex3d(i+10,y1,-100);
}
glEnd();
glPushMatrix();
glTranslatef(-10,14,-50);
drawcabin();
drawskislope();
drawskier();
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
glutPostRedisplay();
//GLfloat horizontalMovement=1;
// GLfloat verticalMovement=0;
}
void TimerFunction(int value)
{
// Redraw the scene with new coordinates
glutPostRedisplay();
updatescene();
glutTimerFunc(16,TimerFunction, 1);
}
///////////////////////////////////////////////////////////
// Setup the rendering context
void SetupRC(void)
{
lookUp=false;
lookDown=false;
lookLeft=false;
lookRight=false;
walkForward=false;
walkBackward=false;
strafeLeft=false;
strafeRight=false;
yRotationAngle=0;
xRotationAngle=0;
zRotationAngle=0;
xTranslation=0;
yTranslation=0;
zTranslation=0;
// White background
glClearColor(0.5f,0.95f, 1.0f, 1.0f );
// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
// Set color shading model to flat
glShadeModel(GL_SMOOTH);
// Clock wise wound polygons are front facing, this is reversed
// because we are using triangle fans
glFrontFace(GL_CCW);
glEnable (GL_DEPTH_TEST);
}
void ChangeSize(int w, int h)
{
//GLfloat nRange = 100.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
GLfloat fAspect;
fAspect = (GLfloat)w / (GLfloat)h;
//glOrtho(-10,10,-10,10,0,1000);
gluPerspective(45,fAspect,0.1,1000);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=true;
if(key == GLUT_KEY_DOWN)
lookDown=true;
if(key == GLUT_KEY_LEFT)
lookLeft=true;
if(key == GLUT_KEY_RIGHT)
lookRight=true;
// Refresh the Window
glutPostRedisplay();
}
void SpecialKeysUp(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=false;
if(key == GLUT_KEY_DOWN)
lookDown=false;
if(key == GLUT_KEY_LEFT)
lookLeft=false;
if(key == GLUT_KEY_RIGHT)
lookRight=false;
// Refresh the Window
glutPostRedisplay();
}
void keyboardFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=true;
break;
case 's':
walkBackward=true;
break;
case 'a':
strafeLeft=true;
break;
case 'd':
strafeRight=true;
break;
case 'r':
setback=true;
break;
default:
break;
}
}
void keyboardUpFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=false;
break;
case 's':
walkBackward=false;
break;
case 'a':
strafeLeft=false;
break;
case 'd':
strafeRight=false;
break;
default:
break;
}
}
///////////////////////////////////////////////////////////
// Main program entry point
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("Assignment 2");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
glutSpecialUpFunc(SpecialKeysUp);
glutKeyboardUpFunc(keyboardUpFunc);
glutKeyboardFunc(keyboardFunc);
glutPassiveMotionFunc(mouseMovement);
SetupRC();
glutMainLoop();
return 0;
}
My general approach is to use a glutTimerFunc() callback to post a redisplay event every 16 milliseconds or so (~60 FPS).
Then in the glutDisplayFunc() callback you can grab the new GLUT_ELAPSED_TIME to calculate a delta-time (dt) from the last frame.
With dt in hand you can update any number of variables such as angles or translation offsets. You'll want to use dt instead of fixed increment values to decouple your animation speed from your framerate.
Then back in the glutDisplayFunc() callback you draw a new frame using the updated state variables.
This is an example that uses the method above to rotate a square at about 30 degrees per second:
#include <GL/glut.h>
float angle = 0;
void update( const double dt )
{
// in degrees per second
const float SPEED = 30.0f;
// update angle
angle += ( SPEED * dt );
}
void display()
{
// GLUT_ELAPSED_TIME is in milliseconds
static int prvMs = glutGet( GLUT_ELAPSED_TIME );
const int curMs = glutGet( GLUT_ELAPSED_TIME );
// dt is in seconds
const double dt = ( curMs - prvMs ) / 1000.0;
prvMs = curMs;
// update world state
update( dt );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// reset projection/modelview matrices each frame;
// this makes sure we have a known-good matrix
// stack each time through display()
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw rotated square
glRotatef( angle, 0, 0, 1 );
glBegin( GL_QUADS );
glColor3ub( 255, 0, 0 );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
this is my cube. Once created, it has a random x position on either -2, -1, 0, 1, or 2.
void cube(void)
{
srand (time(0));
int cube_posX;
int lowv = -2;
int highv = 2;
cube_posX = rand() % (highv - lowv + 1) + lowv;
glTranslatef(cube_posX, 0.0, cube_angle);
glRotatef(cube_angle, 90.0, 0.0, 1.0);
glutSolidCube(0.25);
}
and this is how I move the cube slowly forward
void MOVE_CUBE(int value)
{
cube_posZ = cube_posZ - 0.01;
glutPostRedisplay();
glutTimerFunc(25, MOVE_CUBE, 0);
}
and finally putting them in display:
void init(void)
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
float cam_eyeX = 0.0, cam_eyeY = 1.5, cam_eyeZ = 5.0;
float cam_centerX = 0.0, cam_centerY = 0.0, cam_centerZ = 0.0;
void display(void)
{
glClearColor(1.0,1.0,1.0,1.0); //to add background color (white)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0); //camera! (cam position X, cam position Y, cam position Z, cam target X, cam target Y, cam target Z, up position X, up position Y, up position Z)
cube();
glutSwapBuffers();
angle += 0.05; //to affect the glRotate function
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);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // Set up display buffer
glutInitWindowSize(750, 500); //window's size
glutInitWindowPosition(100, 100); //window's position
glutCreateWindow("Hendra Ganteng!"); //window's title
init();
glutDisplayFunc(display);
glutIdleFunc (display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard_Handler);
MOVE_CUBE(0);
glutMainLoop();
return 0;
}
But when I see it in action, the cube moves forward flawlessly, but keeps changing x position onto those 5 possibilities (-2,-1,0,1,2) every 0.5 to 1 second. If I disable the srand(time(0)), the cube changes its x position rapidly. I just want to make it stay in 1 x position so then I can call more cubes in different x position. Could someone please kindly what's wrong in my code?
How is that behaviour not expected? You are generating a random X position every time you display your cube. If you re-seed the random number generator using the time, then it will be start a different sequence whenever the time changes (once per second).
Instead, you should pre-generate your cube(s). How about this:
// Global cube data
struct Cube {
int x;
double angle;
};
vector<Cube> cubes;
const int num_cubes = 1;
// Example initialisation...
void InitCubes()
{
cubes.reserve(num_cubes);
for( int i = 0; i < num_cubes; i++ )
{
Cube cube;
cube.x = rand() % (highv - lowv + 1) + lowv;
cube.angle = 0.0;
cubes.push_back(cube);
}
}
Now the update/display cycles simply need to modify the angle, but not the x-position.
void UpdateCube( Cube & cube )
{
cube.angle += 0.05;
}
void DisplayCube( Cube & cube )
{
glTranslatef((double)cube.x, 0.0, cube.angle);
glRotatef(cube.angle, 90.0, 0.0, 1.0);
glutSolidCube(0.25);
}
In your main function, call InitCubes() during startup.
In your display function, do this:
void display(void)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(cam_eyeX, cam_eyeY, cam_eyeZ, cam_centerX, cam_centerY, cam_centerZ, 0.0, 1.0, 0.0);
// Display cubes
for( int i = 0; i < cubes.size(); i++ ) DisplayCube( cubes[i] );
glutSwapBuffers();
glFlush();
// Update cubes for next render cycle.
for( int i = 0; i < cubes.size(); i++ ) UpdateCube( cubes[i] );
}