0.前言

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

1.Direct3D C语言的例子

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

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

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

 #include<d3d9.h>  

 #pragma comment(lib, "d3d9.lib")   

 #define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Drawing Lines" // Function Prototypes...
BOOL InitializeD3D(HWND hWnd, BOOL fullscreen);
BOOL InitializeObjects();
void RenderScene();
void Shutdown(); // Direct3D object and device.
LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL; // Vertex buffer to hold the geometry.
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL; // A structure for our custom vertex type
typedef struct
{
float x, y, z, rhw;
unsigned long color;
}stD3DVertex; // Our custom FVF, which describes our custom vertex structure.
#define D3DFVF_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage();
return ;
break; case WM_KEYUP:
if (wp == VK_ESCAPE) PostQuitMessage();
break;
} return DefWindowProc(hWnd, msg, wp, lp);
} int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst,
LPSTR cmdLine, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc,
, , GetModuleHandle(NULL), NULL, LoadCursor(NULL,IDC_ARROW),
NULL, NULL, WINDOW_CLASS, NULL };
RegisterClassEx(&wc); // Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME,
WS_OVERLAPPEDWINDOW, , ,
, , GetDesktopWindow(), NULL,
wc.hInstance, NULL); // Initialize Direct3D
if (InitializeD3D(hWnd, FALSE))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd); // Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
} // Release any and all resources.
Shutdown(); // Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return ;
} BOOL InitializeD3D(HWND hWnd, BOOL fullscreen)
{
D3DDISPLAYMODE displayMode; // Create the D3D object.
g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
if (g_D3D == NULL) return FALSE; // Get the desktop display mode.
if (FAILED(IDirect3D9_GetAdapterDisplayMode(g_D3D,D3DADAPTER_DEFAULT,
&displayMode))) return FALSE; // Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp)); if (fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = ;
d3dpp.BackBufferHeight = ;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format; // Create the D3DDevice
if (FAILED(IDirect3D9_CreateDevice(g_D3D,D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &g_D3DDevice))) return FALSE; // Initialize any objects we will be displaying.
if (!InitializeObjects()) return FALSE; return TRUE;
} BOOL InitializeObjects()
{
unsigned long col = D3DCOLOR_XRGB(, , ); // Fill in our structure to draw an object.
// x, y, z, rhw, color.
stD3DVertex objData[] =
{
{ 420.0f, 150.0f, 0.5f, 1.0f, col, },
{ 420.0f, 350.0f, 0.5f, 1.0f, col, },
{ 220.0f, 150.0f, 0.5f, 1.0f, col, },
{ 220.0f, 350.0f, 0.5f, 1.0f, col, },
}; // Create the vertex buffer.
if (FAILED(IDirect3DDevice9_CreateVertexBuffer(g_D3DDevice,sizeof(objData), ,
D3DFVF_VERTEX, D3DPOOL_DEFAULT, &g_VertexBuffer,
NULL))) return FALSE; // Fill the vertex buffer.
void *ptr; if (FAILED(IDirect3DVertexBuffer9_Lock(g_VertexBuffer,, sizeof(objData),
(void**)&ptr, ))) return FALSE; memcpy(ptr, objData, sizeof(objData)); IDirect3DVertexBuffer9_Unlock(g_VertexBuffer); return TRUE;
} void RenderScene()
{
// Clear the backbuffer.
IDirect3DDevice9_Clear(g_D3DDevice,, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(, , ), 1.0f, ); // Begin the scene. Start rendering.
IDirect3DDevice9_BeginScene(g_D3DDevice); // Render object.
IDirect3DDevice9_SetStreamSource(g_D3DDevice,, g_VertexBuffer, ,
sizeof(stD3DVertex));
IDirect3DDevice9_SetFVF(g_D3DDevice,D3DFVF_VERTEX);
IDirect3DDevice9_DrawPrimitive(g_D3DDevice,D3DPT_LINELIST, , ); // End the scene. Stop rendering.
IDirect3DDevice9_EndScene(g_D3DDevice); // Display the scene.
IDirect3DDevice9_Present(g_D3DDevice,NULL, NULL, NULL, NULL);
} void Shutdown()
{
if (g_D3DDevice != NULL) IDirect3DDevice9_Release(g_D3DDevice);
if (g_D3D != NULL) IDirect3D9_Release(g_D3D);
if (g_VertexBuffer != NULL) IDirect3DVertexBuffer9_Release(g_VertexBuffer); g_D3DDevice = NULL;
g_D3D = NULL;
g_VertexBuffer = NULL;
}

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

  

