www.pudn.com > 3DMENUDEMO.zip > MENUDEMO.C


 
#include  
#include  
#include  
#include  
#include "texture.h" 
#include "menu.h" 
 
 
char *className = "OpenGL"; 
char *windowName = "OpenGL Menu Demo"; 
int winX = 0, winY = 0; 
int winWidth = 800, winHeight = 600; 
HDC hDC; 
HDC hDCFrontBuffer; 
HGLRC hGLRC; 
unsigned *teximage; 
 
//  装入纹理 
void LoadTexture(char *fn, int t_num) 
{ 
	int texwid, texht; 
	int texcomps; 
 
	teximage = read_texture(fn, &texwid, &texht, &texcomps);//e 
	if (!teximage) return; 
	glBindTexture(GL_TEXTURE_2D, texture[t_num]); 
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
 
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage); 
 
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
	 
	free(teximage); 
}  
 
void Init() 
{ 
	GLfloat light_ambient[] = {0.7f, 0.0f, 0.7f, 1.0f}; 
	GLfloat light_diffuse[] = {0.7f, 0.0f, 0.7f, 1.0f}; 
	GLfloat light_specular[] = {0.7f, 0.0f, 0.7f, 1.0f}; 
	GLfloat light_position[] = {0.0f, 0.0f, -10.0f, 0.0f}; 
 
	glGenTextures(14, texture);  
	// 将所有纹理读入内存 
	LoadTexture("textures/cursor.rgb", CURSOR_T); 
	LoadTexture("textures/cursor_transp.rgb", CURSOR_TRANSP_T); 
	LoadTexture("textures/border1.rgb", BORDER1_T); 
	LoadTexture("textures/border2.rgb", BORDER2_T); 
	LoadTexture("textures/border_up.rgb", BORDER3_T); 
	//LoadTexture("textures/pyramid.rgb", PYRAMID_T);//e 
	LoadTexture("textures/cube.rgb", CUBE_T); 
	LoadTexture("textures/sphere.rgb", SPHERE_T); 
	LoadTexture("textures/cbox.rgb", CBOX_T); 
	LoadTexture("textures/spindle.rgb", SPINDLE_T); 
	LoadTexture("textures/torus.rgb", TORUS_T); 
	LoadTexture("textures/line.rgb", LINE_T); 
	LoadTexture("textures/quit.rgb", QUIT_T); 
	// 装入模型文件 
	LoadMFile("models/cube.m", &models[0]); 
	LoadMFile("models/pyramid.m", &models[1]); 
	LoadMFile("models/sphere.m", &models[2]); 
	LoadMFile("models/spindle.m", &models[3]); 
	LoadMFile("models/torus.m", &models[4]); 
	LoadMFile("models/chamferbox.m", &models[5]); 
	// 初始化菜单 
	InitMenu(); 
	// 使用颜色混合 
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
	glEnable(GL_BLEND); 
	glDisable(GL_TEXTURE_2D); 
 
	// 设置光照参数 
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); 
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); 
	glLightfv(GL_LIGHT0, GL_POSITION, light_position); 
	glEnable(GL_LIGHT0); 
	glDepthFunc(GL_LESS); 
 
	glEnable(GL_DEPTH_TEST); 
	glEnable(GL_LIGHTING); 
	glEnable(GL_NORMALIZE); 
} 
 
void setProjection(void) 
{ 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	glFrustum(-0.6666, 0.6666, -0.5, 0.5, 2, 140); 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
} 
 
void resize(void) 
{ 
    glViewport(0, 0, winWidth, winHeight); 
    setProjection(); 
} 
 
void setupPixelFormat(HDC hDC) 
{ 
	PIXELFORMATDESCRIPTOR pfd = {  
	sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小  
	1,                                // 版本号  
	PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图  
	PFD_SUPPORT_OPENGL |              // 支持 OpenGL  
	PFD_DOUBLEBUFFER,                 // 双缓存模式  
	PFD_TYPE_RGBA,                    // RGBA 颜色模式  
	24,                               // 24 位颜色深度  
	0, 0, 0, 0, 0, 0,                 // 忽略颜色位  
	0,                                // 没有非透明度缓存  
	0,                                // 忽略移位位  
	0,                                // 无累加缓存  
	0, 0, 0, 0,                       // 忽略累加位  
	32,                               // 32 位深度缓存      
	0,                                // 无模板缓存  
	0,                                // 无辅助缓存  
	PFD_MAIN_PLANE,                   // 主层  
	0,                                // 保留  
	0, 0, 0                           // 忽略层,可见性和损毁掩模  
	}; 	 
 
	int SelectedPixelFormat; 
	BOOL retVal; 
 
	pfd.cColorBits = GetDeviceCaps(hDC, BITSPIXEL); 
 
	pfd.iPixelType = PFD_TYPE_RGBA; 
	pfd.dwFlags |= PFD_DOUBLEBUFFER; 
	pfd.dwFlags |= PFD_DRAW_TO_WINDOW; 
 
	SelectedPixelFormat = ChoosePixelFormat(hDC, &pfd); 
	if (SelectedPixelFormat == 0)  
	{ 
		(void) MessageBox(WindowFromDC(hDC), 
		"Failed to find acceptable pixel format.", 
		"OpenGL application error", 
		MB_ICONERROR | MB_OK); 
		exit(1); 
    } 
 
	retVal = SetPixelFormat(hDC, SelectedPixelFormat, &pfd); 
	if (retVal != TRUE) 
	{ 
		(void) MessageBox(WindowFromDC(hDC), 
		"Failed to set pixel format.", 
		"OpenGL application error", 
		MB_ICONERROR | MB_OK); 
		exit(1); 
	} 
} 
 
