学校要求用OpengGL做东西,必须和MFC结合。用纯OpenGL实现效果如下但是弄到MFC里就只有2D了,效果如下
想知道是哪里出了问题,求教大神谢谢,在线等,很急,没几天要交了。

解决方案 »

  1.   

    在百度搜”MFC OpenGL“
      

  2.   

    以下是我MFC程序里的3D图形:
    源代码如下,希望能帮到你。其中一些自定义的变量和函数不用管,只需要看框架
    // 3Dview.cpp : implementation file
    //
    #include "stdafx.h"
    #include "room1.h"
    #include "3Dview.h"
    #include "MainFrm.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif#define BS 10.0f 
    #define HS 36.0f/////////////////////////////////////////////////////////////////////////////
    // C3DviewIMPLEMENT_DYNCREATE(C3Dview, CView)C3Dview::C3Dview()
    {
    }
    C3Dview::~C3Dview()
    {
    }
    BEGIN_MESSAGE_MAP(C3Dview, CView)
    //{{AFX_MSG_MAP(C3Dview)
    ON_WM_CREATE()
    ON_WM_DESTROY()
    ON_WM_ERASEBKGND()
    ON_WM_SIZE()
    ON_WM_LBUTTONDOWN()
    ON_WM_RBUTTONDOWN()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_KEYDOWN()
    ON_WM_MOUSEMOVE()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // C3Dview drawingvoid C3Dview::OnDraw(CDC* pDC)
    {
    CDocument* pDoc = GetDocument();
    // TODO: add draw code here
    if (!pDoc)
    return;
    ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    RenderScene();//绘图都放在这
    //drawfont();
     // Tell OpenGL to flush its pipeline
     ::glFinish();
     // Now Swap the buffers
     ::SwapBuffers( m_pDC->GetSafeHdc() );
    }/////////////////////////////////////////////////////////////////////////////
    // C3Dview diagnostics#ifdef _DEBUG
    void C3Dview::AssertValid() const
    {
    CView::AssertValid();
    }void C3Dview::Dump(CDumpContext& dc) const
    {
    CView::Dump(dc);
    }
    #endif //_DEBUGCRoom1Doc* C3Dview::GetDocument(){
    return (CRoom1Doc*)m_pDocument;
    }BOOL C3Dview::InitializeOpenGL()
    {
    //Get a DC for the Client Area
    m_pDC = new CClientDC(this);
    //Failure to Get DC
    if(m_pDC == NULL)
    {
    //::MessageBox("Error Obtaining DC");
    return FALSE;
    }
    //Failure to set the pixel format
    if(!SetupPixelFormat())
    {
    return FALSE;
    }
     //Create Rendering Context
     m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc ());
     //Failure to Create Rendering Context
     if(m_hRC == 0)
     {
    // MessageBox("Error Creating RC");
    return FALSE;
     }
     //Make the RC Current
     if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)
     {
    // MessageBox("Error making RC Current");
    return FALSE;
     }
     
     /*纹理新增
     if (!LoadGLTextures()) // 调用纹理载入子例程( 新增 )
    {
    return FALSE; // 如果未能载入,返回FALSE( 新增 )
    }
    ::glEnable(GL_TEXTURE_2D); // 启用纹理映射( 新增 )
    ::glShadeModel(GL_SMOOTH);// 启用阴影平滑 
    纹理新增*/ //Specify Black as the clear color
     ::glClearColor(0.2f,0.2f,0.2f,0.0f);//设置背景色
     //Specify the back of the buffer as clear depth
     ::glClearDepth(1.0f);
     //Enable Depth Testing
     ::glEnable(GL_DEPTH_TEST); /*纹理新增
     ::glDepthFunc(GL_LEQUAL);// 设置深度缓存
     // 启用深度测试
     // 所作深度测试的类型 
    ::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正
     纹理新增*/
     return TRUE;
     
    }
    BOOL C3Dview::SetupPixelFormat()
    {
     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, // 16-bit z-buffer16->32 
    0,// no stencil buffer
    0,// no auxiliary buffer
    PFD_MAIN_PLANE, // main layer
    0,// reserved
    0, 0, 0 // layer masks ignored
     };
     int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
     if ( m_nPixelFormat == 0 )
     {
    return FALSE;
     }
     if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
     {
    return FALSE;
     }
     return TRUE;
    }void C3Dview::RenderScene()
    {
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
    glLoadIdentity(); // Reset The Current Modelview Matrix
    //glLoadIdentity(); // Reset The Current Modelview Matrix
    //glTranslatef(1.0f,-1.8f,-15.0f); 

    glTranslatef(x0,y0,z0);
    glRotatef(rx,1.0f,0.0f,0.0f); 
    glRotatef(ry,0.0f,1.0f,0.0f);
    glRotatef(rz,0.0f,0.0f,1.0f);

    cab3List::iterator cabi;
    //CString str="",str1;
    for( cabi=cabs.begin();cabi!=cabs.end();++cabi){
     //str1="";
     drawcab3D(cabi->x, 0.0f, cabi->z);
     //str1.Format("id:%d,p:%d,x:%f,z:%f;",cabi->id,cabi->p,cabi->x,cabi->z);
     //str+=str1;
     drawdevsofcab(*cabi);
    }
    drawback();
    drawcabname();
    drawdevname();
    glLoadIdentity(); // Reset The Current Modelview Matrix , 这里再重置一次,应该是为了获取正确的鼠标位置

    glTranslatef(x0,y0,z0);
    glRotatef(rx,1.0f,0.0f,0.0f); // 绕Y轴旋转三角形 ( 新增 )
    glRotatef(ry,0.0f,1.0f,0.0f);
    glRotatef(rz,0.0f,0.0f,1.0f);
     }void C3Dview::drawdevsofcab(cab3 cab)
    {
    //自定义函数,略
    }void C3Dview::drawdev3D(Dev3 dev,GLfloat x,GLfloat z)
    {
    GLfloat y0=((dev.position-1)*0.08f+0.12f)*BS;
    GLfloat h=dev.size*0.08f*BS; 
    GLfloat y=y0;//在绘制设备时,通过设置顶面和侧面不同的颜色,以造成立体的感觉
    glBegin(GL_QUADS); // 绘制正方形
    //glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
    glColor3f(colors[dev.color][0]*0.9f,colors[dev.color][1]*0.9f,colors[dev.color][2]*0.9f);
    glVertex3f( x+BS, y+h,z); // 四边形的右上顶点 (顶面)
    glVertex3f(x, y+h,z); // 四边形的左上顶点 (顶面)
    glVertex3f(x, y+h, z+BS); // 四边形的左下顶点 (顶面)
    glVertex3f(x+BS, y+h, z+BS); // 四边形的右下顶点 (顶面)
    ....
    //图形绘制,同OPENGLglEnd(); // 立方体绘制结束
    }/////////////////////////////////////////////////////////////////////////////
    // C3Dview message handlersint C3Dview::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO: Add your specialized creation code here
    InitializeOpenGL();
    //CRoom1App *pApp = (CRoom1App *)AfxGetApp(); m_tipBtnCtr.Create(this, TTS_ALWAYSTIP); 
    m_tipBtnCtr.AddTool(this); 
    m_tipBtnCtr.Activate(TRUE);
    m_tipBtnCtr.SetDelayTime(100);//delay time
    //m_tipBtnCtr.SetTipTextColor(RGB(0,0,255)); 
    //m_tipBtnCtr.SetTipBkColor( RGB(200,200,0)); 
    m_tipBtnCtr.SetMaxTipWidth(200); BuildFont();
    init0();
    return 0;
    }void C3Dview::OnDestroy() 
    {
    CView::OnDestroy();

    // TODO: Add your message handler code here
    if(::wglMakeCurrent (0,0) == FALSE)
    {
    MessageBox(_T("Could not make RC non-current"));
    }
     
    //Delete the rendering context
    if(::wglDeleteContext (m_hRC)==FALSE)
    {
    MessageBox(_T("Could not delete RC"));
    }
    //Delete the DC
    if(m_pDC)
    {
    delete m_pDC;
    }
    //Set it to NULL
    m_pDC = NULL; KillFont();  //AfxMessageBox("haha");
    }BOOL C3Dview::OnEraseBkgnd(CDC* pDC) 
    {
    // TODO: Add your message handler code here and/or call default

    return CView::OnEraseBkgnd(pDC);
    }void C3Dview::OnSize(UINT nType, int cx, int cy) 
    {
    CView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    CView::OnSize(nType, cx, cy);
    GLdouble aspect_ratio; // width/height ratio

    // TODO: Add your message handler code here
    if ( 0 >= cx || 0 >= cy )
     {
    return;
     }
     // select the full client area
     ::glViewport(0, 0, cx, cy);
     // compute the aspect ratio
     // this will keep all dimension scales equal
     aspect_ratio = (GLdouble)cx/(GLdouble)cy;
     // select the projection matrix and clear it
     ::glMatrixMode(GL_PROJECTION);
     ::glLoadIdentity();
     ::gluPerspective(45.0f, aspect_ratio, .01f*BS, 200.0f*BS);//画三维
     
     
     // switch back to the modelview matrix and clear it
     ::glMatrixMode(GL_MODELVIEW);
     ::glLoadIdentity();
    }void C3Dview::init0()
    {
    //自定义函数
    }
    void C3Dview::OnRButtonDown(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    rx-=1.0f;
    Invalidate(); //glm::dvec3 winPos(win.x, viewport[3] - win.y - 1, 0);
    CView::OnRButtonDown(nFlags, point);
    }
    void C3Dview::drawback()//绘制背景,包括地板和机房的三面
    {
    //自定义函数,略
    }AUX_RGBImageRec* C3Dview::LoadBMP(char *Filename) // 载入位图图象
    {
    FILE *File=NULL; 
    if (!Filename) // 确保文件名已提供。
    {
     return NULL; // 如果没提供,返回 NULL

    File=fopen(Filename,"r"); //尝试打开文件 
    if (File) // 文件存在么?
    {
     fclose(File); // 关闭句柄
     return auxDIBImageLoad(Filename); 

    return NULL; 
    }
    int C3Dview::LoadGLTextures() 
    {
    int Status=FALSE; // Status 状态指示器
    AUX_RGBImageRec *TextureImage[3]; // 创建纹理的存储空间
    memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULLif (TextureImage[0]=LoadBMP("pic/cz1b.bmp"))
    {
    //Status=TRUE;
    glGenTextures(1, &texture[0]); // 创建纹理
    glBindTexture(GL_TEXTURE_2D, texture[0]); // 使用来自位图数据生成 的典型纹理
    glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // 生成纹理
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线形滤波
    if (TextureImage[0]) // 纹理是否存在
    {
    if (TextureImage[0]->data) 
    {
    free(TextureImage[0]->data); 
    }free(TextureImage[0]); // 释放图像结构
    }
    } if (TextureImage[1]=LoadBMP("pic/cz2b.bmp"))
    {
    //Status=TRUE;
    glGenTextures(1, &texture[1]); 
    glBindTexture(GL_TEXTURE_2D, texture[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[1]->sizeX, TextureImage[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // 生成纹理
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    if (TextureImage[1]) // 纹理是否存在
    {
    if (TextureImage[1]->data) // 纹理图像是否存在
    {
    free(TextureImage[1]->data); 
    }free(TextureImage[1]); // 释放图像结构
    }
    } if (TextureImage[2]=LoadBMP("pic/cz3b.bmp"))
    {
    Status=TRUE;
    glGenTextures(1, &texture[2]); // 创建纹理
    glBindTexture(GL_TEXTURE_2D, texture[2]); // 使用来自位图数据生成 的典型纹理
    glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[2]->sizeX, TextureImage[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // 生成纹理
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线形滤波
    if (TextureImage[2]) // 纹理是否存在
    {
    if (TextureImage[2]->data) // 纹理图像是否存在
    {
    free(TextureImage[2]->data); // 释放纹理图像占用的内存
    }free(TextureImage[2]); // 释放图像结构
    }
    }
     
     return Status;
    }BOOL C3Dview::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class
    m_tipBtnCtr.RelayEvent(pMsg);
    CString strTemp;
    if(devid>0){
    strTemp=getdevdetail();
    }else{
    strTemp = _T(""); 
    }
    m_tipBtnCtr.AddTool(this, strTemp);
    return CView::PreTranslateMessage(pMsg);
    }