OpenGL第二章_Hello word

OpenGL.h:

#pragma once

#include "resource.h"

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

OpenGL.cpp:

// OpenGL.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <gl\glut.h>
#include "OpenGL.h"

#include "GfxOpenGL.h"


bool exiting = false;		//程序是否退出.
long windowWidth = 800;		//窗口宽度.
long windowHeight = 600;	//窗口高度.
long windowBits = 32;		//每个相素的字节位.
bool fullscreen = false;	//是否全屏模式.
HDC hDC;					//窗口设备环境.

CGfxOpenGL *g_glRender = NULL;		//OpenGL渲染类的全局指针.

void SetupPixelFormat(HDC hDC) {
    int pixelFormat;

    PIXELFORMATDESCRIPTOR pfd = {   
        sizeof(PIXELFORMATDESCRIPTOR),  // 大小,
            1,                          // 版本都写1
            PFD_SUPPORT_OPENGL |        // OpenGL窗口
            PFD_DRAW_TO_WINDOW |        // 渲染窗口
            PFD_DOUBLEBUFFER,           // 支持双缓冲区.
            PFD_TYPE_RGBA,              // 颜色类型.
            32,                         // 颜色深度.
            0, 0, 0, 0, 0, 0,           // 颜色位数(忽略)
            0,                          // 没有alpha缓冲区.
            0,                          // alpha缓冲区字节位
            0,                          // 没有聚集缓冲区.
            0, 0, 0, 0,                 // 聚集字节位.
            16,                         // 深度缓冲区
            0,                          // 没有模板缓冲区
            0,                          // 没有辅助缓冲区.
            PFD_MAIN_PLANE,             // 主层冲
            0,                          // 保留
            0, 0, 0,                    // 没有层次, 可见性, 破损遮罩.
	};
    pixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, pixelFormat, &pfd);
}

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	static HDC hDC;
    static HGLRC hRC;	//渲染环境.
    int height, width;

    // 发送信息.
    switch (uMsg) {
		case WM_CREATE:         // 创建窗口.
			hDC = GetDC(hWnd);		//获取窗口的设备环境.
			SetupPixelFormat(hDC);	//
			hRC = wglCreateContext(hDC);	//创建渲染环境.
			wglMakeCurrent(hDC, hRC);		//使当前环境生效.
			break;

		case WM_DESTROY:            // 销毁窗口.
		case WM_QUIT:				//退出窗口.

		case WM_CLOSE:                  // 关闭窗口.
			wglMakeCurrent(hDC, NULL);	//取消渲染环境
			wglDeleteContext(hRC);		//删除渲染环境.
			PostQuitMessage(0);	//将WM_QUIT发送到消息队列.
			break;

		case WM_SIZE:			//大小改变时.
			height = HIWORD(lParam);        // 获取宽度和高度.
			width = LOWORD(lParam);
			g_glRender->SetupProjection(width, height);	
			break;

		case WM_ACTIVATEAPP:        // activate app
			break;

		case WM_PAINT:              // paint
			PAINTSTRUCT ps;
			BeginPaint(hWnd, &ps);
			EndPaint(hWnd, &ps);
			break;

		case WM_LBUTTONDOWN:        // left mouse button
			break;

		case WM_RBUTTONDOWN:        // right mouse button
			break;

		case WM_MOUSEMOVE:          // mouse movement
			break;

		case WM_LBUTTONUP:          // 左键弹起.
			break;

		case WM_RBUTTONUP:          // 右键弹起.
			break;

		case WM_KEYUP:
			break;

		case WM_KEYDOWN:
			int fwKeys;
			LPARAM keyData;
			fwKeys = (int)wParam;    // 虚键码.
			keyData = lParam;          // 按键数据.
			switch(fwKeys) {
				case VK_ESCAPE:
					PostQuitMessage(0);
					break;
				default:
					break;
			}
			break;

		default:
			break;
    }
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/**VS2010 应用程序入口**/
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX windowClass;		//窗口类.
	HWND hwnd;					//窗口句柄.
	MSG msg;					//消息.
	DWORD dwExStyle;			//窗口的扩展样式.
	DWORD dwStyle;				//窗口样式.
	RECT windowRect;			//窗口矩形.

	g_glRender = new CGfxOpenGL();
	windowRect.left = (long)0;
	windowRect.right = (long)windowWidth;
	windowRect.top = (long)0;
	windowRect.bottom = (long)windowHeight;

	//填写窗口类的结构.
	windowClass.cbSize          = sizeof(WNDCLASSEX);
    windowClass.style           = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc     = MainWindowProc;
    windowClass.cbClsExtra      = 0;
    windowClass.cbWndExtra      = 0;
    windowClass.hInstance       = hInstance;
    windowClass.hIcon           = LoadIcon(NULL, IDI_APPLICATION);  // 定义图标
    windowClass.hCursor         = LoadCursor(NULL, IDC_ARROW);      // 默认箭头
    windowClass.hbrBackground   = NULL;                             // 不要背景
    windowClass.lpszMenuName    = NULL;                             // 没有菜单
    windowClass.lpszClassName   = _T("GLClass");
    windowClass.hIconSm         = LoadIcon(NULL, IDI_WINLOGO);      // windows的小标记.

    // 注册windows 类
    if (!RegisterClassEx(&windowClass)) {
		return 0;
	}

	if (fullscreen) {                           // 是否全屏.
        DEVMODE dmScreenSettings;                   // 设备模式.
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));	
        dmScreenSettings.dmSize = sizeof(dmScreenSettings); 
        dmScreenSettings.dmPelsWidth = windowWidth;         // 屏幕宽度.
        dmScreenSettings.dmPelsHeight = windowHeight;           // 屏幕高度.
        dmScreenSettings.dmBitsPerPel = windowBits;             // 每个象素字节位.
        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
            // 设置显示模式失败, 切换为窗口模式.
            MessageBox(NULL, _T("Display mode failed"), NULL, MB_OK);
            fullscreen = FALSE; 
        }
    }

    if (fullscreen) {                           // 是否继续全屏模式. 
        dwExStyle=WS_EX_APPWINDOW;                  // 窗口扩展样式.隐藏顶层窗口.
        dwStyle=WS_POPUP;                       // 窗口样式.没有边缘的窗口.
        ShowCursor(FALSE);                      // 隐藏鼠标.
    } else {
        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;    // 窗口扩展样式. 
        dwStyle=WS_OVERLAPPEDWINDOW;                     // 窗口样式.
    }

	AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);     // 将窗口调整为所需大小.

	//类被注册.
	hwnd = CreateWindowEx(NULL,
				_T("GLClass"),                          // 类名
				_T("BOGLGP - Chapter 2 - OpenGL Application"),      // 应用程序的名称.
				dwStyle | WS_CLIPCHILDREN |
				WS_CLIPSIBLINGS,
				0, 0,                               // X和Y座标.
				windowRect.right - windowRect.left,
				windowRect.bottom - windowRect.top, // 宽度和高度.
				NULL,                               // 父句柄.
				NULL,                               // 菜单句柄.
				hInstance,                          // 应用程序实例.
				NULL);                              // 没有额外参数.

    hDC = GetDC(hwnd);

    // 查看窗口创建是否失败.(hwnd = NULL)
    if(!hwnd) return 0;

	ShowCursor(TRUE);					//显示鼠标.
    ShowWindow(hwnd, SW_SHOW);          //显示窗口.
    UpdateWindow(hwnd);					//更新窗口.
	g_glRender->Init();					//初始化PoenGL.

	while (!exiting) {
		g_glRender->Prepare(0.0f);		//
		g_glRender->Render();			//
        SwapBuffers(hDC);
			while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) {
			if(!GetMessage (&msg, NULL, 0, 0)) {
                exiting = true;
                break;
            }
			TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

	delete g_glRender;							//清除OpenGL
    if (fullscreen) {							//如果是全屏.
        ChangeDisplaySettings(NULL,0);          //切换到桌面.
        ShowCursor(TRUE);                       //显示鼠标.
    }

	return (int)msg.wParam;
}


GfxOpenGL.h

#pragma once
class CGfxOpenGL {

private:
	private:
	int m_windowWidth;
	int m_windowHeight;
	float m_angle;

public:
	CGfxOpenGL(void);
	~CGfxOpenGL(void);
	void CGfxOpenGL::Prepare(float ft);
	void CGfxOpenGL::SetupProjection(int width, int height);
	bool CGfxOpenGL::Init();
	void CGfxOpenGL::Render();
};

GfxOpenGL.cpp:

#include "StdAfx.h"
#include "GfxOpenGL.h"
#include <windows.h>
#include <gl/glut.h>

CGfxOpenGL::CGfxOpenGL(void) { }

CGfxOpenGL::~CGfxOpenGL(void) { }

//禁用隐式的浮点数值到双精度数值的转换.
#pragma warning(disable:4305);

//设置窗口的投影矩阵.
void CGfxOpenGL::SetupProjection(int width, int height) {
	if (height == 0) {					// 不能除以0;
		height = 1;					
	}

	glViewport(0, 0, width, height);		// 将窗口重设为新的尺寸.
	glMatrixMode(GL_PROJECTION);			// 将投影矩阵作为当前矩阵.
	glLoadIdentity();						// 设置投影矩阵.

	// 计算窗口的长宽比.
	gluPerspective(52.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);

	glMatrixMode(GL_MODELVIEW);				// 设置模型观察矩阵.
	glLoadIdentity();						// 重置模型观察矩阵.

	m_windowWidth = width;
	m_windowHeight = height;
}

