📄 opengl.cpp
字号:
#include "opengl.h"
#include "../global.h"
////////////////////////////////////////////////////////////////////////////////////
GcOpenGL::GcOpenGL():
hRC(NULL),
hDC(NULL),
m_hWnd(NULL),
m_multiTextureSupport(false),
m_vertexArraySupport(false),
m_fogSupport(false)
{
// Constructing the OpenGL object
}
////////////////////////////////////////////////////////////////////////////////////
GcOpenGL::~GcOpenGL()
{
// Destroying the OpenGL object
}
////////////////////////////////////////////////////////////////////////////////////
bool GcOpenGL::Init( HWND hParent, int width, int height, int depth )
{
m_screenWidth = width;
m_screenHeight = height;
m_screenDepth = depth;
// Check for a legal window handle
if(!hParent) {
return false;
}
m_hWnd = hParent;
// Set the pixel format
if(!SetupPixelFormat())
{
Close();
return false;
}
// Set up the OpenGL window
if(!SetupGLWindow())
{
Close();
return false;
}
// Set up the OpenGL state machine
SetupGLState();
return true;
}
////////////////////////////////////////////////////////////////////////////////////
bool GcOpenGL::Close()
{
/* Do We Have A Rendering Context? */
if(hRC)
{
/* Are We Able To Release The DC And RC Contexts? */
if(!wglMakeCurrent(NULL, NULL))
{
MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR",
MB_OK | MB_ICONINFORMATION );
g_Debug->Log("Release of DC and RC failed.\n");
}
// Are We Able To Delete The RC?
if(!wglDeleteContext(hRC))
{
MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR",
MB_OK | MB_ICONINFORMATION );
g_Debug->Log("Release rendering context failed.\n");
}
// Set RC To NULL
hRC = NULL;
}
/* Are We Able To Release The DC */
if(hDC && m_hWnd)
{
if(!ReleaseDC(m_hWnd, hDC))
{
MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR",
MB_OK | MB_ICONINFORMATION );
g_Debug->Log("Release device context failed.\n");
// Set DC To NULL
hDC = NULL;
m_hWnd = NULL;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////
void GcOpenGL::SetPerspective(int iWidth, int iHeight)
{
m_screenWidth = iWidth;
m_screenHeight = iHeight;
/* Reset The Current Viewport */
glViewport( 0, 0, iWidth, iHeight );
/* Select The Projection Matrix */
glMatrixMode(GL_PROJECTION);
/* Reset The Projection Matrix */
glLoadIdentity();
/* Calculate The Aspect Ratio Of The Window */
gluPerspective(45.0f, (GLfloat)iWidth / (GLfloat)iHeight, 4.0f, 15000.0f);
/* Select The Modelview Matrix */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
////////////////////////////////////////////////////////////////////////////////////
bool GcOpenGL::SetupPixelFormat()
{
/* Setup the PIXELFORMATDESCRIPTOR */
m_pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); /* Size Of This Pixel Format Descriptor */
m_pfd.nVersion = 1; /* Version Number */
m_pfd.dwFlags = PFD_DRAW_TO_WINDOW /* Format Must Support Window */
| PFD_SUPPORT_OPENGL /* Format Must Support OpenGL */
| PFD_DOUBLEBUFFER; /* Must Support Double Buffering */
m_pfd.iPixelType = PFD_TYPE_RGBA; /* Request An RGBA Format */
m_pfd.cColorBits = m_screenDepth; /* Select Our Color Depth */
m_pfd.cRedBits = 0; /* Color Bits Ignored */
m_pfd.cRedShift = 0;
m_pfd.cGreenBits = 0;
m_pfd.cGreenShift = 0;
m_pfd.cBlueBits = 0;
m_pfd.cBlueShift = 0;
m_pfd.cAlphaBits = 0; /* No Alpha Buffer */
m_pfd.cAlphaShift = 0; /* Shift Bit Ignored */
m_pfd.cAccumBits = 0; /* No Accumulation Buffer */
m_pfd.cAccumRedBits = 0; /* Accumulation Bits Ignored */
m_pfd.cAccumGreenBits = 0;
m_pfd.cAccumBlueBits = 0;
m_pfd.cAccumAlphaBits = 0;
m_pfd.cDepthBits = 16; /* 16Bit Z-Buffer (Depth Buffer) */
m_pfd.cStencilBits = 0; /* No Stencil Buffer */
m_pfd.cAuxBuffers = 0; /* No Auxiliary Buffer */
m_pfd.iLayerType = PFD_MAIN_PLANE; /* Main Drawing Layer */
m_pfd.bReserved = 0; /* Reserved */
m_pfd.dwLayerMask = 0; /* Layer Masks Ignored */
m_pfd.dwVisibleMask = 0;
m_pfd.dwDamageMask = 0;
if(!(hDC = GetDC(m_hWnd)))
{
Close();
MessageBox(NULL, "Can't create a gl device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
g_Debug->Log("Can't create a gl device context.\n");
return false;
}
/* Did Windows Find A Matching Pixel Format? */
if(!( iPixelFormat = ChoosePixelFormat( hDC, &m_pfd)))
{
Close();
MessageBox(NULL, "Can't find a suitable pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
g_Debug->Log("Can't find a suitable pixel format.\n");
return false;
}
/* Are We Able To Set The Pixel Format? */
if(!SetPixelFormat(hDC, iPixelFormat, &m_pfd))
{
Close();
MessageBox(NULL, "Can't set the pixel format.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
g_Debug->Log("Can't set the pixel format.\n");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////
bool GcOpenGL::SetupGLWindow()
{
/* Are We Able To Get A Rendering Context? */
if(!(hRC = wglCreateContext(hDC)))
{
Close();
MessageBox(NULL, "Can't create a GL Rendering context.", "ERROR",
MB_OK | MB_ICONEXCLAMATION );
g_Debug->Log("Can't create a GL Rendering context.\n");
return false;
}
/* Try To Activate The Rendering Context */
if(!wglMakeCurrent(hDC, hRC))
{
Close();
MessageBox(NULL, "Can't activate the GL Rendering context.", "ERROR",
MB_OK | MB_ICONEXCLAMATION );
g_Debug->Log("Can't activate the GL Rendering context.\n");
return false;
}
// Set Up Our Perspective GL Screen
SetPerspective(m_screenWidth, m_screenHeight);
return true;
}
////////////////////////////////////////////////////////////////////////////////////
void GcOpenGL::SetupGLState()
{
// Clear background to black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Use smooth shading
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
// Don't calculate inside of polys
glEnable(GL_CULL_FACE);
// Counter clockwise polygones cut
glFrontFace(GL_CCW);
// Enable the "colorkey"
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
// Enable 2D texturing
glEnable(GL_TEXTURE_2D);
// Enable detail texturing if suported
SetupMultitexturing();
// Enable volumetric fog if suported and desiered
SetupFog();
// Eanble video memory if suported
SetupVertexArrayRange();
// Enable vertex and texture coord arrays
if(GcSettings::Light()) {
glEnableClientState(GL_NORMAL_ARRAY);
glEnable(GL_LIGHT0); // Turn on a light with defaults set
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Allow color
}
if(GcSettings::ColorArray()) {
glEnableClientState(GL_COLOR_ARRAY);
}
}
////////////////////////////////////////////////////////////////////////////////////
void GcOpenGL::SetupMultitexturing()
{
// Find out if the card suport multitexturing
GcSettings::MultiTexture(CheckSupport("GL_ARB_multitexture",
(char*)glGetString(GL_EXTENSIONS)));
m_multiTextureSupport = CheckSupport("GL_ARB_multitexture", (char *)glGetString(GL_EXTENSIONS));
// Initialize the multi texturing
if(GcSettings::MultiTexture()) // FIX ME: Multitexture?
{
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)
wglGetProcAddress("glMultiTexCoord2fARB");
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)
wglGetProcAddress("glActiveTextureARB");
glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)
wglGetProcAddress("glClientActiveTextureARB");
}
else {
g_Debug->Log("Multitexturing not suported\n");
}
}
////////////////////////////////////////////////////////////////////////////////////
void GcOpenGL::SetupFog()
{
// Find out if volumetric fog is supported
m_fogSupport = CheckSupport("GL_EXT_fog_coord", (char*)glGetString(GL_EXTENSIONS));
// Use fog?
if(GcSettings::Fog() && m_fogSupport)
{
// Get the extension for the volumetric fog
glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)
wglGetProcAddress("glFogCoordPointerEXT");
glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)
wglGetProcAddress("glFogCoordfEXT");
float color[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
glEnable(GL_FOG);
glFogfv(GL_FOG_COLOR, color);
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, 0.0f);
glFogf(GL_FOG_END, 1000.0f);
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
}
else
{
GcSettings::Fog(false);
}
}
////////////////////////////////////////////////////////////////////////////////////
void GcOpenGL::SetupVertexArrayRange()
{
// Find out if the vertex data can be stored on the gfx card
//settings.VideoMemory();
m_vertexArraySupport = CheckSupport("GL_NV_vertex_array_range", (char *)glGetString(GL_EXTENSIONS));
GcSettings::VideoMemory(m_vertexArraySupport);
if(m_vertexArraySupport)
{
glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)
wglGetProcAddress("glFlushVertexArrayRangeNV");
glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)
wglGetProcAddress("glVertexArrayRangeNV");
wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)
wglGetProcAddress("wglAllocateMemoryNV");
wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)
wglGetProcAddress("wglFreeMemoryNV");
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
////////////////////////////////////////////////////////////////////////////////////
bool GcOpenGL::CheckSupport(char *check, char *str)
{
char *endOfStr;
uint i = 0;
// Last char of the string
endOfStr = str + strlen(str);
while(str < endOfStr)
{
// Find a space
i = strcspn(str, " ");
// Check to see if the string match the one looked for
if((strlen(check) == i) && (strncmp(check, str, i) == 0)) {
return true;
}
str += i + 1;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -