Reputation: 47
I am having trouble with this code. I want it to fire fireworks that explode and fall in front of a static background. Right now the fireworks and background work, but together they cause a flickering and the fireworks don't fall at a regular rate. How do I prevent this flickering and achieve a regular rate of firework's fall?
#include <GL/freeglut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include "Header.h"
using namespace std;
#define M_PI (3.1415926535897932384626433832795)
GLfloat randomNum()
{
return (rand() % 10000) / 10000.0;
}
GLfloat nx = 0;
GLfloat ny = .8;
#define MAX_POINTS 750
GLfloat numPoints;
GLfloat curx, cury;
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
GLfloat red, green, blue;
int step; int length;
GLfloat newRed = 0;
GLfloat newGreen = 0;
GLfloat newBlue = 0;
GLint totPor = 0;
GLint strontiumPor = 0;
GLfloat bariumPor = 0;
GLfloat copperPor = 0;
GLfloat sodiumPor = 0;
GLfloat phosPor = 0;
GLfloat red2;
GLfloat green2;
GLfloat green3;
GLfloat blue2;
void initialize()
{
int j; double temp, temp2;
numPoints = randomNum()*(MAX_POINTS - 1);
curx = nx;
cury = ny;
//Color Mixing
if (totPor != 0)
{
red = newRed * strontiumPor / (totPor - strontiumPor); //s red
green = newGreen * bariumPor / (totPor - bariumPor); //b green
blue = newBlue * copperPor / (totPor - copperPor); //c blue
red2 = newRed * sodiumPor / (totPor - sodiumPor); //d yellow
green2 = newGreen * sodiumPor / (totPor - sodiumPor);
green3 = newGreen * phosPor / (totPor - phosPor); //p blue green
blue2 = newBlue * phosPor / (totPor - phosPor);
red = red + red2;
green = green + green2 + green3;
blue = blue + blue2;
}
else
{
red = newRed;
green = newGreen;
blue = newBlue;
}
glPointSize(1.7);
step = 0;
length = 500 + 300 * randomNum();
/* initialize the blast */
for (j = 0; j<numPoints; j++) {
x[j] = curx;
y[j] = cury;
temp = randomNum();
temp2 = randomNum()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp) / length;
yacc[j] = (sin(temp2) * temp) / length;
}
}
void draw_fireworks(void)
{
int i;
double glow = (length - (step)) / (double)length;
glColor3f(red*glow, green*glow, blue*glow); //glow
glBegin(GL_POINTS);
for (i = 0; i<numPoints; i++) {
x[i] += xacc[i];
y[i] += yacc[i];
glVertex2f(x[i], y[i]);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
if (step < 0.9*length) {
for (i = 0; i<numPoints; i++)
yacc[i] -= 0.02 / length; // gravity
draw_fireworks();
}
step++;
if (step > length) initialize();
DrawScene();
glutSwapBuffers();
}
int t = 0;
void idle(void)
{
if (t == 45000)
{
glutPostRedisplay();
t = 0;
}
t++;
}
void SpecialKey(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT:
/* Move fireworks left or right, up or down */
nx = nx + -.025;
break;
case GLUT_KEY_RIGHT:
nx = nx + .025;
break;
case GLUT_KEY_UP:
ny = ny + .025;
break;
case GLUT_KEY_DOWN:
ny = ny + -.025;
break;
}
glutPostRedisplay();
}
void Keyboard(unsigned char key, int x, int y)
{
//Select Chemicals
switch (key)
{
case 's':
newRed = 1;
strontiumPor = strontiumPor + 1;
totPor = totPor + 1;
break;
case 'b':
newGreen = 1;
bariumPor = bariumPor + 1;
totPor = totPor + 1;
break;
case 'c':
newBlue = 1;
copperPor = copperPor + 1;
totPor = totPor + 1;
break;
case 'd':
newRed = 1;
newGreen = 1;
sodiumPor = sodiumPor + 1;
totPor = totPor + 1;
break;
case 'p':
newBlue = 1;
newGreen = 1;
phosPor = phosPor + 1;
totPor = totPor + 1;
break;
case 'R': newRed = newRed + .1;
break;
case 'G': newGreen = newGreen + .1;
break;
case 'B': newBlue = newBlue + .1;
break;
case ' ': //Space bar is Reset or start
newRed = 1;
newGreen = 1;
newBlue = 1;
totPor = 0;
strontiumPor = 0;
bariumPor = 0;
copperPor = 0;
sodiumPor = 0;
phosPor = 0;
break;
case 'm': nx = 0; ny = 0.8; //M resets target to default
break;
case 'q': exit(0); //Q is quit
}
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0,
-1.0*(GLfloat)h / (GLfloat)w, 1.0*(GLfloat)h / (GLfloat)w,
-1.0, 1.0);
else
glOrtho(-1.0*(GLfloat)w / (GLfloat)h, 1.0*(GLfloat)w / (GLfloat)h,
-1.0, 1.0,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(700, 700);
glutInitWindowPosition(0, 0);
glutCreateWindow("Fireworks Display");
glClearColor(0.0, 0.0, 0.0, 0.0);
initialize();
initText();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SpecialKey);
glutMainLoop();
return 0;
}
And then also this:
#include <GL/freeglut.h>
#include "Soil.h"
GLuint tex_ID;
void LoadTextureMap()
{
int width, height, channels;
unsigned char* image = SOIL_load_image("washington.png", &width, &height, &channels, SOIL_LOAD_AUTO);
glGenTextures(1, &tex_ID);
glBindTexture(GL_TEXTURE_2D, tex_ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
}
void Tree(GLfloat x, GLfloat y, GLfloat z)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_ID);
glPushMatrix();
glRotatef(180, 0.0f, 0.0f, 1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0 + x, -1.0 + y, 1.0 + z);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0 + x, 1.0 + y, 1.0 + z);
glTexCoord2f(1.0, 1.0); glVertex3f(1 + x, 1.0 + y, 1.0 + z);
glTexCoord2f(1.0, 0.0); glVertex3f(1 + x, -1.0 + y, 1.0 + z);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
void DrawScene()
{
Tree(0, 0, 0);
}
void initText()
{
LoadTextureMap();
}
Upvotes: 1
Views: 412
Reputation: 47865
You're calling glutSwapBuffers() in draw_fireworks() and also in display(). You should call it only once per frame.
Btw, if you want to learn OpenGL don't waste your time with this legacy fixed function pipeline stuff. Go with shaders instead.
Upvotes: 1