Win32实现简单游戏引擎
来源:互联网 发布:c语言数据类型 编辑:程序博客网 时间:2024/04/25 19:30
通过win32实现了简单的游戏引擎,通过模拟游戏引擎的加载、图形渲染以及游戏退出的操作来理解游戏引擎的基本原理。
文中分别使用了GDI以及Direct3D来实现,希望对你有所帮助。
// MyEngine.cpp : 定义应用程序的入口点。//#include "stdafx.h"#include <stdio.h>#include "MyEngine.h"#include <time.h>#include <d3d9.h>#pragma comment(lib,"D3d9.lib")#define MAX_LOADSTRING 100// 全局变量: HINSTANCE hInst; // 当前实例WCHAR szTitle[] = L"游戏引擎 - FPS:0"; // 标题栏文本WCHAR szWindowClass[] = L"MyGameEngine"; // 主窗口类名HWND g_hMainWnd;TCHAR g_Key[256] = { 0 }; // 按键检测DWORD nWidth = 0; // 保存当前窗口的宽DWORD nHeight = 0; // 保存当前窗口的高LPDIRECT3D9 g_pD3D = NULL;LPDIRECT3DDEVICE9 g_pDev = NULL;LPDIRECT3DSURFACE9 g_pBackBuffer = NULL;LPDIRECT3DSURFACE9 g_pSurface = NULL;#define KEYDOWN(x) g_Key[x] DWORD GetRand(DWORD dwBase); // 获取随机数// 使用GDI绘图测试DWORD OnGameInit_GDI(); // 模拟游戏引擎的加载DWORD OnGameRender_GDI(); // 模拟游戏进行画面的渲染DWORD OnGameOver_GDI(); // 模拟游戏退出时的清理工作// 使用Direct3D测试bool OnGameInit_D3D(); // 模拟游戏引擎的加载bool OnGameRender_D3D(); // 模拟游戏进行画面的渲染DWORD OnGameOver_D3D(); // 模拟游戏退出时的清理工作LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow){ WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYENGINE)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); RegisterClassExW(&wcex); hInst = hInstance; // 将实例句柄存储在全局变量中 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 600, 300, 800, 600, nullptr, nullptr, hInstance, nullptr); if (!hWnd) return 0; g_hMainWnd = hWnd; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); //OnGameInit_GDI(); if (!OnGameInit_D3D())return 0; DWORD dwFPS = 0; // 帧率 DWORD dwLastTime = GetTickCount(); // 上一次渲染时间 DWORD dwNowTime = 0; // 当前渲染时间 DWORD dwLastFPSTime = dwLastTime; // 保存最后次计算FPS的时间 DWORD dwDelta = 0; // 每帧的运行时间 LARGE_INTEGER nLast; // 精确定时 LARGE_INTEGER nNow; LARGE_INTEGER _animationInterval; LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); _animationInterval.QuadPart = freq.QuadPart*1.0 / 60; QueryPerformanceCounter(&nLast); MSG msg = { 0 }; while (TRUE)// 此处 PeekMessage 与 GetMessage { if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))// 无论消息队列中是否有消息,都进行探测 { if (WM_QUIT == msg.message) break; TranslateMessage(&msg); DispatchMessage(&msg); } QueryPerformanceCounter(&nNow); dwFPS++; if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart) { //OnGameRender_GDI(); OnGameRender_D3D(); nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart); if (dwFPS) { char szTitle[32]; sprintf(szTitle, "游戏引擎 - FPS:%d", dwFPS); SetWindowTextA(g_hMainWnd, szTitle); dwFPS = 0; } } Sleep(1); // 使用GetTickCount控制帧率// OnGameRender_GDI();// OnGameRender_D3D();// dwFPS++;// dwNowTime = GetTickCount();// dwDelta = dwNowTime - dwLastTime; // 计算本帧的运行时间// // 控制每一帧在10ms左右// if (dwDelta < 20)// {// Sleep(20 - dwDelta);// }// // if ((dwNowTime - dwLastFPSTime) > 1000)// {// char szTitle[32];// if (dwFPS)// {// sprintf(szTitle, "游戏引擎 - FPS:%d", dwFPS);// SetWindowTextA(g_hMainWnd, szTitle);// dwLastFPSTime = dwNowTime;// dwFPS = 0;// }// }// dwLastTime = dwNowTime; // 保存上一次更新的时间 } //OnGameOver_GDI(); OnGameOver_D3D(); return (int) msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: g_Key[wParam] = 1; break; case WM_KEYUP: g_Key[wParam] = 0; break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}// 计算并获取0~dwBase的随机值DWORD GetRand(DWORD dwBase){ DWORD result = 0; __asm { rdtsc // 取CPU执行的指令数 mov result,eax } return result % dwBase;}DWORD OnGameInit_GDI(){ RECT rc; GetWindowRect(g_hMainWnd, &rc); nWidth = rc.right - rc.left; nHeight = rc.bottom - rc.top; return 0;}DWORD OnGameRender_GDI(){ if (KEYDOWN(VK_ESCAPE)) { SendMessage(g_hMainWnd, WM_CLOSE, 0, 0); } HDC hdc = GetDC(g_hMainWnd); HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); SelectObject(hdc, hPen); MoveToEx(hdc, GetRand(nWidth), GetRand(nHeight), NULL); LineTo(hdc, GetRand(nWidth), GetRand(nHeight)); DeleteObject(hPen); ReleaseDC(g_hMainWnd,hdc); return 0;}DWORD OnGameOver_GDI(){ return 0;}bool OnGameInit_D3D(){ // 初始化Direct3D g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if (NULL == g_pD3D) { MessageBox(g_hMainWnd, _T("Init Direct3D failed!"), _T("Error"), MB_OK | MB_ICONERROR); return false; } RECT rc; GetWindowRect(g_hMainWnd, &rc); nWidth = rc.right - rc.left; nHeight = rc.bottom - rc.top; D3DDISPLAYMODE displayMode; if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode))) return false; // 设置Direct3D的属性 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = displayMode.Format; d3dpp.BackBufferCount = 1; d3dpp.BackBufferWidth = nWidth; d3dpp.BackBufferHeight = nHeight; d3dpp.hDeviceWindow = g_hMainWnd; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // 按要求建立Direct3D设备 if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hMainWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pDev))) { int err1 = E_FAIL; int err = GetLastError(); MessageBox(g_hMainWnd, _T("CreateDevice failed!"), _T("Error"), MB_OK | MB_ICONERROR); return false; } //D3DERR_DEVICELOST D3DERR_INVALIDCALL D3DERR_NOTAVAILABLE D3DERR_OUTOFVIDEOMEMORY srand(time(NULL)); // 将背景色设置为黑色 g_pDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); // 获取后台渲染指针 if (FAILED(g_pDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackBuffer))) return false; // 建立离屏表面 (类似GDI双缓存) if(FAILED(g_pDev->CreateOffscreenPlainSurface(nWidth,nHeight,displayMode.Format, D3DPOOL_DEFAULT,&g_pSurface,NULL))) return false; return true;}bool OnGameRender_D3D(){ if (KEYDOWN(VK_ESCAPE)) SendMessage(g_hMainWnd, WM_CLOSE, 0, 0); // 确认Direct3D设备 if (!g_pDev) return false; // 开始渲染 if (g_pDev->BeginScene()) { // 将离屏幕表面填充随机颜色 int r = rand() % 255; int g = rand() % 255; int b = rand() % 255; g_pDev->ColorFill(g_pSurface, NULL, D3DCOLOR_XRGB(r, g, b)); // 画离屏表面到后台g_psurface的指定区域 RECT rc; rc.left = rand() % nWidth / 2; rc.right = rc.left + rand() % nWidth / 2; rc.top = rand() % nHeight; rc.bottom = rc.top + rand() % nHeight / 2; g_pDev->StretchRect(g_pSurface, NULL, g_pBackBuffer, &rc, D3DTEXF_NONE); // 定制渲染 g_pDev->EndScene(); // 完成后台画面与前台的交互 g_pDev->Present(NULL, NULL, NULL, NULL); } return 0;}DWORD OnGameOver_D3D(){ return 0;}
源码VS2015
本文难免有所错误,如有问题欢迎留言。
阅读全文
0 0
- Win32实现简单游戏引擎
- 3D游戏引擎一 win32编程
- 一个简单的游戏引擎核心状态机的C++实现
- HTML简单的游戏引擎实现第一篇
- 游戏服务器引擎实现
- Win32游戏制作之--游戏引擎的设计
- 简单盘点游戏开发引擎
- 【Android】基于andengine游戏引擎的简单游戏实现(模拟控制器、tiledmap地图)
- ajax简单引擎实现
- 【Cocos2d-X 游戏引擎】 Win32打包生成 Android 项目
- 贪吃蛇游戏win32 application实现
- 一个简单的2d游戏引擎
- 第二课:简单配置引擎,进入游戏。
- cocos2d-x开源游戏引擎,C++开发iphone/android/uphone/win32游戏
- AJAX引擎(简单实现)
- 简单正则表达式实现引擎
- 游戏引擎及其间单实现
- 使用游戏引擎实现的水波纹
- 没有技术博客的救赎
- 考研路茫茫——早起看书
- ADB学习笔记
- 设置火狐浏览器新打开的页面为百度首页
- EOF \n \0 NULL 之间的区别
- Win32实现简单游戏引擎
- 复杂链表的复制
- LUOGUP1801 黑匣子_NOI导刊2010提高(06)
- 在Eclipse下配置Python环境……
- Java ArrayList扩容
- 运行React项目报错:npm start --->
- Nginx、LVS及HAProxy负载均衡软件的优缺点详解
- jquery
- ssm的pon.xml文件