📄 copenglview.cpp
字号:
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
16, // 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
if ( 0 == (m_PixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) )
{
SetError(2);
return FALSE;
}
if ( FALSE == ::SetPixelFormat(m_pDC->GetSafeHdc(), m_PixelFormat, &pfd) )
{
SetError(3);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// This is a helper function that's used to parse the strings
static const char* GetString( GLenum theEnum );
// This is a helper function
static const char* GetString( GLenum theEnum )
{
char* string;
// returns a pointer to a STATIC string!
string = (char*)::glGetString( theEnum );
if ( GL_NO_ERROR != ::glGetError() ) // failed!
{
static char* error = "no-information-available" "";
string = error;
}
return string;
}
/////////////////////////////////////////////////////////////////////////////
void COpenGLView::FetchExtendedInformation()
{
// Get information about the particular pixel format that's running. From this we
// can tell if the OpenGL implementation is strictly software, partially in hardware with
// some of the routines being processed by the generic software driver (the Mini-Client driver)
// or if the entire implementation is in hardware (the Installable Client driver)
PIXELFORMATDESCRIPTOR pfd;
// Get information about the DC's current pixel format
::DescribePixelFormat( m_pDC->GetSafeHdc(), m_PixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &pfd );
// Now that we've set up a pixel format, get information about the current
// driver for this format. You can use this info to determine which pixel format
// is the fastest. Note that the Mini-Client driver is only available in OpenGL 1.1
// or later.
if ( 0 == ( INSTALLABLE_DRIVER_TYPE_MASK & pfd.dwFlags ) )
m_eCurrentDriver = eInstallableClient; // fully in hardware (fastest)
else if ( INSTALLABLE_DRIVER_TYPE_MASK == ( INSTALLABLE_DRIVER_TYPE_MASK & pfd.dwFlags ) )
m_eCurrentDriver = eMiniClient; // partially in hardware (pretty fast, maybe..)
else // plain old generic
m_eCurrentDriver = eGeneric; // software
// end of the current driver specific area
// Get general information about the OpenGL driver
// GL_VENDOR
// Returns the company responsible for this GL implementation.
// This name does not change from release to release.
m_pVender = GetString( GL_VENDOR );
// GL_RENDERER
// Returns the name of the renderer. This name is typically specific
// to a particular configuration of a hardware platform.
// It does not change from release to release.
m_pRenderer = GetString( GL_RENDERER );
// GL_VENDOR and GL_RENDERER together uniquely specify a platform,
// and will not change from release to release. They should be used
// to identify the platform.
// GL_VERSION
// Returns a version or release number.
m_pVersion = GetString( GL_VERSION );
// GL_EXTENSIONS
// Returns a space-separated list of supported extensions to GL.
// Because GL does not include queries for the performance
// characteristics of an implementation, it is expected that some
// applications will be written to recognize known platforms and will
// modify their GL usage based on known performance characteristics
// of these platforms.
// The format and contents of the string that glGetString() returns depend
// on the implementation, except that extension names will not include
// space characters and will be separated by space characters
// in the GL_EXTENSIONS string, and that all strings are null-terminated.
char *extension, *c;
const char* e = GetString( GL_EXTENSIONS );
// This string is deleted in the destructor
m_ExtensionPtr = c = new char[ strlen(e)+1 ];
if ( 0 == m_ExtensionPtr )
{
TRACE("Couldn't allocate memory for the extension list.\n");
return;
}
// make a local copy to mess with
::strcpy( m_ExtensionPtr, e );
BOOL bDone = FALSE;
bDone = TRUE;
while ( !bDone )
{
extension = c;
while ( (0 != *c) && (' ' != *c) )
c++;
if ( 0 == *c )
bDone = TRUE;
*c = 0; // terminate the string
// Now create a new CString object and add it to the array
m_ExtensionArray.Add( extension );
// skip to next string
extension = ++c;
}
// End of the extended driver information
}
/////////////////////////////////////////////////////////////////////////////
// SetupViewport
BOOL COpenGLView::SetupViewport( int cx, int cy )
{
// select the full client area
::glViewport(0, 0, cx, cy);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// SetupViewingFrustum
BOOL COpenGLView::SetupViewingFrustum( GLdouble aspect_ratio )
{
// select a default viewing volumn
::gluPerspective(40.0f, aspect_ratio, .1f, 20.0f);
// here's an ortho view
// glOrtho( -2.0f, 2.0f, -2.0f, 2.0f, -.10f, 20.0f );
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// SetupViewingTransform
// This is a static, default viewing transform
BOOL COpenGLView::SetupViewingTransform()
{
// select a default viewing transformation
// of a 20 degree rotation about the X axis
// then a -5 unit transformation along Z
// (It's as good as any I guess...)
::glTranslatef( 0.0f, 0.0f, -5.0f );
::glRotatef( 20.0f, 1.0f, 0.0f, 0.0f );
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// RenderScene
// This is the default scene for the COpenGLView class.
// draw a red wire sphere inside a light blue cube
BOOL COpenGLView::RenderScene()
{
// rotate the wire sphere so it's vertically
// oriented
::glRotatef( 90.0f, 1.0f, 0.0f, 0.0f );
::glColor3f( 1.0f, 0.0f, 0.0f );
::auxWireSphere( .5 );
::glColor3f( 0.5f, 0.5f, 1.0f );
::auxWireCube( 1.0 );
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// GetNewDisplayListIDs
// This is just a nice wrapper for the glGenLists() function.
GLuint COpenGLView::GetNewDisplayListIDs( GLsizei range )
{
ASSERT( 0 < range );
return ::glGenLists( range );
}
/////////////////////////////////////////////////////////////////////////////
// RenderStockScene
// This routine performs a lazy-rendering of the stock scene; i.e. if the
// stock scene isn't yet a disply list, it generates the display list. In any
// event it then renders the disply list.
void COpenGLView::RenderStockScene()
{
// if the display list for the stock
// scene hasn't been generated, then do so
// the selected varaible is only used to change
// the stock scene
if ( m_SelectedStockScene )
{
GenerateStockScene( m_SelectedStockScene );
m_SelectedStockScene = eStockSceneSet; // clear it
}
if ( 0 != m_StockSceneListIndex )
{
::glCallList( m_StockSceneListIndex );
}
}
/////////////////////////////////////////////////////////////////////////////
// GenerateStockScene
// This routine simply generates the display list for the stock scene(s)
BOOL COpenGLView::GenerateStockScene( eStockSceneID id )
{
// if the display list for the stock
// scene hasn't been generated, then do so
// we'll reuse this ID for all stock scenes
if ( 0 == m_StockSceneListIndex )
{
// get a unique id
m_StockSceneListIndex = GetNewDisplayListID( );
if ( 0 == m_StockSceneListIndex ) // failed
{
return FALSE;
}
}
// we have an ID, so set (or reset) it
// and create the new stock scene
::glNewList( m_StockSceneListIndex, GL_COMPILE );
GenerateThisStockScene( id );
::glEndList();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// GenerateThisStockScene
// This routine generates the stock scenes. The functions
// called are simply expected to render a scene
void COpenGLView::GenerateThisStockScene( eStockSceneID id )
{
switch( id )
{
case eStockSceneSet:
case eStockSceneNone:
; // an empty list
break;
case eStockSceneUserDefined:
StockSceneUserDefined();
break;
case eStockSceneTriangles:
StockSceneTriangles();
break;
case eStockSceneCheckerboard:
StockSceneCheckerboard();
break;
case eStockSceneFlatSurface:
StockSceneFlatSurface();
break;
default:
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// StockSceneCheckerboard
// Draw a black and white checkerboard
// NOTE: You can use a quad strip and get better performance
// as long as you don't need smooth shading.
void COpenGLView::StockSceneCheckerboard( )
{
// define all vertices X Y Z
GLfloat v0[3], v1[3], v2[3], v3[3], delta;
int color = 0;
delta = 0.5f;
// define the two colors
GLfloat color1[3] = { 0.9f, 0.9f, 0.9f };
GLfloat color2[3] = { 0.05f, 0.05f, 0.05f };
v0[1] = v1[1] = v2[1] = v3[1] = 0.0f;
::glBegin( GL_QUADS );
int x, z;
for ( x = -5 ; x <= 5 ; x++ )
{
for ( z = -5 ; z <= 5 ; z++ )
{
::glColor3fv( (color++)%2 ? color1 : color2 );
v0[0] = 0.0f+delta*z;
v0[2] = 0.0f+delta*x;
v1[0] = v0[0]+delta;
v1[2] = v0[2];
v2[0] = v0[0]+delta;
v2[2] = v0[2]+delta;
v3[0] = v0[0];
v3[2] = v0[2]+delta;
::glVertex3fv( v0 );
::glVertex3fv( v1 );
::glVertex3fv( v2 );
::glVertex3fv( v3 );
}
}
::glEnd();
}
/////////////////////////////////////////////////////////////////////////////
// StockSceneTriangles
// Draw a square surface of red and blue triangles
// all touching the origin.
void COpenGLView::StockSceneTriangles( )
{
// define all vertices X Y Z
GLfloat surface0[3] = { 0.0f, 0.0f, 0.0f };
GLfloat surface1[3] = {+5.0f, 0.0f, 0.0f };
GLfloat surface2[3] = {+5.0f, 0.0f,-5.0f };
GLfloat surface3[3] = { 0.0f, 0.0f,-5.0f };
GLfloat surface4[3] = {-5.0f, 0.0f,-5.0f };
GLfloat surface5[3] = {-5.0f, 0.0f, 0.0f };
GLfloat surface6[3] = {-5.0f, 0.0f,+5.0f };
GLfloat surface7[3] = { 0.0f, 0.0f,+5.0f };
GLfloat surface8[3] = {+5.0f, 0.0f,+5.0f };
GLfloat surface9[3] = {+5.0f, 0.0f, 0.0f };
// define the two colors
GLfloat color1[3] = { 0.5f, 0.0f, 0.0f };
GLfloat color2[3] = { 0.0f, 0.0f, 0.5f };
::glBegin( GL_TRIANGLES );
::glColor3fv( color1 );
::glVertex3fv( surface0 );
::glVertex3fv( surface1 );
::glVertex3fv( surface2 );
::glColor3fv( color2 );
::glVertex3fv( surface0 );
::glVertex3fv( surface2 );
::glVertex3fv( surface3 );
::glColor3fv( color1 );
::glVertex3fv( surface0 );
::glVertex3fv( surface3 );
::glVertex3fv( surface4 );
::glColor3fv( color2 );
::glVertex3fv( surface0 );
::glVertex3fv( surface4 );
::glVertex3fv( surface5 );
::glColor3fv( color1 );
::glVertex3fv( surface0 );
::glVertex3fv( surface5 );
::glVertex3fv( surface6 );
::glColor3fv( color2 );
::glVertex3fv( surface0 );
::glVertex3fv( surface6 );
::glVertex3fv( surface7 );
::glColor3fv( color1 );
::glVertex3fv( surface0 );
::glVertex3fv( surface7 );
::glVertex3fv( surface8 );
::glColor3fv( color2 );
::glVertex3fv( surface0 );
::glVertex3fv( surface8 );
::glVertex3fv( surface9 );
::glEnd();
}
/////////////////////////////////////////////////////////////////////////////
// StockSceneFlatSurface
// Draw a dark-grey square surface
void COpenGLView::StockSceneFlatSurface( void )
{
// define vertices
GLfloat v0[2], v1[2];
// define the color (not too black!)
GLfloat color0[3] = { 0.2f, 0.2f, 0.2f };
v0[0] = v1[1] = -5.0f;
v0[1] = v1[0] = 5.0f;
::glColor3fv( color0 );
// glRect draws on the z=0 plane and we want it on the
// y=0 plane, so rotate about the x axis
::glRotatef( -90.0f, 1.0f, 0.0f, 0.0f );
::glRectfv( v0, v1 );
}
/////////////////////////////////////////////////////////////////////////////
// Draw3DAxes
// Draws lines along the current 3 axes from "start" units to "finish", with
// "ticks" tickmarks spaced out along it.
void COpenGLView::Draw3DAxes( float start, float finish, int ticks )
{
// make sure that start < finish
if ( start > finish )
{
float temp = start;
start = finish;
finish = start;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -