大二的时候开始想着做游戏,因为学校的课程实在是无聊就想着做些有意义的事情。毕竟学了编程这一行就得做些实事,于是就在网上搜了一下图形编程,偶然的了解到了Opengl (同时还有Windows上的Direct3D 但由于Opengl的跨平台等原因入了坑)。虽然到现在也没写出什么小游戏出来,毕竟一个用一个那么底层的图像接口做一个有玩法有乐趣的游戏工作量还是很大的。然后因为最近刚开了博客想起这段学习经历,于是这几天就再看了一下我之前写过的代码,把我的理解写下来希望对别人有帮助同时也写给未来的自己。
首先我是在Windows上编写OpenGL的,但网上大多数都叫你去下一个glut库来创建Windows窗口,因为这样简单方便不用再去学Windows的API。这些教程也就不需要再给你介绍这些东西,但我个人觉得应该用Windows的API来创建窗口;这因为Windows提供很多API,通过这些API我们可以实现很多功能,而创建窗口的这些API是很基础的;学习这些API你可以更好的了解Windows,而且使用API可以更加灵活的定制你自己想要的窗口和实现甘glut库没有提供的功能。对于Linux由于我学识有限还不知道怎么使用Opengl大家可以自行百度一下。
// Win32Project.cpp : 定义应用程序的入口点。 // #include "stdafx.h" //Windows消息循环 处理各种信息 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: return 0; case WM_CLOSE: PostQuitMessage(0); return 0; case WM_DESTROY: return 0; case WM_KEYDOWN: //键盘按下消息 return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } } //Windows程序入口函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; WNDCLASS wc; wc.style = CS_OWNDC; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("GLSample"); RegisterClass(&wc); //下面这个函数中间的4个数字前两个是屏幕的x,y后面是高宽 HWND hWnd = CreateWindowA("GLSample", "OpenGL Sample", WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 0, 0, 400, 600, NULL, NULL, hInstance, NULL); if (hWnd == NULL) return -1; hDC = GetDC(hWnd); PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; int iFormat = ChoosePixelFormat(hDC, &pfd); SetPixelFormat(hDC, iFormat, &pfd); hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); while (!bQuit) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { bQuit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { glClearColor(1.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 在这里添加Opengl代码 */ SwapBuffers(hDC); Sleep(10); } } wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); return msg.wParam; }
上面这个代码你要用Visual Studio或Visual C++创建一个Win32工程来使用,因为博主我用的是Visual Studio 2015所以以下的图片都是在VS2015截的,VS和VC的向导界面是不同的,但大概意思的选项还是能找到的,因为博主比较懒所以就只在关键步骤发图了。
打开VS或VC → 新建 → 项目
弹出创建向导,找到Visual C++下的Win32,里面有个Win32控制台和Win32项目,选择Win32项目写一个喜欢的项目名字点确定。
之后会再弹出一个向导,直接点下一步确定不,过要注意以下选项。
如果你是初学者,你应该在创建向导界面不要勾选空项目这个选项,他自己生成的代码可以帮助你更好的分析和入门
接下来VS会帮你创建好很多文件,这些文件你可能不知道有什么作用。
如下图:
但关键的文件就4个stdafx.h , stdafx.cpp ,你取的工程名加.h 和工程名.cpp(PS:这里我取得名字为Win32Project3)。
然后再简单讲解一下4个文件的作用
stdafx.h:你把VS自带的头文件例如<iostream>、<Windows.h>都包含在这个文件中。在你第一次编译时生成一个.pch文件之后编译编译器会利用这个文件加快你的编译速度
stdafx.cpp:包含stdafx.h头文件具体为什么要有这个文件我就不太清楚了知道的大佬可以留言给我
Win32Project.h:头文件可以写你自己定义的结构体、类和变量
Win32Project.cpp:这次我们的代码就写在这里WinMain主要的文件
现在创建好了一个工程你点调试→开始调试运行就能弹出一个Windows窗口
接下来双击打开Win32Project.cpp删除原来的代码把文章开头的代码粘贴过来
开始调试发现报错因为没有引入头文件
在stdafx.h文件中加入 #include <gl/GL.h>当然你也可以直接加在Win32Project.cpp文件里
再次调试运行 一般情况下都会出现如下结果
这是因为没有引入OpenGL的Lib库文件可以在stdafx.h 或 Win32Project.cpp加入#pragma comment(lib, "opengl32.lib")来引用OpenGL库文件
最后调试运行
如果你的窗口变黄了就代表你成功了
下篇Blog我打算写OpenGL的glew库的使用,个人觉得glew对OpenGL来说是十分重要的
最后就是博主是第一次写博文,写的不好多多包涵,有任何问题可以给我留言。
原文地址:https://www.cnblogs.com/yddsblog/p/11084835.html