LRESULT APIENTRY WndProc( 
    HWND hWnd, 
    UINT message, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
	static UINT timer; 
	static int omx, omy, mx, my; 
 
	switch (message) 
	{ 
		case WM_CREATE: 
			timer = SetTimer(hWnd, 1, 2, NULL); 
			return 0; 
		case WM_DESTROY: 
			wglMakeCurrent(NULL, NULL); 
			wglDeleteContext(hGLRC); 
			KillTimer(hWnd, timer); 
			PostQuitMessage(0); 
			return 0; 
		case WM_SIZE: 
			if (hGLRC) 
			{ 
				winWidth = (int) LOWORD(lParam); 
				winHeight = (int) HIWORD(lParam); 
				resize(); 
				return 0; 
			} 
		case WM_PAINT: 
			if (hGLRC) 
			{ 
				PAINTSTRUCT ps; 
				BeginPaint(hWnd, &ps); 
				doRedraw(&hDC); 
				EndPaint(hWnd, &ps); 
				return 0; 
			} 
			break; 
		case WM_TIMER: 
			InvalidateRect(hWnd, NULL, FALSE); 
			return 0; 
 
		case WM_LBUTTONUP:  // 判断鼠标左键是否按下 
			mx = LOWORD(lParam); 
			my = HIWORD(lParam); 
			if  (mx & 1 << 15) mx -= (1 << 16); 
			if  (my & 1 << 15) my -= (1 << 16); 
			check_menu(1, mx, my, winWidth, winHeight, hWnd); 
			return 0; 
 
		case WM_MOUSEMOVE: // 判断鼠标是否移动 
			mx = LOWORD(lParam); 
			my = HIWORD(lParam); 
			if  (mx & 1 << 15) mx -= (1 << 16); 
			if  (my & 1 << 15) my -= (1 << 16); 
			check_menu(0, mx, my, winWidth, winHeight, hWnd); 
			return 0; 
 
		case WM_CHAR: 
			switch ((int)wParam)  
			{ 
				case VK_ESCAPE: // 是否按下ESC键 
					DestroyWindow(hWnd); 
					return 0; 
      			default: 
					break; 
			} 
			break; 
      default: 
	    break; 
   } 
 
  return DefWindowProc(hWnd, message, wParam, lParam); 
} 
 
int APIENTRY WinMain( 
    HINSTANCE hCurrentInst, 
    HINSTANCE hPreviousInst, 
    LPSTR lpszCmdLine, 
    int nCmdShow) 
{ 
	WNDCLASS wndClass; 
	HWND hWnd; 
	MSG msg; 
	HDC hdc; 
 
	// 获取当前的分辨率 
	hdc = GetDC(NULL);   
 
	wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
	wndClass.lpfnWndProc = WndProc; 
	wndClass.cbClsExtra = 0; 
	wndClass.cbWndExtra = 0; 
	wndClass.hInstance = hCurrentInst; 
	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
	wndClass.hbrBackground = NULL; 
	wndClass.lpszMenuName = NULL; 
	wndClass.lpszClassName = className; 
	RegisterClass(&wndClass); 
 
	hWnd = CreateWindow( 
		className, 
		windowName,	 
		WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION , 
		winX, winY, 
		winWidth, winHeight, 
		NULL, 
		NULL, 
		hCurrentInst, 
		NULL); 
 
	ShowCursor(FALSE); 
	ShowWindow(hWnd, nCmdShow); 
	UpdateWindow(hWnd); 
 
	hDC = GetDC(hWnd); 
	hDCFrontBuffer = hDC; 
	setupPixelFormat(hDC); 
	hGLRC = wglCreateContext(hDC); 
	wglMakeCurrent(hDC, hGLRC); 
	Init(); 
	setProjection(); 
 
	while (GetMessage(&msg, NULL, 0, 0)) 
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	} 
	ReleaseDC(hWnd, hDC); 
	return msg.wParam; 
}