[英]Problems rendering particles in openGL
我開始使用 glut 在 OpenGL 中編寫一個小粒子噴泉。 我已經讓粒子出現並在屏幕上反彈,就像我想要的那樣。 所以當我第一次運行程序時,我得到了這個
並在大約 2 秒后更改為
我嘗試弄亂代碼以查看導致此問題的原因,但我無法解決。
到目前為止,這是我在程序中所擁有的
void Render_particle() //渲染粒子,該函數在DrawGLScene()函數中調用。
void idle()// 空閑函數,調用 Adjust_particles 和 Activate_particles,后跟 glutPostRedisplay()
這是完整的代碼:
// particle_fountain.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdlib.h>
#include <stdio.h>
#include<Windows.h>
#include <time.h>
#include <GL\glut.h>
#include<GL\GLU.h>
#define MAX_PARTICLES 100
#define MAX_BOUNCE_COUNT 10
#define MAX_PARTICLE_AGE 50
//Colours
float R = 0.8f;
float G = 0.2f;
float B = 0.0f;
float cR = 0.001f;
float cG = 0.002f;
float cB = 0.003f;
float Size = 0.01f; //size for points
GLuint txParticle;
GLuint txPlane;
struct PARTICLE {
float X,Y,Z; // Current position
float sX,sY,sZ; // Current Speed/Movement
float tX,tY,tZ; // Target Speed/Movement
float R,B,G; // Particle Colour
bool Active; // Is particle Active
int Age; // Age of the particle
int MaxAge; // Maximum Age before particle dies
int BounceCount;
} Particles[MAX_PARTICLES];
void Init_Particles();
void Activate_Particles();
void Adjust_Particles();
void Render_Particles();
bool LoadBitmapTexture(char * FileName, GLuint &texid);
void idle();
void DrawGLscene();
void Reshape(GLsizei w, GLsizei h);
int main(int argc, char** argv){
glutInit(&argc,argv);
glutCreateWindow("Particle fountain");
Init_Particles();
glTranslatef(0.0f, -0.7f, 0.0f);
glutDisplayFunc(Render_Particles);
glutIdleFunc(idle);
glutMainLoop();
}
void idle(){
Activate_Particles();
Adjust_Particles();
glutPostRedisplay();
}
void Init_Particles(){
int p;
srand((int)time(NULL));
for(p=0; p<MAX_PARTICLES; p++){
Particles[p].Active = FALSE;
Particles[p].tX = 0.0f;
Particles[p].tY = -0.1f;
Particles[p].tZ = 0.0f;
}
}
void Activate_Particles(){
int p;
for(p=0; p<MAX_PARTICLES; p++){
if(!Particles[p].Active){
// Start the particle at 0,0,0 origin
Particles[p].X = 0.0f;
Particles[p].Y = 0.0f;
Particles[p].Z = 0.0f;
// The following lines set a random speed value
Particles[p].sX = (((float)((rand() % 100) + 1)) /
1000.0f) - 0.05f;
Particles[p].sY = (((float)((rand() % 100) + 50)) /
500.0f);
Particles[p].sZ = (((float)((rand() % 100) + 1)) /
1000.0f) - 0.05f;
// We also activate the particle
Particles[p].Active = true;
// Set it's Age to zero
Particles[p].Age = 0;
// We also assign a max age to the particles
Particles[p].MaxAge = MAX_PARTICLE_AGE;
// We Also reset the bouncecount to zero
Particles[p].BounceCount = 0;
return;
}
}
}
void Adjust_Particles(){
int p;
for(p=0; p<MAX_PARTICLES; p++){
// We move the speed towards the target speed by 1/20 (5%)
Particles[p].sX+= (Particles[p].tX - Particles[p].sX) / 20.0f;
Particles[p].sY+= (Particles[p].tY - Particles[p].sY) / 20.0f;
Particles[p].sZ+= (Particles[p].tZ - Particles[p].sZ) / 20.0f;
// Then we adjust the position of
// the particle by the new speed
Particles[p].X+= Particles[p].sX;
Particles[p].Y+= Particles[p].sY;
Particles[p].Z+= Particles[p].sZ;
// Now for the bounce code.
if(Particles[p].Y < 0.0f){
Particles[p].Y = 0.0f;
Particles[p].sY = -Particles[p].sY;
Particles[p].BounceCount++;
if(Particles[p].BounceCount > MAX_BOUNCE_COUNT){
Particles[p].Active = FALSE;
}
}
// And finally the age check
Particles[p].Age++;
if(Particles[p].Age > Particles[p].MaxAge){
Particles[p].Active = FALSE;
}
}
}
void Render_Particles(){
int p;
glBegin(GL_POINTS);
for(p=0; p<MAX_PARTICLES; p++){
if(Particles[p].Active){
glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
glVertex3f(Particles[p].X,
Particles[p].Y,
Particles[p].Z);
}
}
glEnd();
glFlush();
}
在繪制之前添加了 16ms 刷新和glClear()
:
// g++ main.cpp -o main -lglut -lGL
#include <GL/glut.h>
#define MAX_PARTICLES 100
#define MAX_BOUNCE_COUNT 10
#define MAX_PARTICLE_AGE 50
struct PARTICLE
{
float X,Y,Z; // Current position
float sX,sY,sZ; // Current Speed/Movement
float tX,tY,tZ; // Target Speed/Movement
float R,B,G; // Particle Colour
bool Active; // Is particle Active
int Age; // Age of the particle
int MaxAge; // Maximum Age before particle dies
int BounceCount;
} Particles[MAX_PARTICLES];
void Init_Particles()
{
srand(0);
for(unsigned int p=0; p<MAX_PARTICLES; p++)
{
Particles[p].Active = false;
Particles[p].tX = 0.0f;
Particles[p].tY = -0.1f;
Particles[p].tZ = 0.0f;
}
}
void Activate_Particles()
{
for(unsigned int p=0; p<MAX_PARTICLES; p++)
{
if(!Particles[p].Active)
{
// Start the particle at 0,0,0 origin
Particles[p].X = 0.0f;
Particles[p].Y = 0.0f;
Particles[p].Z = 0.0f;
// The following lines set a random speed value
Particles[p].sX = (((float)((rand() % 100) + 1)) / 1000.0f) - 0.05f;
Particles[p].sY = (((float)((rand() % 100) + 50)) / 500.0f);
Particles[p].sZ = (((float)((rand() % 100) + 1)) / 1000.0f) - 0.05f;
// We also activate the particle
Particles[p].Active = true;
// Set it's Age to zero
Particles[p].Age = 0;
// We also assign a max age to the particles
Particles[p].MaxAge = MAX_PARTICLE_AGE;
// We Also reset the bouncecount to zero
Particles[p].BounceCount = 0;
return;
}
}
}
void Adjust_Particles()
{
for(unsigned int p=0; p<MAX_PARTICLES; p++)
{
// We move the speed towards the target speed by 1/20 (5%)
Particles[p].sX+= (Particles[p].tX - Particles[p].sX) / 20.0f;
Particles[p].sY+= (Particles[p].tY - Particles[p].sY) / 20.0f;
Particles[p].sZ+= (Particles[p].tZ - Particles[p].sZ) / 20.0f;
// Then we adjust the position of
// the particle by the new speed
Particles[p].X+= Particles[p].sX;
Particles[p].Y+= Particles[p].sY;
Particles[p].Z+= Particles[p].sZ;
// Now for the bounce code.
if(Particles[p].Y < 0.0f)
{
Particles[p].Y = 0.0f;
Particles[p].sY = -Particles[p].sY;
Particles[p].BounceCount++;
if(Particles[p].BounceCount > MAX_BOUNCE_COUNT)
{
Particles[p].Active = false;
}
}
// And finally the age check
Particles[p].Age++;
if(Particles[p].Age > Particles[p].MaxAge)
{
Particles[p].Active = false;
}
}
}
void Render_Particles()
{
Activate_Particles();
Adjust_Particles();
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_POINTS);
for(unsigned int p=0; p<MAX_PARTICLES; p++)
{
if(Particles[p].Active)
{
glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
glVertex3f(Particles[p].X, Particles[p].Y, Particles[p].Z);
}
}
glEnd();
glutSwapBuffers();
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode( GLUT_RGBA| GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow("Particle fountain");
Init_Particles();
glTranslatef(0.0f, -0.7f, 0.0f);
glutDisplayFunc(Render_Particles);
glutTimerFunc(0, timer, 0);
glutMainLoop();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.