www.pudn.com > coolMEMORY.rar > AS_OpenGL.cpp


//----------------------------------------------------------------------------- 
// File: AS_OpenGL.cpp 
//----------------------------------------------------------------------------- 
 
#include "AS_ENGINE.h" 
 
 
// Variables: ***************************************************************** 
// OpenGL info 
char *pbyOpenGLVersion, *pbyOpenGLChipInfo, *pbyOpenGLRendererInfo, 
	 *pbyOpenGLExtensionInfo; 
GLuint iFontTexture[1]; 
GLuint iFontBase; 
/////////////////////////////////////////////////////////////////////////////// 
 
// Functions: ***************************************************************** 
LRESULT CALLBACK OpenGLInfoProc(HWND, UINT, WPARAM, LPARAM); 
HRESULT ASInitOpenGL(AS_WINDOW *, HWND, HDC *, HGLRC *, BOOL); 
HRESULT ASDestroyOpenGL(AS_WINDOW *, HWND, HDC, HGLRC); 
void ASSetFillMode(void); 
void ASConfigOpenGL(int, int); 
void ASBuildFont(void); 
void ASKillFont(void); 
void ASPrint(int, int, char *, int); 
void ASSimplePrint(int, int, char *, int); 
/////////////////////////////////////////////////////////////////////////////// 
 
 
LRESULT CALLBACK OpenGLInfoProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) 
{ // begin OpenGLInfoProc() 
	char *pbyTemp, byTemp[256]; 
 
    switch(iMessage) 
    { 
        case WM_INITDIALOG: 
				_AS->WriteLogMessage("Open OpenGL dialog"); 
			    ShowWindow(hWnd, _AS->GetCmdShow()); 
				UpdateWindow(hWnd); 
            	SetDlgItemText(hWnd, IDC_OPENGL_VERSION_INFO, (const char *) pbyOpenGLVersion); 
            	SetDlgItemText(hWnd, IDC_OPENGL_CHIP_INFO, (const char *) pbyOpenGLChipInfo); 
            	SetDlgItemText(hWnd, IDC_OPENGL_RENDERER_INFO, (const char *) pbyOpenGLRendererInfo); 
				pbyTemp = pbyOpenGLExtensionInfo;  
				for(;;) 
				{ 
					if(sscanf(pbyTemp, "%s", byTemp) == EOF) 
						break; 
					SendDlgItemMessage(hWnd, IDC_OPENGL_EXTENSIONS_INFO, LB_ADDSTRING, 0, (LONG)(LPSTR) byTemp); 
					if(*(pbyTemp+strlen(byTemp)+1) == 0) 
						break; 
					pbyTemp += strlen((const char *) byTemp)+1; 
				} 
		return TRUE; 
 
        case WM_COMMAND: 
            switch(LOWORD(wParam)) 
            { 
                case ID_OPENGL_OK: 
					EndDialog(hWnd, FALSE); 
					_AS->WriteLogMessage("Close OpenGL dialog(OK)"); 
                return TRUE; 
            } 
        break; 
		 
		case WM_CLOSE: 
			SendMessage(hWnd, WM_COMMAND, ID_OPENGL_OK, 0); 
		break; 
    } 
    return FALSE; 
} // end OpenGLInfoProc() 
 
