• C语言集锦(三)Direct3D和GDI+的例子


    0.前言

      有些时候你可能想了解,如何用纯C语言来写Direct3D和GDI+的Demo。注意,下面的Direct3D例子不适用于TCC编译器,GDI+的例子是可以的。

    1.Direct3D C语言的例子

      几乎所有的D3D例子都是用COM和C++写的。C语言可以用D3D吗,StackOverflow上给出了答案:directx-programming-in-c

    1 hr = IDirect3D9_GetDeviceCaps(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dcaps9);
    2 hr = IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm);
    3 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, game_window, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &d3d_dev);

      按照这种格式,可以用C语言写出Direct3D的Demo:

      1 #include<d3d9.h>  
      2 
      3 #pragma comment(lib, "d3d9.lib")   
      4 
      5 #define WINDOW_CLASS "UGPDX"  
      6 #define WINDOW_NAME  "Drawing Lines"  
      7 
      8 // Function Prototypes...  
      9 BOOL InitializeD3D(HWND hWnd, BOOL fullscreen);
     10 BOOL InitializeObjects();
     11 void RenderScene();
     12 void Shutdown();
     13 
     14 
     15 // Direct3D object and device.  
     16 LPDIRECT3D9 g_D3D = NULL;
     17 LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
     18 
     19 // Vertex buffer to hold the geometry.  
     20 LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;
     21 
     22 
     23 // A structure for our custom vertex type  
     24 typedef struct 
     25 {
     26     float x, y, z, rhw;
     27     unsigned long color;
     28 }stD3DVertex;
     29 
     30 // Our custom FVF, which describes our custom vertex structure.  
     31 #define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)   
     32 
     33 
     34 LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
     35 {
     36     switch (msg)
     37     {
     38     case WM_DESTROY:
     39         PostQuitMessage(0);
     40         return 0;
     41         break;
     42 
     43     case WM_KEYUP:
     44         if (wp == VK_ESCAPE) PostQuitMessage(0);
     45         break;
     46     }
     47 
     48     return DefWindowProc(hWnd, msg, wp, lp);
     49 }
     50 
     51 
     52 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst,
     53     LPSTR cmdLine, int show)
     54 {
     55     // Register the window class  
     56     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
     57         0, 0, GetModuleHandle(NULL), NULL, LoadCursor(NULL,IDC_ARROW),
     58         NULL, NULL, WINDOW_CLASS, NULL };
     59     RegisterClassEx(&wc);
     60 
     61     // Create the application's window  
     62     HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME,
     63         WS_OVERLAPPEDWINDOW, 100, 100,
     64         640, 480, GetDesktopWindow(), NULL,
     65         wc.hInstance, NULL);
     66 
     67     // Initialize Direct3D  
     68     if (InitializeD3D(hWnd, FALSE))
     69     {
     70         // Show the window  
     71         ShowWindow(hWnd, SW_SHOWDEFAULT);
     72         UpdateWindow(hWnd);
     73 
     74         // Enter the message loop  
     75         MSG msg;
     76         ZeroMemory(&msg, sizeof(msg));
     77 
     78         while (msg.message != WM_QUIT)
     79         {
     80             if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
     81             {
     82                 TranslateMessage(&msg);
     83                 DispatchMessage(&msg);
     84             }
     85             else
     86                 RenderScene();
     87         }
     88     }
     89 
     90     // Release any and all resources.  
     91     Shutdown();
     92 
     93     // Unregister our window.  
     94     UnregisterClass(WINDOW_CLASS, wc.hInstance);
     95     return 0;
     96 }
     97 
     98 
     99 BOOL InitializeD3D(HWND hWnd, BOOL fullscreen)
    100 {
    101     D3DDISPLAYMODE displayMode;
    102 
    103     // Create the D3D object.  
    104     g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
    105     if (g_D3D == NULL) return FALSE;
    106 
    107 
    108     // Get the desktop display mode.  
    109     if (FAILED(IDirect3D9_GetAdapterDisplayMode(g_D3D,D3DADAPTER_DEFAULT,
    110         &displayMode))) return FALSE;
    111 
    112 
    113     // Set up the structure used to create the D3DDevice  
    114     D3DPRESENT_PARAMETERS d3dpp;
    115     ZeroMemory(&d3dpp, sizeof(d3dpp));
    116 
    117 
    118     if (fullscreen)
    119     {
    120         d3dpp.Windowed = FALSE;
    121         d3dpp.BackBufferWidth = 640;
    122         d3dpp.BackBufferHeight = 480;
    123     }
    124     else
    125         d3dpp.Windowed = TRUE;
    126     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    127     d3dpp.BackBufferFormat = displayMode.Format;
    128 
    129 
    130     // Create the D3DDevice  
    131     if (FAILED(IDirect3D9_CreateDevice(g_D3D,D3DADAPTER_DEFAULT,
    132         D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
    133         &d3dpp, &g_D3DDevice))) return FALSE;
    134 
    135 
    136     // Initialize any objects we will be displaying.  
    137     if (!InitializeObjects()) return FALSE;
    138 
    139     return TRUE;
    140 }
    141 
    142 
    143 BOOL InitializeObjects()
    144 {
    145     unsigned long col = D3DCOLOR_XRGB(255, 255, 255);
    146 
    147     // Fill in our structure to draw an object.  
    148     // x, y, z, rhw, color.  
    149     stD3DVertex objData[] =
    150     {
    151         { 420.0f, 150.0f, 0.5f, 1.0f, col, },
    152         { 420.0f, 350.0f, 0.5f, 1.0f, col, },
    153         { 220.0f, 150.0f, 0.5f, 1.0f, col, },
    154         { 220.0f, 350.0f, 0.5f, 1.0f, col, },
    155     };
    156 
    157     // Create the vertex buffer.  
    158     if (FAILED(IDirect3DDevice9_CreateVertexBuffer(g_D3DDevice,sizeof(objData), 0,
    159         D3DFVF_VERTEX, D3DPOOL_DEFAULT, &g_VertexBuffer,
    160         NULL))) return FALSE;
    161 
    162     // Fill the vertex buffer.  
    163     void *ptr;
    164 
    165     if (FAILED(IDirect3DVertexBuffer9_Lock(g_VertexBuffer,0, sizeof(objData),
    166         (void**)&ptr, 0))) return FALSE;
    167 
    168     memcpy(ptr, objData, sizeof(objData));
    169 
    170 
    171     IDirect3DVertexBuffer9_Unlock(g_VertexBuffer);
    172 
    173     return TRUE;
    174 }
    175 
    176 
    177 void RenderScene()
    178 {
    179     // Clear the backbuffer.  
    180     IDirect3DDevice9_Clear(g_D3DDevice,0, NULL, D3DCLEAR_TARGET,
    181         D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    182 
    183     // Begin the scene.  Start rendering.  
    184    IDirect3DDevice9_BeginScene(g_D3DDevice);
    185 
    186     // Render object.  
    187    IDirect3DDevice9_SetStreamSource(g_D3DDevice,0, g_VertexBuffer, 0,
    188         sizeof(stD3DVertex));
    189    IDirect3DDevice9_SetFVF(g_D3DDevice,D3DFVF_VERTEX);
    190    IDirect3DDevice9_DrawPrimitive(g_D3DDevice,D3DPT_LINELIST, 0, 2);
    191 
    192     // End the scene.  Stop rendering.  
    193    IDirect3DDevice9_EndScene(g_D3DDevice);
    194 
    195     // Display the scene.  
    196     IDirect3DDevice9_Present(g_D3DDevice,NULL, NULL, NULL, NULL);
    197 }
    198 
    199 void Shutdown()
    200 {
    201     if (g_D3DDevice != NULL) IDirect3DDevice9_Release(g_D3DDevice);
    202     if (g_D3D != NULL) IDirect3D9_Release(g_D3D);
    203     if (g_VertexBuffer != NULL) IDirect3DVertexBuffer9_Release(g_VertexBuffer);
    204 
    205     g_D3DDevice = NULL;
    206     g_D3D = NULL;
    207     g_VertexBuffer = NULL;
    208 }

      这里只是画了两条平行的线段,作为一个例子:

      

    2.GDI+ C语言的例子

      参考来源:http://blog.csdn.net/zuishikonghuan/article/details/47251225

      直接使用gdiplus的头文件,编译会报错。虽然gdiplus.dll本身是用C语言写的,但是官方只提供了C++的友好的接口,函数比较少的话,可以自己做函数声明,避免编译错误。

      1 //tcc -run gdiplus.c
      2 #include <windows.h>
      3 #pragma comment(lib,"gdiplus")
      4 
      5 //GDI+Flat
      6 typedef struct _GdiplusStartupInput
      7 {
      8     unsigned int GdiplusVersion;
      9     unsigned int DebugEventCallback;
     10     BOOL SuppressBackgroundThread;
     11     BOOL SuppressExternalCodecs;
     12 }GdiplusStartupInput;
     13 
     14 
     15 int WINAPI GdiplusStartup(int* token, GdiplusStartupInput *input, int *output);
     16 void WINAPI GdiplusShutdown(int token);
     17 int WINAPI GdipCreateFromHDC(HDC hdc, int* graphics);
     18 int WINAPI GdipDeleteGraphics(int graphics);
     19 //画笔
     20 int WINAPI GdipCreatePen1(unsigned int argb_color, float width, int unit, int** pen);
     21 int WINAPI GdipDeletePen(int* pen);
     22 int WINAPI GdipDrawRectangle(int graphics, int* pen, float x, float y, float width, float height);
     23 int WINAPI GdipDrawLine(int graphics, int* pen, float x1, float y1, float x2, float y2);
     24 
     25 int token;
     26 int* pen;
     27 
     28 //*************************************************************
     29 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
     30 
     31 WNDCLASS wc;
     32 const TCHAR* AppName = TEXT("MyWindowClass1");
     33 HWND hwnd1;
     34 
     35 int APIENTRY WinMain(HINSTANCE hInstance,
     36     HINSTANCE hPrevInstance,
     37     LPTSTR    lpCmdLine,
     38     int       nCmdShow)
     39 {
     40     //GDI+开启
     41     GdiplusStartupInput StartupInput = { 0 };
     42     StartupInput.GdiplusVersion = 1;
     43     if (GdiplusStartup(&token, &StartupInput, NULL))MessageBox(0, TEXT("GdiPlus开启失败"), TEXT("错误"), MB_ICONERROR);
     44 
     45     //这里是在构建窗口类结构
     46     wc.style = CS_HREDRAW | CS_VREDRAW;
     47     wc.lpfnWndProc = WndProc;//窗口回调函数指针
     48     wc.cbClsExtra = 0;
     49     wc.cbWndExtra = 0;
     50     wc.hInstance = hInstance;//实例句柄
     51     wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
     52     wc.hCursor = LoadCursor(NULL, IDC_ARROW);//默认指针
     53     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//默认背景颜色
     54     wc.lpszMenuName = NULL;
     55     wc.lpszClassName = AppName;//窗口类名
     56 
     57                                //注册窗口类
     58     if (!RegisterClass(&wc))
     59     {
     60         MessageBox(NULL, TEXT("注册窗口类失败!"), TEXT("错误"), MB_ICONERROR);
     61         return 0;
     62     }
     63 
     64     //创建窗口
     65     int style = WS_OVERLAPPEDWINDOW;
     66     hwnd1 = CreateWindow(AppName, TEXT("窗口标题"), style, 50, 50, 500, 500, 0,NULL, hInstance, 0);
     67     if (hwnd1 == NULL)
     68     {
     69         MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);
     70         return 0;
     71     }
     72     //无边框窗口
     73     /*SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);*/
     74 
     75     //显示、更新窗口
     76     ShowWindow(hwnd1, nCmdShow);
     77     UpdateWindow(hwnd1);
     78 
     79     //消息循环
     80     MSG msg;
     81     while (GetMessage(&msg, NULL, 0, 0))
     82     {
     83         TranslateMessage(&msg);
     84         DispatchMessage(&msg);
     85     }
     86 
     87     //GDI+关闭
     88     GdiplusShutdown(token);//可以把这个写在消息循环后面,程序退出就销毁,或者在不需要GDI+时调用,比如GDI+窗口的WM_DESTROY消息里调用
     89     return msg.wParam;
     90 }
     91 
     92 LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     93 {
     94     HDC hdc;
     95     PAINTSTRUCT ps;
     96     switch (uMsg)
     97     {
     98 
     99         case WM_PAINT:
    100             
    101             
    102             hdc = BeginPaint(hwnd, &ps);
    103 
    104             int graphics;
    105             GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
    106             GdipCreatePen1(0x60FF2015, 1, 2, &pen);//创建画笔
    107             GdipDrawRectangle(graphics, pen, 20, 20, 120, 120);//画矩形
    108             GdipDrawLine(graphics, pen, 50, 60, 170, 340);//画直线
    109 
    110             GdipDeletePen(pen);//销毁画笔
    111             GdipDeleteGraphics(graphics);//销毁Graphics对象
    112 
    113             EndPaint(hwnd, &ps);
    114             return 0;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。
    115         case WM_CREATE:
    116             break;
    117         case WM_DESTROY://窗口已经销毁
    118             PostQuitMessage(0);//退出消息循环,结束应用程序
    119             return 0;
    120             break;
    121         case WM_LBUTTONDOWN://鼠标左键按下
    122                             //让无边框窗口能够拖动(在窗口客户区拖动)
    123             PostMessage(hwnd, WM_SYSCOMMAND, 61458, 0);
    124             break;
    125             /*case WM_MOUSEMOVE://鼠标移动
    126             int xPos, yPos;
    127             xPos = GET_X_LPARAM(lParam);//鼠标位置X坐标
    128             yPos = GET_Y_LPARAM(lParam);//鼠标位置Y坐标
    129             //不要用LOWORD和HIWORD获取坐标,因为坐标有可能是负的
    130             break;*/
    131         default:
    132             break;
    133     }
    134     return DefWindowProc(hwnd, uMsg, wParam, lParam);//其他消息交给系统处理
    135 }

      

  • 相关阅读:
    烂泥:高负载均衡学习haproxy之TCP应用
    烂泥:高负载均衡学习haproxy之关键词介绍
    sqlpuls基本命令
    Oracle开机自启动
    centos6.5安装oracle11g_2
    centos7安装图片界面
    centos7安装activemq
    centos7删除自带openjdk
    centos7安装nexus私服2.14
    mysql优化记录
  • 原文地址:https://www.cnblogs.com/wurui1994/p/6785036.html
Copyright © 2020-2023  润新知