我将第十九课的代码弄到MFC单文档视图上
具体如下
// 粒子系统MFCDoc.cpp :  CMFCDoc 类的实现
//#include "stdafx.h"
#include "粒子系统MFC.h"#include "粒子系统MFCDoc.h"
#include ".\粒子系统mfcdoc.h"#ifdef _DEBUG
#define new DEBUG_NEW#endif
// CMFCDoc
static GLfloat color[12][3]= // Rainbow Of Colors
{
{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};
IMPLEMENT_DYNCREATE(CMFCDoc, CDocument)BEGIN_MESSAGE_MAP(CMFCDoc, CDocument)
END_MESSAGE_MAP()
// CMFCDoc 构造/析构CMFCDoc::CMFCDoc()
: texture(0)
{
// TODO: 在此添加一次性构造代码}CMFCDoc::~CMFCDoc()
{
}BOOL CMFCDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE; // TODO: 在此添加重新初始化代码
// (SDI 文档将重用该文档) return TRUE;
}
// CMFCDoc 序列化void CMFCDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: 在此添加存储代码
}
else
{
// TODO: 在此添加加载代码
}
}
// CMFCDoc 诊断#ifdef _DEBUG
void CMFCDoc::AssertValid() const
{
CDocument::AssertValid();
}void CMFCDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
// CMFCDoc 命令bool CMFCDoc::init(void)
{
  LoadGLTextures();
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
  glClearColor(0.0f,0.0f,0.0f,0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
  glDisable(GL_DEPTH_TEST); // Disable Depth Testing
   glEnable(GL_BLEND); // Enable Blending
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Type Of Blending To Perform
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // Really Nice Perspective Calculations
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); // Really Nice Point Smoothing
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBindTexture(GL_TEXTURE_2D,texture);
for(int i=0;i<MAXNUMBER;i++)
{
s[i].active=true;
s[i].life=1.0;
s[i].fade=float(rand()%100)/1000.0f+0.003f;
s[i].r=color[i*(12/MAXNUMBER)][0];
s[i].g=color[i*(12/MAXNUMBER)][0];
s[i].b=color[i*(12/MAXNUMBER)][0];
s[i].gx=0;
s[i].gy=-0.8 ;
s[i].gz=0;
s[i].ax=float((rand()%50)-26.0f)*10.0f;
s[i].ay=float((rand()%50)-26.0f)*10.0f;
s[i].az=float((rand()%50)-26.0f)*10.0f;
}

return true;
}AUX_RGBImageRec * CMFCDoc::LoadBMP(char *filename)
{
FILE *file=NULL;
if(filename==NULL)
return false;
file=fopen(filename,"r");
if(file)
{
fclose(file);
return auxDIBImageLoad(filename);
}
return NULL;
}void CMFCDoc::LoadGLTextures(void)
{
AUX_RGBImageRec *TextureImage[1];
    memset(TextureImage,0,sizeof(void *)*1);  if(TextureImage[0]=LoadBMP("Data/Particle.bmp") )
 {
   
glGenTextures(1, &texture ); // Create One Texture
glBindTexture(GL_TEXTURE_2D, texture );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
 }   
 
        if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); // Free The Texture Image Memory
}
free(TextureImage[0]); // Free The Image Structure
}
}