HRESULT ASInitOpenGL(AS_WINDOW *pWindow, HWND hWndT, HDC *hDC, HGLRC *hRC, BOOL bFullScreen) 
{ // begin ASInitOpenGL() 
	int PixelFormat; 
	HDC hDeskTopDC; 
	UCHAR byBits; 
	HWND hWnd; 
 
	_AS->WriteLogMessage("Init OpenGL for window"); 
	if(pWindow) 
		hWnd = *pWindow->GethWnd(); 
	else 
	{ 
		if(!hWndT) 
		{ 
			_AS->WriteLogMessage("There is no handle for this window!"); 
			return 1; 
		} 
		hWnd = hWndT; 
	}	 
	_AS->bFullScreen = bFullScreen; 
	if(bFullScreen) 
	{ 
		byBits = (UCHAR) _ASConfig->DevMode.dmBitsPerPel; 
		EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &ASSavedDisplayMode); 
		_AS->WriteLogMessage("Change display mode"); 
		_ASConfig->iWindowWidth = (int) _ASConfig->DevMode.dmPelsWidth; 
		_ASConfig->iWindowHeight = (int) _ASConfig->DevMode.dmPelsHeight; 
		if(ChangeDisplaySettings(&_ASConfig->DevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 
		{ 
			_AS->WriteLogMessage("Couln't change display mode"); 
			return 1; 
		} 
		_AS->ShowMouseCursor(FALSE); 
	} 
	else 
	{ 
		_AS->ShowMouseCursor(TRUE); 
		// Get destop color depth: 
		hDeskTopDC = GetDC(NULL); 
		byBits = GetDeviceCaps(hDeskTopDC, BITSPIXEL); 
		ReleaseDC(NULL, hDeskTopDC); 
	} 
	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 
		(UCHAR) byBits,								// 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 
		_ASConfig->byZBuffer,						// 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(!(*hDC = GetDC(hWnd)))					    // Did We Get A Device Context? 
	{ 
		_AS->WriteLogMessage("Can't Create A GL Device Context"); 
		ASDestroyOpenGL(pWindow, hWndT, *hDC, *hRC); 
		goto Failed; 
	} 
	if(!(PixelFormat = ChoosePixelFormat(*hDC, &pfd)))	// Did Windows Find A Matching Pixel Format? 
	{ 
		_AS->WriteLogMessage("Can't Find A Suitable PixelFormat"); 
		ASDestroyOpenGL(pWindow, hWndT, *hDC, *hRC); 
		goto Failed; 
	} 
	if(!SetPixelFormat(*hDC, PixelFormat, &pfd))		// Are We Able To Set The Pixel Format? 
	{ 
		_AS->WriteLogMessage("Can't Set The PixelFormat"); 
		ASDestroyOpenGL(pWindow, hWndT, *hDC, *hRC); 
		goto Failed; 
	} 
	if(!*hRC) 
		if(!(*hRC = wglCreateContext(*hDC)))				// Are We Able To Get A Rendering Context? 
		{ 
			_AS->WriteLogMessage("Can't Create A GL Rendering Context"); 
			ASDestroyOpenGL(pWindow, hWndT, *hDC, *hRC); 
			goto Failed; 
		} 
	if(!wglMakeCurrent(*hDC, *hRC)) 
		return 0; 
	RECT Rect; 
	GetWindowRect(hWnd, &Rect); 
	ASConfigOpenGL(Rect.right-Rect.left, Rect.bottom-Rect.top); 
	if(pWindow && pWindow->GetIsMainWindow()) 
	{ 
		_AS->WriteLogMessage("This is the main window"); 
		// Get OpenGL Information 
		// Version 
		if(pbyOpenGLVersion) 
			delete pbyOpenGLVersion; 
		pbyOpenGLVersion = new char[strlen((const char *) glGetString(GL_VERSION))+1]; 
		strcpy(pbyOpenGLVersion, (const char *) glGetString(GL_VERSION)); 
		// Chip Info 
		if(pbyOpenGLChipInfo) 
			delete pbyOpenGLChipInfo; 
		pbyOpenGLChipInfo = new char[strlen((const char *) glGetString(GL_VENDOR))+1]; 
		strcpy(pbyOpenGLChipInfo, (const char *) glGetString(GL_VENDOR)); 
		// Renderer Info 
		if(pbyOpenGLRendererInfo) 
			delete pbyOpenGLRendererInfo; 
		pbyOpenGLRendererInfo = new char[strlen((const char *) glGetString(GL_RENDERER))+1]; 
		strcpy(pbyOpenGLRendererInfo, (const char *) glGetString(GL_RENDERER)); 
		// Extensions Info 
		if(pbyOpenGLExtensionInfo) 
			delete pbyOpenGLExtensionInfo; 
		pbyOpenGLExtensionInfo = new char[strlen((const char *) glGetString(GL_EXTENSIONS))+1]; 
		strcpy(pbyOpenGLExtensionInfo, (const char *) glGetString(GL_EXTENSIONS)); 
	} 
	_AS->WriteLogMessage("Create fonts"); 
	if(pWindow) 
		pWindow->BuildFont(); 
	_AS->WriteLogMessage("OpenGL init complete"); 
	return 0; 
 
Failed: 
	MessageBox(NULL, M_CouldNotInitializeOpenGLGraphic, T_Error, MB_OK | MB_ICONINFORMATION); 
	return 1; 
} // end ASInitOpenGL() 
		 
HRESULT ASDestroyOpenGL(AS_WINDOW *pWindow, HWND hWndT, HDC hDC, HGLRC hRC) 
{ // begin ASDestroyOpenGL() 
	HWND hWnd; 
 
	_AS->WriteLogMessage("Destroy OpenGL from window"); 
	if(pWindow) 
		hWnd = *pWindow->GethWnd(); 
	else 
	{ 
		if(!hWndT) 
		{ 
			_AS->WriteLogMessage("There is no handle for this window!"); 
			return 1; 
		} 
		hWnd = hWndT; 
	} 
	if(!wglMakeCurrent(hDC, hRC)) 
		return 0; 
	if(pWindow && pWindow->GetIsMainWindow()) 
		_AS->WriteLogMessage("This is the main window"); 
	_AS->WriteLogMessage("Kill fonts"); 
	if(pWindow) 
		pWindow->KillFont(); 
	_AS->WriteLogMessage("Set display mode to default"); 
	glDisableClientState(GL_COLOR_ARRAY); 
	glDisableClientState(GL_VERTEX_ARRAY); 
	glDisableClientState(GL_NORMAL_ARRAY); 
	if(hRC)											// Do We Have A Rendering Context? 
	{ 
		if(!wglMakeCurrent(NULL, NULL))					// Are We Able To Release The DC And RC Contexts? 
			_AS->WriteLogMessage("Release Of DC And RC Failed"); 
		if(!wglDeleteContext(hRC))						// Are We Able To Delete The RC? 
			_AS->WriteLogMessage("Release Rendering Context Failed"); 
		hRC = NULL;										// Set RC To NULL 
	} 
	if(hDC && !ReleaseDC(hWnd, hDC))					// Are We Able To Release The DC 
		_AS->WriteLogMessage("Release Device Context Failed"); 
	hDC = NULL;										// Set DC To NULL 
	_AS->WriteLogMessage("OpenGL successful destroyed"); 
	ChangeDisplaySettings(&ASSavedDisplayMode, CDS_RESET); // Change it to the saved settings 
	_AS->ShowMouseCursor(TRUE); 
	return 0; 
} // ASDestroyOpenGL() 
 
void ASConfigOpenGL(int iWidth, int iHeight) 
{ // begin ASConfigOpenGL() 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
	glViewport(0, 0, iWidth, iHeight); 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	gluPerspective(45.f, (GLfloat)iWidth/(GLfloat)iHeight, 0.01f, 100.0f); 
	glMatrixMode(GL_MODELVIEW); 
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
	glClearDepth(100.0f); 
	glClearStencil(0); 
	glEnable(GL_DEPTH_TEST); 
	glDepthFunc(GL_LEQUAL); 
	if(!_ASConfig->bHightRenderQuality) 
	{ 
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 
		glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); 
		glFogi(GL_FOG_MODE, GL_EXP2); 
		glHint(GL_FOG, GL_FASTEST); 
		glHint(GL_FOG_HINT, GL_FASTEST); 
		glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); 
		glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); 
		glDisable(GL_DITHER); 
		glDisable(GL_COLOR_MATERIAL_FACE); 
	} 
	else 
	{ 
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
		glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
		glFogi(GL_FOG_MODE, GL_EXP2); 
		glHint(GL_FOG, GL_NICEST); 
		glHint(GL_FOG_HINT, GL_NICEST); 
		glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 
		glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); 
		glEnable(GL_DITHER); 
		glEnable(GL_COLOR_MATERIAL); 
		glEnable(GL_COLOR_MATERIAL_FACE); 
	} 
	glEnable(GL_CULL_FACE); 
	glCullFace(GL_BACK); 
	switch(_ASConfig->byLight) 
	{ 
		case 1: 
			glShadeModel(GL_FLAT); 
		break; 
 
		case 2: 
			glShadeModel(GL_SMOOTH); 
		break; 
	} 
	glColor4f(1.0f, 1.0f, 1.0f, 1.0); 
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); 
	glMateriali(GL_FRONT, GL_SHININESS,128); 
	glBlendFunc(GL_SRC_ALPHA, GL_ONE); 
	glEnable(GL_TEXTURE_2D); 
	ASEnableLighting();	 
	 
	// Setup the standart light: 
	GLfloat LightDiffuse[]	= { 0.01f, 0.01f, 0.01f, 1.0f };  
	GLfloat LightAmbient[]	= { 0.5f, 0.5f, 0.5f, 1.0f }; 
	GLfloat LightPosition[]	= { 0.0f, 0.0f, 0.0f, 1.0f }; 
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); 
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); 
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); 
	glEnable(GL_LIGHT1); 
 
	ASSetFillMode(); 
} // end ASConfigOpenGL() 
 