2.GDI+ C语言的例子

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

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

 //tcc -run gdiplus.c
#include <windows.h>
#pragma comment(lib,"gdiplus") //GDI+Flat
typedef struct _GdiplusStartupInput
{
unsigned int GdiplusVersion;
unsigned int DebugEventCallback;
BOOL SuppressBackgroundThread;
BOOL SuppressExternalCodecs;
}GdiplusStartupInput; int WINAPI GdiplusStartup(int* token, GdiplusStartupInput *input, int *output);
void WINAPI GdiplusShutdown(int token);
int WINAPI GdipCreateFromHDC(HDC hdc, int* graphics);
int WINAPI GdipDeleteGraphics(int graphics);
//画笔
int WINAPI GdipCreatePen1(unsigned int argb_color, float width, int unit, int** pen);
int WINAPI GdipDeletePen(int* pen);
int WINAPI GdipDrawRectangle(int graphics, int* pen, float x, float y, float width, float height);
int WINAPI GdipDrawLine(int graphics, int* pen, float x1, float y1, float x2, float y2); int token;
int* pen; //*************************************************************
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); WNDCLASS wc;
const TCHAR* AppName = TEXT("MyWindowClass1");
HWND hwnd1; int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
//GDI+开启
GdiplusStartupInput StartupInput = { };
StartupInput.GdiplusVersion = ;
if (GdiplusStartup(&token, &StartupInput, NULL))MessageBox(, TEXT("GdiPlus开启失败"), TEXT("错误"), MB_ICONERROR); //这里是在构建窗口类结构
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;//窗口回调函数指针
wc.cbClsExtra = ;
wc.cbWndExtra = ;
wc.hInstance = hInstance;//实例句柄
wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//默认指针
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//默认背景颜色
wc.lpszMenuName = NULL;
wc.lpszClassName = AppName;//窗口类名 //注册窗口类
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("注册窗口类失败!"), TEXT("错误"), MB_ICONERROR);
return ;
} //创建窗口
int style = WS_OVERLAPPEDWINDOW;
hwnd1 = CreateWindow(AppName, TEXT("窗口标题"), style, , , , , ,NULL, hInstance, );
if (hwnd1 == NULL)
{
MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);
return ;
}
//无边框窗口
/*SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);*/ //显示、更新窗口
ShowWindow(hwnd1, nCmdShow);
UpdateWindow(hwnd1); //消息循环
MSG msg;
while (GetMessage(&msg, NULL, , ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} //GDI+关闭
GdiplusShutdown(token);//可以把这个写在消息循环后面,程序退出就销毁,或者在不需要GDI+时调用,比如GDI+窗口的WM_DESTROY消息里调用
return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (uMsg)
{ case WM_PAINT: hdc = BeginPaint(hwnd, &ps); int graphics;
GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
GdipCreatePen1(0x60FF2015, , , &pen);//创建画笔
GdipDrawRectangle(graphics, pen, , , , );//画矩形
GdipDrawLine(graphics, pen, , , , );//画直线 GdipDeletePen(pen);//销毁画笔
GdipDeleteGraphics(graphics);//销毁Graphics对象 EndPaint(hwnd, &ps);
return ;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。
case WM_CREATE:
break;
case WM_DESTROY://窗口已经销毁
PostQuitMessage();//退出消息循环,结束应用程序
return ;
break;
case WM_LBUTTONDOWN://鼠标左键按下
//让无边框窗口能够拖动(在窗口客户区拖动)
PostMessage(hwnd, WM_SYSCOMMAND, , );
break;
/*case WM_MOUSEMOVE://鼠标移动
int xPos, yPos;
xPos = GET_X_LPARAM(lParam);//鼠标位置X坐标
yPos = GET_Y_LPARAM(lParam);//鼠标位置Y坐标
//不要用LOWORD和HIWORD获取坐标,因为坐标有可能是负的
break;*/
default:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);//其他消息交给系统处理
}

  

