2012-11-24 58 views
2

我在openGL中做了一個粒子噴泉,我的粒子運行正常。我決定增加一架飛機,讓它看起來像是在反彈。我想要得到的是這樣的 enter image description hereOpenGL平面沒有顯示

不幸的是什麼,我得到的是這種

enter image description here

平原似乎並沒有在所有出現。我試圖搞亂座標,似乎沒有做任何事情。 This是我用作紋理的圖像,它是一個256 X 256 24位bmp。

我加載紋理在init函數,然後調用它之前,我使顆粒在以下功能

void Load_Plane(){ 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 
    glColor4f(0.0f, 0.2f, 0.2f, 0.5f); 
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, txPlane); 
    glBegin(GL_QUADS); 
     glNormal3f(-10.0f, 0.0f, -10.0f); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex3f(-10.0f, 0.0f, 10.0f); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex3f(10.0f, 0.0f, 10.0f); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex3f(10.0f, 0.0f, -10.0f); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex3f(-10.0f, 0.0f, -10.0f); 
    glEnd(); 
} 

全碼

// 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 200 //max number of particles 
#define MAX_BOUNCE_COUNT 5 //number of times a particle should bounce 
#define MAX_PARTICLE_AGE 95 

//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.02f; //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 timer(int extra); 
void Load_Plane(); 
void DrawGLscene(); 
void Reshape(GLsizei w, GLsizei h); 

int main(int argc, char** argv){ 
    glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE); 
    glutInitWindowSize(640, 480);  
    glutCreateWindow("Particle fountain"); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glTranslatef(0.0, -0.9, -3.0); 


    Init_Particles(); 
    glutDisplayFunc(DrawGLscene); 
    glutTimerFunc(0, timer, 0); 
    glutMainLoop(); 

} 

void timer(int extra) 
{ 
    glutPostRedisplay(); 
    glutTimerFunc(20, timer, 0); 
} 

void Load_Plane(){ 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 
    glColor4f(0.0f, 0.2f, 0.2f, 0.5f); 
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, txPlane); 
    glBegin(GL_QUADS); 
     glNormal3f(-10.0f, 0.0f, -10.0f); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex3f(-10.0f, 0.0f, 10.0f); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex3f(10.0f, 0.0f, 10.0f); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex3f(10.0f, 0.0f, -10.0f); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex3f(-10.0f, 0.0f, -10.0f); 
    glEnd(); 
} 
void DrawGLscene(){ 
    Load_Plane(); 
    glPushMatrix(); 
    glScalef(1.0f, -1.0f, 1.0f); 
    Render_Particles(); 
    glPopMatrix(); 
    Render_Particles(); 

} 


void Init_Particles(){ 
    LoadBitmapTexture("./Particle.bmp", txParticle); //load the particle texture 
    LoadBitmapTexture("./Plain.bmp",txPlane); //load the plain texture 

    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; 

      //Adding the colours 
      Particles[p].R = R; 
      Particles[p].G = G; 
      Particles[p].B = B; 
      R+=cR; 
      G+=cG; 
      B+=cB; 
      if(R>1.0f){R=1.0f; cR=-cR;} 
      if(R<0.0f){R=0.0f; cR=-cR;} 
      if(G>1.0f){G=1.0f; cG=-cG;} 
      if(G<0.0f){G=0.0f; cG=-cG;} 
      if(B>1.0f){B=1.0f; cB=-cB;} 
      if(B<0.0f){B=0.0f; cB=-cB;} 
      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(){ 
    Activate_Particles(); 
    Adjust_Particles(); 

    glClear(GL_COLOR_BUFFER_BIT); 

    int p; 
    // Enable textures and bind our particle texture 
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, txParticle); 
    // Disable Depth testing. 
    glDisable(GL_DEPTH_TEST); 
    // Enable blending 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_COLOR,GL_ONE); 
    for(p=0; p<MAX_PARTICLES; p++){ 
     if(Particles[p].Active){ 
      glColor4f(Particles[p].R, 
       Particles[p].G, 
       Particles[p].B, 1.0f); 
      glPushMatrix(); 
      glTranslatef(Particles[p].X, 
       Particles[p].Y, 
       Particles[p].Z); 
      glBegin(GL_QUADS); 
      glNormal3f(0.0f, 0.0f, 1.0f); 
      glTexCoord2f(0.0f, 0.0f); 
      glVertex3f(-Size, -Size, 0.0f); 
      glTexCoord2f(1.0f, 0.0f); 
      glVertex3f(Size, -Size, 0.0f); 
      glTexCoord2f(1.0f, 1.0f); 
      glVertex3f(Size, Size, 0.0f); 
      glTexCoord2f(0.0f, 1.0f); 
      glVertex3f(-Size, Size, 0.0f); 
      glEnd(); 
      glPopMatrix(); 


     } 
    } 
    glEnable(GL_DEPTH_TEST); 
    glutSwapBuffers(); 
} 