void ASSetFillMode(void) 
{ // begin ASSetFillMode() 
	// Set fill mode: 
	if(_ASConfig->bWireframeMode) 
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
	else 
		if(_ASConfig->bPointMode) 
			glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); 
		else 
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
} // end ASSetFillMode() 
 
void ASBuildFont(void) 
{ // begin ASBuildFont() 
	AS_TEXTURE Texture; 
	char byTemp[256]; 
	float cx, cy; 
 
	sprintf(byTemp, "%s%s\\Font.jpg", _AS->byProgramPath, _AS->byBitmapsDirectory); 
	ASLoadJpegRGB(&Texture, byTemp); 
	glPixelStorei(GL_UNPACK_ALIGNMENT,3); 
	glGenTextures(1, &iFontTexture[0]); 
	glBindTexture(GL_TEXTURE_2D, iFontTexture[0]); 
	if(_ASConfig->bUseMipmaps) 
	{ 
		if(_ASConfig->bFastTexturing) 
		{ 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST); 
			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Texture.iWidth, Texture.iHeight, GL_RGB, GL_UNSIGNED_BYTE, Texture.pbyData); 
		} 
		else 
		{ 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Texture.iWidth, Texture.iHeight, GL_RGB, GL_UNSIGNED_BYTE, Texture.pbyData); 
		} 
	} 
	else 
	{ 
		if(_ASConfig->bFastTexturing) 
		{ 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
			glTexImage2D(GL_TEXTURE_2D, 0, 3, Texture.iWidth, Texture.iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Texture.pbyData); 
		} 
		else 
		{ 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
			glTexImage2D(GL_TEXTURE_2D, 0, 3, Texture.iWidth, Texture.iHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Texture.pbyData); 
		} 
	} 
	SAFE_DELETE(Texture.pbyData); 
	iFontBase = glGenLists(256); 
	glBindTexture(GL_TEXTURE_2D, iFontTexture[0]); 
	for(int i = 0; i < 256; i++) 
	{ 
		cx = (float) (i%16)/16.0f; 
		cy = (float) (i/16)/16.0f; 
 
		glNewList(iFontBase+i, GL_COMPILE); 
			glBegin(GL_QUADS); 
				glTexCoord2f(cx, cy+0.0625f); 
				glVertex2i(0, 0); 
				glTexCoord2f(cx+0.0625f, cy+0.0625f); 
				glVertex2i(16, 0); 
				glTexCoord2f(cx+0.0625f, cy); 
				glVertex2i(16, 16); 
				glTexCoord2f(cx, cy); 
				glVertex2i(0, 16); 
			glEnd(); 
			glTranslated(10, 0, 0); 
		glEndList(); 
	} 
} // end ASBuildFont() 
 