//更新数据操作.
void CGfxOpenGL::Prepare(float ft){
	m_angle += 0.1f;
}

//初始化方法.
bool CGfxOpenGL::Init(){
	glClearColor(0.0, 0.0, 0.0, 0.0);	//将背景清除为黑色.
	m_angle = 0.1f;						//初始化浮点全局变量.
	return true;
}

//渲染场景.
void CGfxOpenGL::Render() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// 清除屏幕和深度缓冲区.
	glLoadIdentity();

	glTranslatef(0.0, 0.0, -5.0f);
    glRotatef(m_angle, 1.0f, 0.0f, 0.0f);
    glRotatef(m_angle, 0.0f, 1.0f, 0.0f);
    glRotatef(m_angle, 0.0f, 0.0f, 1.0f);

	glColor3f(0.7f, 1.0f, 0.3f);			//灰绿色.

	//在中间绘制旋转的三角型.
    glBegin(GL_TRIANGLES);
        glVertex3f(1.0f, -1.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 0.0f);
        glVertex3f(0.0f, 1.0f, 0.0f);
    glEnd();

}

获取当前环境: HGLRC wglGetCurrentContext(); .不存在返回NULL.

获取当前设备环境: HDC wglGetCurrentDC();


PIXELFORMATDESCRIPTOR结构的属必和行为:

typeof struct tagPIXELFORMATDESCRIPTOR{
	WORD 	nSize;			//结构大小. sizeof(PIXELFORMATDESCRIPTOR);
	WORD 	nVersion		//版本, 总被设置为1.
	DWORD 	dwFlags;		//像素缓冲区的属性标记.
	BYTE 	iPixelType;		//像素数据的类型.
	BYTE 	cColorBits;		//每个像素的字节位数.
	BYTE 	cRedBits;		//红色的字节位数.
	BYTE 	cRedShift;		//红色的移位计数.
	BYTE 	cGreenBits;		//绿色的字节位数.	
	BYTE 	cGreenShift;	//绿色的移位计数.
	BYTE 	cBlueBits;		//蓝色的字节位数.
	BYTE 	cBlueShift;		//蓝色的移位计数.
	BYTE 	cAlphaBits;		//alpha的字节位数.
	BYTE 	cAlphaShift;	//alpha的移位计数.
	BYTE 	cAccumBits;		//累加缓冲区的字节位数.
	BYTE 	cAccumRedBits;	//红色累加的字节位数.
	BYTE 	cAccumGreenBits;//绿色累加的字节位数.
	BYTE 	cAccumBlueBits;	//蓝色累加的字节位数.
	BYTE	cAccumAlphaBits;//alpha累加的字节位数.
	BYYE	cDepthBits;		//深度缓冲区的字节位数.
	BYTE	cStencliBits;	//特征缓冲区的字节位数.
	BYTE	cAuxBuffers;	//辅助缓冲区的字节位数.
	BYTE	iLayerType;		//不再使用.
	BYTE	bReserved;		//覆盖面和底层面的数量.
	DWORD	dwLayerMask;	//不再使用.
	DWORD	dwVisibleMask;	//平面色彩下的透明.
	DWORD	dwDamageMask;	//不再使用.
} PIXELFORMATDESCRIPTOR;



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值