bool LoadBitmapTexture(char * FileName, GLuint &texid){ 
    HBITMAP hBMP; // Handle Of The Bitmap 
    BITMAP BMP; // Bitmap Structure 
    glGenTextures(1, &texid); // Create The Texture 
    hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL), 
     FileName, 
     IMAGE_BITMAP, 0, 0, 
     LR_CREATEDIBSECTION | LR_LOADFROMFILE 
     ); 

    if (!hBMP) // Does The Bitmap Exist? 
     return FALSE; // If Not Return False 
    GetObject(hBMP, sizeof(BMP), &BMP); // Get The Object 
    // hBMP: Handle To Graphics Object 
    // sizeof(BMP): Size Of Buffer For Object Information 
    // &BMP: Buffer For Object Information 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 
    // Pixel Storage Mode (Word Alignment/4 Bytes) 
    // Typical Texture Generation Using Data From The Bitmap 
    glBindTexture(GL_TEXTURE_2D, texid);// Bind To The Texture ID 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
     GL_LINEAR); // Linear Min Filter 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
     GL_LINEAR); // Linear Mag Filter 
    glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight, 
     0, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits); 
    DeleteObject(hBMP); // Delete The Object 
    return TRUE; // Loading Was Successful 
} 
+0

您是否嘗試過使用'glGetError'進行錯誤檢查? – Tim

+0

什麼是您的圖像的'BMP.bmBitsPixel'? – genpfault

+0

我該如何檢查? – cyberbemon

回答

1

這可能是因爲你不清除深度緩衝區。

它不會影響任何粒子,因爲您在渲染渲染時禁用了深度測試,但是當渲染平面時,啓用了深度測試,並且由於深度緩衝區未被清除,所以它有一個spaz和不渲染飛機。

glClear(GL_DEPTH_BUFFER_BIT); 

您呈現的平面清除深度緩衝區之前。

編輯:

要調用

glClear(GL_COLOR_BUFFER_BIT); 

後您呈現的平面這一定是它 - 。看看你DrawGLScene函數中:

Load_Plane(); // you are drawing the plane here 
glPushMatrix(); 
glScalef(1.0f, -1.0f, 1.0f); 
Render_Particles(); // this function calls "glClear(GL_COLOR_BUFFER_BIT);" 
// so anything that you rendered before is now removed. 
glPopMatrix(); 
Render_Particles(); // same goes for here. 

的解決辦法是從您的Render_Particles函數刪除調用glClear, 並將其添加到DrawGLScene的頂部:

(新DrawGLScene代碼)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
Load_Plane(); 
glPushMatrix(); 
glScalef(1.0f, -1.0f, 1.0f); 
Render_Particles(); 
glPopMatrix(); 
Render_Particles(); 

編輯#2:

你在Render_Particles函數中調用glutSwapBuffers。 不要在那裏叫它。在DrawGLScene結束時調用它:

+0

在調用Load_Plain()函數之前,我添加了'glClear(GL_DEPTH_BUFFER_BIT);',但不幸的是沒有解決問題。 – cyberbemon

+0

@cyberbemon我想我有它!重讀我的答案,我編輯它並投入新的可能的解決方案! – Aaron

+0

不幸的是,沒有使它的工作,我甚至改變了質地,仍然沒有用! – cyberbemon