解决方案 »

  1.   

    // 双重纹理实验MFCView.cpp : CMFCView 类的实现
    //#include "stdafx.h"
    #include "粒子系统MFC.h"#include "粒子系统MFCDoc.h"
    #include "粒子系统MFCView.h"
    #include ".\粒子系统mfcview.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    // CMFCViewstatic GLfloat colors[12][3]= // Rainbow Of Colors
    {
    {1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
    {0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
    {0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
    };
    float xspeed; // Base X Speed (To Allow Keyboard Direction Of Tail)
    float yspeed;
    int col;
    IMPLEMENT_DYNCREATE(CMFCView, CView)BEGIN_MESSAGE_MAP(CMFCView, CView)
    // 标准打印命令
    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
    ON_WM_ERASEBKGND()
    ON_WM_CREATE()
    ON_WM_SIZE()
    // ON_WM_MOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    END_MESSAGE_MAP()// CMFCView 构造/析构CMFCView::CMFCView()
    : m_pDC(NULL)
    , MouseDownPoint(0)
    , X_Angle(0)
    , Y_Angle(0)
    , pi(3.141592653)
    , theta(0)
    , slowdown(2)
    , zoom(10)
    , vx(0)
    , vy(0)
    , vz(15)
    {
    // TODO: 在此处添加构造代码}CMFCView::~CMFCView()
    {
    }BOOL CMFCView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
    // 样式 return CView::PreCreateWindow(cs);
    }// CMFCView 绘制void CMFCView::OnDraw(CDC* )
    {
    CMFCDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); // gluLookAt(vx,vy,vz,0,0,0,0,1,0);
    glRotatef(X_Angle,1,0,0);
    glRotatef(Y_Angle,0,1,0);

       for (int i=0;i<MAXNUMBER;i++) // i Through All The Particles
    {
    if (pDoc->s[i].active) // If The Particle Is Active
    {
    float x=pDoc->s[i].x; // Grab Our Particle X Position
    float y=pDoc->s[i].y; // Grab Our Particle Y Position
    float z=pDoc->s[i].z+zoom; // Particle Z Pos + Zoom // Draw The Particle Using Our RGB Values, Fade The Particle Based On It's Life
    glColor4f(pDoc->s[i].r,pDoc->s[i].g,pDoc->s[i].b,pDoc->s[i].life); glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
        glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); // Top Right
    glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); // Top Left
    glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); // Bottom Right
    glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); // Bottom Left
    glEnd(); // Done Building Triangle Strip pDoc->s[i].x+=pDoc->s[i].ax/(slowdown*1000);// Move On The X Axis By X Speed
    pDoc->s[i].y+=pDoc->s[i].ay/(slowdown*1000);// Move On The Y Axis By Y Speed
    pDoc->s[i].z+=pDoc->s[i].az/(slowdown*1000);// Move On The Z Axis By Z Speed pDoc->s[i].ax+=pDoc->s[i].gx; // Take Pull On X Axis Into Account
    pDoc->s[i].ay+=pDoc->s[i].gy; // Take Pull On Y Axis Into Account
      pDoc->s[i].az+=pDoc->s[i].gz; // Take Pull On Z Axis Into Account
    pDoc->s[i].life-=pDoc->s[i].fade; // Reduce Particles Life By 'Fade' if (pDoc->s[i].life<0.0f) // If Particle Is Burned Out
    {
    pDoc->s[i].life=1.0f; // Give It New Life
    pDoc->s[i].fade=float(rand()%100)/1000.0f+0.003f; // Random Fade Value
    pDoc->s[i].x=0.0f; // Center On X Axis
    pDoc->s[i].y=0.0f; // Center On Y Axis
    pDoc->s[i].z=0.0f; // Center On Z Axis
    pDoc->s[i].ax=xspeed+float((rand()%60)-32.0f); // X Axis Speed And Direction
    pDoc->s[i].ay=yspeed+float((rand()%60)-30.0f); // Y Axis Speed And Direction
    pDoc->s[i].az=float((rand()%60)-30.0f); // Z Axis Speed And Direction
    pDoc->s[i].r=colors[2][0]; // Select Red From Color Table
    pDoc->s[i].g=colors[2][1]; // Select Green From Color Table
    pDoc->s[i].b=colors[2][2]; // Select Blue From Color Table
    }
    }

    SwapBuffers(wglGetCurrentDC()); // TODO: 在此处为本机数据添加绘制代码
    }
    // CMFCView 打印BOOL CMFCView::OnPreparePrinting(CPrintInfo* pInfo)
    {
    // 默认准备
    return DoPreparePrinting(pInfo);
    }void CMFCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: 打印前添加额外的初始化
    }void CMFCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    // TODO: 打印后添加清除过程
    }
    // CMFCView 诊断#ifdef _DEBUG
    void CMFCView::AssertValid() const
    {
    CView::AssertValid();
    }void CMFCView::Dump(CDumpContext& dc) const
    {
    CView::Dump(dc);
    }CMFCDoc* CMFCView::GetDocument() const // 非调试版本是内联的
    {
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCDoc)));
    return (CMFCDoc*)m_pDocument;
    }
    #endif //_DEBUG
    // CMFCView 消息处理程序BOOL CMFCView::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值 return true;
    }int CMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;
        init();
    // TODO:  在此添加您专用的创建代码 return 0;
    }void CMFCView::init(void)
    {
    PIXELFORMATDESCRIPTOR pfd;
    int         n;
    HGLRC       hrc; m_pDC = new CClientDC(this); ASSERT(m_pDC != NULL); if (!bSetupPixelFormat())
    return;
        GLfloat light_position[] = { 0.0, 0.0, 1.0, 1.0 }; n = ::GetPixelFormat(m_pDC->GetSafeHdc());
    ::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd), &pfd);
    hrc = wglCreateContext(m_pDC->GetSafeHdc());
    wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    CMFCDoc* pDoc=GetDocument();
    pDoc->init();
    /* glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_DEPTH_TEST);
    // glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_TEXTURE_2D);*/
    }bool CMFCView::bSetupPixelFormat(void)
    {
    static PIXELFORMATDESCRIPTOR pfd =
    {
    sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
    1,                              // version number
    PFD_DRAW_TO_WINDOW |            // support window
      PFD_SUPPORT_OPENGL |          // support OpenGL
      PFD_DOUBLEBUFFER,             // double buffered
    PFD_TYPE_RGBA,                  // RGBA type
    24,                             // 24-bit color depth
    0, 0, 0, 0, 0, 0,               // color bits ignored
    0,                              // no alpha buffer
    0,                              // shift bit ignored
    0,                              // no accumulation buffer
    0, 0, 0, 0,                     // accum bits ignored
    32,                             // 32-bit z-buffer
    0,                              // no stencil buffer
    0,                              // no auxiliary buffer
    PFD_MAIN_PLANE,                 // main layer
    0,                              // reserved
    0, 0, 0                         // layer masks ignored
    };
    int pixelformat; if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
    {
    MessageBox("ChoosePixelFormat failed");
    return FALSE;
    } if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
    {
    MessageBox("SetPixelFormat failed");
    return FALSE;
    } return TRUE;
    }void CMFCView::OnSize(UINT nType, int cx, int cy)
    {
    CView::OnSize(nType, cx, cy);
        int w=cx,
    int h=cy;
    glViewport(0,0,w,h); 
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); 
      //gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.1f,200.0f);
    gluPerspective(caculate(20,20),(float)w/(float)h,1,50);
    glMatrixMode(GL_MODELVIEW);
        glLoadIdentity(); 
    // TODO: 在此处添加消息处理程序代码
    }double CMFCView::caculate(double s, double d)
    {
    double r,dd; 
        r=atan2(s/2,d)*2; 
        dd=(180*r)/2; 
        return dd; 
    return 0;
    }
    void CMFCView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值 MouseDownPoint=point;
    SetCapture();
    CView::OnLButtonDown(nFlags, point);}void CMFCView::OnLButtonUp(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    MouseDownPoint=CPoint(0,0);
    ReleaseCapture();
    CView::OnLButtonUp(nFlags, point);
    }void CMFCView::OnMouseMove(UINT nFlags, CPoint point)
    {
    if (GetCapture()==this)  //返回值是与当前线程相关联的捕获窗口的句柄。如果当前线程里没有窗口捕获到鼠标,则返回NULL。
    {
    // 旋转对象一个步长
    X_Angle+=double(point.y-MouseDownPoint.y);
    Y_Angle+=double(point.x-MouseDownPoint.x);
    // 更新场景
    Invalidate(TRUE);
    // 记下鼠标位置
    MouseDownPoint=point;
    };
    CView::OnMouseMove(nFlags, point);
    }
      

  2.   

    // 粒子系统MFCDoc.h :  CMFCDoc 类的接口
    //
    #pragma once
    #define MAXNUMBER 50typedef struct star
    {
    bool active;
     float life;
     float fade;
     float r;
     float g;
     float b;
     float x;
     float y;
     float z;
     float ax;
     float ay;
     float az;
     float gx;
     float gy;
     float gz;
    }stars;class CMFCDoc : public CDocument
    {
    protected: // 仅从序列化创建
    CMFCDoc();
    DECLARE_DYNCREATE(CMFCDoc)// 属性
    public:

    // 操作
    public:// 重写
    public:
    virtual BOOL OnNewDocument();
    virtual void Serialize(CArchive& ar);// 实现
    public:
    virtual ~CMFCDoc();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endifprotected:// 生成的消息映射函数
    protected:
    DECLARE_MESSAGE_MAP()
    public:
    bool init(void);
    stars s[MAXNUMBER];
    AUX_RGBImageRec * LoadBMP(char* filename);
    void LoadGLTextures(void);
    GLuint texture;
    };
      

  3.   

    数据定义在DOC类中,在DOC类里init()初始化粒子,
    然后在VIEW类中的init()里调用DOC中的init()
    然后在VIEW类中的ONDraw()函数中对粒子系统进行绘画
    结果却并没有出现粒子喷射的效果,而是粒子初始的静态画面。
    要让他实现NEHE第19课的效果,应该怎么改???????
      

  4.   

    要喷射的效果 是不是应该加上time的响应函数啊