📄 mgcoglrenderer.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement. The various license agreements may be found at
// the Magic Software web site. This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf
#include "MgcOglRenderer.h"
#include "MgcPolyline.h"
#include "MgcTriMesh.h"
MgcImplementRTTI(MgcOglRenderer,MgcRenderer);
MgcImplementStream(MgcOglRenderer);
//----------------------------------------------------------------------------
MgcOglRenderer::MgcOglRenderer (HWND hWnd, int iWidth, int iHeight)
:
MgcRenderer(iWidth,iHeight)
{
CreateRenderer(hWnd);
}
//----------------------------------------------------------------------------
MgcOglRenderer::MgcOglRenderer ()
{
}
//----------------------------------------------------------------------------
MgcOglRenderer::~MgcOglRenderer ()
{
if ( m_hWindowRC )
wglDeleteContext(m_hWindowRC);
if ( m_hWindowDC )
ReleaseDC(m_hWnd,m_hWindowDC);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::CreateRenderer (HWND hWnd)
{
assert( m_iWidth > 0 && m_iHeight > 0 );
m_hWnd = hWnd;
m_hWindowDC = GetDC(m_hWnd);
// select format for drawing surface
PIXELFORMATDESCRIPTOR kPFD;
memset(&kPFD,0,sizeof(PIXELFORMATDESCRIPTOR));
kPFD.nSize = sizeof(PIXELFORMATDESCRIPTOR);
kPFD.nVersion = 1;
kPFD.dwFlags =
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_GENERIC_ACCELERATED |
PFD_DOUBLEBUFFER;
kPFD.iPixelType = PFD_TYPE_RGBA;
kPFD.cColorBits = 16; // 16-bit colors for front/back buffers
kPFD.cDepthBits = 16; // 16-bit depth buffer
// set the pixel format for the rendering context
int iPixelFormat = ChoosePixelFormat(m_hWindowDC,&kPFD);
if ( iPixelFormat == 0 )
{
m_bConstructed = false;
return;
}
BOOL bSuccess = SetPixelFormat(m_hWindowDC,iPixelFormat,&kPFD);
if ( !bSuccess )
{
m_bConstructed = false;
return;
}
// create an OpenGL context
m_hWindowRC = wglCreateContext(m_hWindowDC);
if ( !m_hWindowRC )
{
m_bConstructed = false;
return;
}
bSuccess = wglMakeCurrent(m_hWindowDC,m_hWindowRC);
if ( !bSuccess )
{
m_bConstructed = false;
return;
}
m_bConstructed = true;
GetDriverInformation();
InitializeState();
}
//----------------------------------------------------------------------------
void MgcOglRenderer::GetDriverInformation ()
{
// get OpenGL extensions
char* acVendor = (char*) glGetString(GL_VENDOR);
char* acRenderer = (char*) glGetString(GL_RENDERER);
char* acVersion = (char*) glGetString(GL_VERSION);
char* acGluVersion = (char*) gluGetString(GLU_VERSION);
char* acExtensions =
new char[strlen((const char*)glGetString(GL_EXTENSIONS))+1];
strcpy(acExtensions,(const char*)glGetString(GL_EXTENSIONS));
// create message buffer (include space for prefixs and null terminator)
int iMaxLength = strlen(acVendor);
int iLength = strlen(acRenderer);
if ( iLength > iMaxLength )
iMaxLength = iLength;
iLength = strlen(acVersion);
if ( iLength > iMaxLength )
iMaxLength = iLength;
iLength = strlen(acGluVersion);
if ( iLength > iMaxLength )
iMaxLength = iLength;
iLength = strlen(acExtensions);
if ( iLength > iMaxLength )
iMaxLength = iLength;
iMaxLength += 16;
char* acMessage = new char[iMaxLength];
sprintf(acMessage,"Vendor: %s\n",acVendor);
OutputDebugString(acMessage);
sprintf(acMessage,"Renderer: %s\n",acRenderer);
OutputDebugString(acMessage);
sprintf(acMessage,"Version: %s\n",acVersion);
OutputDebugString(acMessage);
sprintf(acMessage,"GLU Version: %s\n",acGluVersion);
OutputDebugString(acMessage);
OutputDebugString("Extensions:\n");
char* acToken = strtok(acExtensions," \t\r\n");
while ( acToken )
{
sprintf(acMessage," %s\n",acToken);
OutputDebugString(acMessage);
acToken = strtok(0," \t\r\n");
}
delete[] acExtensions;
delete[] acMessage;
}
//----------------------------------------------------------------------------
void MgcOglRenderer::SetBackgroundColor (const MgcColor& rkColor)
{
MgcRenderer::SetBackgroundColor(rkColor);
glClearColor(rkColor.r,rkColor.g,rkColor.b,1.0f);
}
//---------------------------------------------------------------------------
void MgcOglRenderer::ClearBackBuffer ()
{
glDisable(GL_DITHER);
glEnable(GL_SCISSOR_TEST);
glScissor(0,0,m_iWidth,m_iHeight);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_DITHER);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::DisplayBackBuffer ()
{
glFlush();
SwapBuffers(m_hWindowDC);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::ClearZBuffer ()
{
glDisable(GL_DITHER);
glEnable(GL_SCISSOR_TEST);
glScissor(0,0,m_iWidth,m_iHeight);
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_DITHER);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::ClearBuffers ()
{
glDisable(GL_DITHER);
glEnable(GL_SCISSOR_TEST);
glScissor(0,0,m_iWidth,m_iHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_DITHER);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::InitializeState ()
{
MgcRenderer::InitializeState();
// do back face culling (front faces are counterclockwise ordered)
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
// vertices always exist
glEnableClientState(GL_VERTEX_ARRAY);
// no global ambient lighting
GLfloat afBlack[4] = { 0.0, 0.0, 0.0, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,afBlack);
}
//----------------------------------------------------------------------------
void MgcOglRenderer::Draw (const MgcTriMesh& rkMesh)
{
// set world matrix
const MgcMatrix3& rkRot = rkMesh.WorldRotate();
const MgcVector3& rkTrn = rkMesh.WorldTranslate();
MgcReal fScale = rkMesh.WorldScale();
GLfloat afModelToWorld[16] =
{
fScale*rkRot[0][0], fScale*rkRot[1][0], fScale*rkRot[2][0], 0.0f,
fScale*rkRot[0][1], fScale*rkRot[1][1], fScale*rkRot[2][1], 0.0f,
fScale*rkRot[0][2], fScale*rkRot[1][2], fScale*rkRot[2][2], 0.0f,
rkTrn.x, rkTrn.y, rkTrn.z, 1.0f
};
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(afModelToWorld);
// render the object
GLfloat* afVertices = (GLfloat*) rkMesh.Vertices();
glVertexPointer(3,GL_FLOAT,0,afVertices);
GLfloat* afNormals = (GLfloat*) rkMesh.Normals();
if ( afNormals )
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,afNormals);
}
else
{
glDisableClientState(GL_NORMAL_ARRAY);
}
GLfloat* afColors = (GLfloat*) rkMesh.Colors();
if ( afColors )
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3,GL_FLOAT,0,afColors);
}
else
{
glDisableClientState(GL_COLOR_ARRAY);
}
GLfloat* afTextures = (GLfloat*) rkMesh.Textures();
if ( afTextures )
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,afTextures);
}
else
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glDrawElements(GL_TRIANGLES,3*rkMesh.GetTriangleQuantity(),
GL_UNSIGNED_INT,rkMesh.Connectivity());
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
//----------------------------------------------------------------------------
void MgcOglRenderer::Draw (const MgcPolyline& rkLine)
{
// set world matrix
const MgcMatrix3& rkRot = rkLine.WorldRotate();
const MgcVector3& rkTrn = rkLine.WorldTranslate();
MgcReal fScale = rkLine.WorldScale();
GLfloat afModelToWorld[16] =
{
fScale*rkRot[0][0], fScale*rkRot[1][0], fScale*rkRot[2][0], 0.0f,
fScale*rkRot[0][1], fScale*rkRot[1][1], fScale*rkRot[2][1], 0.0f,
fScale*rkRot[0][2], fScale*rkRot[1][2], fScale*rkRot[2][2], 0.0f,
rkTrn.x, rkTrn.y, rkTrn.z, 1.0f
};
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(afModelToWorld);
// render the object
glBegin(GL_LINES);
// draw line
const MgcVector3* akVertex = rkLine.Vertices();
unsigned int uiL;
if ( rkLine.Colors() )
{
const MgcColor* akColor = rkLine.Colors();
for (uiL = 0; uiL < rkLine.GetVertexQuantity() - 1; uiL++)
{
glColor3fv((GLfloat*)akColor++);
glVertex3fv((GLfloat*)akVertex++);
glColor3fv((GLfloat*)akColor++);
glVertex3fv((GLfloat*)akVertex++);
}
// close the polyline
if ( rkLine.Closed() )
{
glColor3fv((GLfloat*)akColor);
glVertex3fv((GLfloat*)akVertex);
glColor3fv((GLfloat*)rkLine.Colors());
glVertex3fv((GLfloat*)rkLine.Vertices());
}
}
else
{
for (uiL = 0; uiL < rkLine.GetVertexQuantity() - 1; uiL++)
{
glVertex3fv((GLfloat*)akVertex++);
glVertex3fv((GLfloat*)akVertex++);
}
// close the polyline
if ( rkLine.Closed() )
{
glVertex3fv((GLfloat*)akVertex);
glVertex3fv((GLfloat*)rkLine.Vertices());
}
}
glEnd();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
//----------------------------------------------------------------------------
//---------------------------------------------------------------------------
// streaming
//---------------------------------------------------------------------------
MgcObject* MgcOglRenderer::Factory (MgcStream& rkStream)
{
MgcOglRenderer* pkObject = new MgcOglRenderer;
MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
pkObject->Load(rkStream,pkLink);
return pkObject;
}
//---------------------------------------------------------------------------
void MgcOglRenderer::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcRenderer::Load(rkStream,pkLink);
}
//---------------------------------------------------------------------------
void MgcOglRenderer::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcRenderer::Link(rkStream,pkLink);
}
//---------------------------------------------------------------------------
bool MgcOglRenderer::Register (MgcStream& rkStream)
{
return MgcRenderer::Register(rkStream);
}
//---------------------------------------------------------------------------
void MgcOglRenderer::Save (MgcStream& rkStream)
{
MgcRenderer::Save(rkStream);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// debugging
//---------------------------------------------------------------------------
bool MgcOglRenderer::OperationOkay ()
{
GLenum eCode = glGetError();
if ( eCode == GL_NO_ERROR )
return true;
char acMsg[128];
sprintf(acMsg,"Error: %s\n",gluErrorString(eCode));
OutputDebugString(acMsg);
return false;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -