登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: [opengl]一个简单易懂的 win32 框架     [回主站]     [分站链接]
标题
[opengl]一个简单易懂的 win32 框架
clq
浏览(0) + 2010-08-16 10:03:26 发表 编辑

关键字:

可以关联到任意一个窗口上.不过好象 win32 下的 opengl 窗口没法指定只使用窗口的一部分 rect 这个就比不上 directdraw 了.

clq
2010-8-16 10:05:40 发表 编辑

原作者:不详    源出处:CSDN    发布类型:转载  发布日期:2008-10-13

              

       今天写了个基于MFC对话框的OpenGL类:COpenGL,可以在对话框程序中使用OpenGL了,并且提供了全屏与非全屏转换的两个函数,很容易使用,速度快。

   使用方法:在对话框上加一个Static控件(或者其他的也可以),在OnInitDialog()中加人下面这段代码(假设控件ID为IDC_OPENGL,m_openGL是类COpenGL的对象):

Code: CRect rect;
GetDlgItem(IDC_OPENGL)->GetWindowRect(rect);
ScreenToClient(rect);
m_openGL.Create(rect, this);

   然后在适当的地方调用m_openGL.RenderGLScene()就可以了。

   以下是类代码(OpenGL.h和OpenGL.cpp):

Code:#if !defined(AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_)
#define AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OpenGL.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// COpenGL window

class COpenGL : public CWnd
{
  // Construction
  public:
   COpenGL();
 
   // Attributes
  public:

   // Operations
  public:

   // Overrides
   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(COpenGL)
   //}}AFX_VIRTUAL

   // Implementation
  public:
   BOOL SetNormScreen();
   BOOL SetFullScreen(int width, int height, int depth);
   virtual void RenderGLScene();
   void Create(CRect rect, CWnd *parent);
   virtual ~COpenGL();

   // Generated message map functions
  protected:
   CRect m_rect;
   CWnd* m_parent;
   BOOL m_bFullScreen;
   DEVMODE m_DMsaved;
   BOOL m_bInit;
   int InitGL();
   void KillGLWindow();
   HDC m_hDC;
   HGLRC m_hRC;
   //{{AFX_MSG(COpenGL)
   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
   afx_msg void OnPaint();
   afx_msg void OnSize(UINT nType, int cx, int cy);
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_)

Code:// OpenGL.cpp : implementation file
//

#include "stdafx.h"
#include "DialogOpenGL.h"
#include "OpenGL.h"
#include <gl/gl.h>
#include <gl/glu.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COpenGL

COpenGL::COpenGL():m_bInit(FALSE),m_bFullScreen(FALSE),
m_hDC(NULL),m_hRC(NULL),m_parent(NULL)
{
}

COpenGL::~COpenGL()
{
  KillGLWindow(); // Shutdown
}


BEGIN_MESSAGE_MAP(COpenGL, CWnd)
  //{{AFX_MSG_MAP(COpenGL)
   ON_WM_CREATE()
   ON_WM_PAINT()
   ON_WM_SIZE()
   ON_WM_KEYDOWN()
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// COpenGL message handlers