void ASKillFont(void) 
{ // begin ASKillFont() 
	glDeleteTextures(1, &iFontTexture[0]); 
	if(glIsList(iFontBase)) 
		glDeleteLists(iFontBase, 256); 
} // end ASKillFont() 
 
void ASPrint(int x, int y, char *string, int set) 
{ // begin ASPrint() 
	glBindTexture(GL_TEXTURE_2D, iFontTexture[set]); 
	ASSimplePrint(x, y, string, iFontBase); 
} // end ASPrint() 
 
void ASSimplePrint(int x, int y, char *string, int iFontBase) 
{ // begin ASSimplePrint() 
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
	glDisable(GL_CULL_FACE); 
	glDisable(GL_DEPTH_TEST); 
	glMatrixMode(GL_PROJECTION); 
	glPushMatrix(); 
	glLoadIdentity(); 
	glOrtho(0, 640, 0, 480, -100, 100); 
	glMatrixMode(GL_MODELVIEW); 
	glPushMatrix(); 
	glLoadIdentity(); 
	glTranslated(x, y, 0); 
	glListBase(iFontBase); 
	glCallLists(strlen(string), GL_UNSIGNED_BYTE, string); 
	glMatrixMode(GL_PROJECTION); 
	glPopMatrix(); 
	glMatrixMode(GL_MODELVIEW); 
	glPopMatrix(); 
	glEnable(GL_DEPTH_TEST); 
	glEnable(GL_CULL_FACE); 
	ASSetFillMode(); 
} // end ASSimplePrint()