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. 将Excel文件转为csv文件的python脚本

    #!/usr/bin/env python __author__ = "lrtao2010" ''' Excel文件转csv文件脚本 需要将该脚本直接放到要转换的Excel文件同级 ...

  2. centos6.9系统安装

    1. 选择系统及下载 CentOS 5.x CentOS 6.x 50% 6.9 CentOS 7.x 50% 7.2 centos 6.9 centos 7. 最新版 https://wiki.ce ...

  3. 51nod 1202 不同子序列个数(计数DP)

    1202 子序列个数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40      子序列的定义:对于一个序列a=a[1],a[2],......a[n].则非空序列a'=a[p1],a ...

  4. The Moving Points - HDU - 4717 (模拟退火)

    题意 二维空间中有\(n\)个运动的点,每个点有一个初始坐标和速度向量.求出一个时间\(T\),使得此时任意两点之间的最大距离最小.输出\(T\)和最大距离. 题解 模拟退火. 这个题告诉了我,初始步 ...

  5. python双向链表的疑问(Question)

    Table of Contents 1. 问题 问题 在看 collections.OrderedDict 的源码时,对于它如何构造有序的结构这一部分不是很理解,代码如下: class Ordered ...

  6. opencv使用日记之一:平台搭建Mat类以及图像的读取修改

    平台搭建就摸了一整天时间,真的是...不说了,最后我选择的是 opencv3.0(2015/06/04)  + win7 + vs2012   注意opencv的版本不同导入的库文件是不一样的,所以请 ...

  7. Java多线程-yield(),sleep()以及wait()的区别

    从操作系统的角度讲,os会维护一个ready queue(就绪的线程队列).并且在某一时刻cpu只为ready queue中位于队列头部的线程服务.但是当前正在被服务的线程可能觉得cpu的服务质量不够 ...

  8. django 自定义过滤器中的坑.

    今天在创建自定义过滤器的时候,设置已正常.但是在运行后报: 'filter' is not a valid tag library: Template library filter not found ...

  9. uoj206 [APIO2016]最大差分

    ref #include "gap.h" #include <iostream> #include <cstdio> using namespace std ...

  10. 如何将int转换为datetime?

    $timestamp = 1210003200; $datetime = date('Y-m-d H:i:s', $timestamp); echo "该时间戳代表的时间:", $ ...