void COpenGL::Create(CRect rect, CWnd *parent)
{
  if (m_bInit) return;
  ASSERT(rect);
  ASSERT(parent);
  m_rect = rect;
  m_parent = parent;

  CString className = AfxRegisterWndClass(
   CS_HREDRAW | CS_VREDRAW | CS_OWNDC,NULL,(HBRUSH)GetStockObject(BLACK_BRUSH),NULL);

   CreateEx(0,className,"OpenGL",WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,rect,parent,0);
  }

  int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
   if (CWnd::OnCreate(lpCreateStruct) == -1)
    return -1;

   // TODO: Add your specialized creation code here
   EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &m_DMsaved);

   GLuint PixelFormat; // Holds The Results After Searching For A Match
   static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
   {
    sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
    1, // Version Number
    PFD_DRAW_TO_WINDOW | // Format Must Support Window
    PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
    PFD_DOUBLEBUFFER, // Must Support Double Buffering
    PFD_TYPE_RGBA, // Request An RGBA Format
    m_DMsaved.dmBitsPerPel, // Select Our 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, // Accumulation Bits Ignored
    16, // 16Bit Z-Buffer (Depth Buffer)
    0, // No Stencil Buffer
    0, // No Auxiliary Buffer
    PFD_MAIN_PLANE, // Main Drawing Layer
    0, // Reserved
    0, 0, 0 // Layer Masks Ignored
   };

   if ( !( m_hDC = ::GetDC ( m_hWnd ) ) ) { // Did We Get A Device Context?
    KillGLWindow (); // Reset The Display
    TRACE ( "Can't Create A GL Device Context." );
    return FALSE;
   }

   if ( !( PixelFormat = ChoosePixelFormat ( m_hDC, &pfd ) ) ) { // Did Windows Find A Matching Pixel Format?
    KillGLWindow (); // Reset The Display
    TRACE ( "Can't Find A Suitable PixelFormat." );
    return FALSE;
   }

   if ( !SetPixelFormat ( m_hDC, PixelFormat, &pfd ) ){ // Are We Able To Set The Pixel Format?
    KillGLWindow (); // Reset The Display
    TRACE ( "Can't Set The PixelFormat." );
    return FALSE;
   }

   if ( !( m_hRC = wglCreateContext ( m_hDC ) ) ) { // Are We Able To Get A Rendering Context?
    KillGLWindow (); // Reset The Display
    TRACE( " Can't Create A GL Rendering Context." );
    return FALSE;
   }

   if ( !wglMakeCurrent ( m_hDC, m_hRC ) ) { // Try To Activate The Rendering Context
    KillGLWindow (); // Reset The Display
    TRACE ( "Can't Activate The GL Rendering Context." );
    return FALSE;
   } 

   if ( !InitGL () ) { // Initialize Our Newly Created GL Window
    KillGLWindow (); // Reset The Display
    TRACE ( "Initialization Failed." );
    return FALSE;
   }
   m_bInit = TRUE;
   return 0;
  }

  void COpenGL::KillGLWindow()
  {
   if (m_bFullScreen) // Are We In Fullscreen Mode?
   {
    if (!ChangeDisplaySettings(NULL,CDS_TEST)) { // if the shortcut doesn't work
     ChangeDisplaySettings(NULL,CDS_RESET); // Do it anyway (to get the values out of the registry)
     ChangeDisplaySettings(&m_DMsaved,CDS_RESET); // change it to the saved settings
    } else {
     ChangeDisplaySettings(NULL,CDS_RESET);
    }

    ShowCursor(TRUE); // Show Mouse Pointer
   }

   if ( m_hRC ) { // Do We Have A Rendering Context?
    if ( !wglMakeCurrent ( NULL, NULL ) ) { // Are We Able To Release The DC And RC Contexts?
     TRACE ( "Release Of DC And RC Failed." );
    }

    if ( !wglDeleteContext ( m_hRC ) ) { // Are We Able To Delete The RC?
     TRACE ( "Release Rendering Context Failed." );
    }
    m_hRC = NULL; // Set RC To NULL
   }

   if ( m_hDC && !::ReleaseDC ( m_hWnd, m_hDC ) ) { // Are We Able To Release The DC
    TRACE ( "Release Device Context Failed." );
    m_hDC = NULL; // Set DC To NULL
   }

   if ( m_hWnd && !::DestroyWindow ( m_hWnd ) ) { // Are We Able To Destroy The Window?
    TRACE( "Could Not Release m_hWnd." );
    m_hWnd = NULL; // Set m_hWnd To NULL
   }
  }

  int COpenGL::InitGL()
  {
   glShadeModel(GL_SMOOTH); // Enable Smooth Shading
   glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
   glClearDepth(1.0f); // Depth Buffer Setup
   glEnable(GL_DEPTH_TEST); // Enables Depth Testing
   glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
   glEnable(GL_TEXTURE_2D); // Enable Texture Mapping

   return TRUE; // Initialization Went OK
  }

  void COpenGL::RenderGLScene()
  {
   if(!m_bInit) return;

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
   glLoadIdentity();

   // EXAMPLE OPENGL CODE START ////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////////////
   static GLfloat xrot; // X Rotation
   static GLfloat yrot; // Y Rotation
   static GLfloat zrot; // Z Rotation

   glPushMatrix(); // Push Matrix Onto Stack (Copy The Current Matrix)
   glLoadIdentity(); // Reset The Current Modelview Matrix
   glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0

   glRotatef(xrot,1.0f,0.0f,0.0f);
   glRotatef(yrot,0.0f,1.0f,0.0f);
   glRotatef(zrot,0.0f,0.0f,1.0f);

   glBegin(GL_QUADS);
   // Front Face
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);
   glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);
   // Back Face
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);
   glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);
   // Top Face
   glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);
   glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);
   // Bottom Face
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);
   glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);
   // Right face
   glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);
   // Left Face
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);
   glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);
   glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);
   glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);

   glEnd();
   glPopMatrix(); // Pop Matrix Off The Stack

   xrot+=1.3f;
   yrot+=1.2f;
   zrot+=1.4f; // Decrease The Rotation Variable For The Quad
   //////////////////////////////////////////////////////////////////////////////
   // EXAMPLE OPENGL CODE END //////////////////////////////////////////////////////////

   // Swap our scene to the front

   SwapBuffers(m_hDC);

   Invalidate(FALSE);
  }

  void COpenGL::OnPaint()
  {
   CPaintDC dc(this); // device context for painting
 
   // TODO: Add your message handler code here
   ::ValidateRect ( m_hWnd, NULL );

   // Do not call CWnd::OnPaint() for painting messages
  }

  void COpenGL::OnSize(UINT nType, int cx, int cy)
  {
   CWnd::OnSize(nType, cx, cy);

   // TODO: Add your message handler code here
   if ( cy==0) { // Prevent A Divide By Zero By
    cy=1; // Making Height Equal One
   }

   glViewport(0,0,cx,cy); // Reset The Current Viewport

   glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
   glLoadIdentity(); // Reset The Projection Matrix

   gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window

   glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
   glLoadIdentity(); // Reset The Modelview Matrix

  }

  BOOL COpenGL::SetFullScreen(int width, int height, int depth)
  {
   if(!m_bInit) return FALSE;
   if (m_bFullScreen) return TRUE;

   DEVMODE dmScreenSettings; // Device Mode
   memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
   dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
   dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
   dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
   dmScreenSettings.dmBitsPerPel = depth; // Selected Bits Per Pixel
   dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

   // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.

   if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
   {
    return m_bFullScreen = FALSE;
   }

   SetParent(NULL);
   SetWindowPos(&CWnd::wndTop,0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW);

   ShowCursor(FALSE);
   SetFocus();
   return m_bFullScreen = TRUE;
  }

  BOOL COpenGL::SetNormScreen()
  {
   if(!m_bInit) return FALSE;

   if (m_bFullScreen) // Are We In Fullscreen Mode?
   {
    if (!ChangeDisplaySettings(NULL,CDS_TEST)) { // if the shortcut doesn't work
     ChangeDisplaySettings(NULL,CDS_RESET); // Do it anyway (to get the values out of the registry)
     ChangeDisplaySettings(&m_DMsaved,CDS_RESET); // change it to the saved settings
    } else {
     ChangeDisplaySettings(NULL,CDS_RESET);
    }
    SetParent(m_parent);
    SetWindowPos(&CWnd::wndTop,m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), SWP_SHOWWINDOW);
    ShowCursor(TRUE); // Show Mouse Pointer
    m_bFullScreen = FALSE;
   }
  return TRUE;
}




总数:1 页次:1/1 首页 尾页  
总数:1 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1