C语言集锦(三)Direct3D和GDI+的例子的更多相关文章

  1. Swift语言指南(三)--语言基础之整数和浮点数

    原文:Swift语言指南(三)--语言基础之整数和浮点数 整数 整数指没有小数的整数,如42,-23.整数可以是有符号的(正数,零,负数),也可以是无符号的(正数,零). Swift提供了8,16,3 ...

  2. ASP.NET MVC:多语言的三种技术处理策略

    ASP.NET MVC:多语言的三种技术处理策略 背景 本文介绍了多语言的三种技术处理策略,每种策略对应一种场景,这三种场景是: 多语言资源信息只被.NET使用. 多语言资源信息只被Javascrip ...

  3. 基于C#程序设计语言的三种组合算法

    目录 基于C#程序设计语言的三种组合算法 1. 总体思路 1.1 前言 1.2 算法思路 1.3 算法需要注意的点 2. 三种组合算法 2.1 普通组合算法 2.2 与自身进行组合的组合算法 2.3 ...

  4. UWP 多语言的三个概念

    首先了解一下 RFC4646 和 BCP-47 是什么东西: RFC4646 The name is a combination of an ISO 639 two-letter lowercase ...

  5. 第二百五十九节,Tornado框架-模板语言的三种方式

    Tornado框架-模板语言的三种方式 模板语言就是可以在html页面,接收逻辑处理的self.render()方法传输的变量,将数据渲染到对应的地方 一.接收值渲染 {{...}}接收self.re ...

  6. DirectX11笔记(三)--Direct3D初始化代码

    原文:DirectX11笔记(三)--Direct3D初始化代码 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737/article ...

  7. DirectX11笔记(三)--Direct3D初始化2

    原文:DirectX11笔记(三)--Direct3D初始化2 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737/article/ ...

  8. 第三章SignalR在线聊天例子

    第三章SignalR在线聊天例子 本教程展示了如何使用SignalR2.0构建一个基于浏览器的聊天室程序.你将把SignalR库添加到一个空的Asp.Net Web应用程序中,创建用于发送消息到客户端 ...

  9. 深入研究C语言 第三篇

    本篇研究TC2.0下其他几个工具.同时看看TC由源代码到exe程序的过程. 1. 用TCC将下面的程序编为.obj文件 我们知道,TCC在默认的编译连接一个C语言的源程序a.c的时候分为以下两步: ( ...

随机推荐

  1. Python学习笔记(三):文件和集合操作

    python string与list互转 因为python的read和write方法的操作对象都是string.而操作二进制的时候会把string转换成list进行解析,解析后重新写入文件的时候,还得 ...

  2. 命令java 找不到或无法加载主类

    这个是由于用了package导致cmd下找不到class文件产生的错误,解决方案: 方法1.删除HelloWord.java源程序中的第一行package demo1:然后在cmd下正常使用javac ...

  3. 16,Python网络爬虫之Scrapy框架(CrawlSpider)

    今日概要 CrawlSpider简介 CrawlSpider使用 基于CrawlSpider爬虫文件的创建 链接提取器 规则解析器 引入 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话, ...

  4. 11,scrapy框架持久化存储

    今日总结 基于终端指令的持久化存储 基于管道的持久化存储 今日详情 1.基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的 ...

  5. 10,Scrapy简单入门及实例讲解

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...

  6. CodeForces 781E Andryusha and Nervous Barriers 线段树 扫描线

    题意: 有一个\(h \times w\)的矩形,其中有\(n\)个水平的障碍.从上往下扔一个小球,遇到障碍后会分裂成两个,分别从障碍的两边继续往下落. 如果从太高的地方落下来,障碍会消失. 问从每一 ...

  7. 常用的一些api

    发送手机短信 // 发送短信给安全号码 SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage(phon ...

  8. “帮你APP”团队冲刺5

    1.整个项目预期的任务量 (任务量 = 所有工作的预期时间)和 目前已经花的时间 (所有记录的 ‘已经花费的时间’),还剩余的时间(所有工作的 ‘剩余时间’) : 所有工作的预期时间:88h 目前已经 ...

  9. lambda表达式与函数接口的关系以及使用案例

    lambda表达式与函数式接口是结合使用的. 函数式接口:接口中只有一个抽象方法的接口,其中可以包括default修饰,static 修饰的实例方法.函数式接口可以在接口上添加@FuncationIn ...

  10. 测试环境docker化—容器集群编排实践

    本文来自网易云社区 作者:孙婷婷 背景 在前文<测试环境docker化-基于ndp部署模式的docker基础镜像制作>中已经详述了docker镜像制作及模块部署的过程,按照上述做法已可以搭 ...