[很麻烦]opengl,step 0
//test.d
//save as utf 16 LE
//dmd test.d -L/exet:nt/su:windows:4.0
import win32.windows;
import std.c.string;
import opengl.gl;
pragma(lib,"win32.lib");
pragma(lib,"gdi32.lib");
pragma(lib,"opengl32.lib");
pragma(lib,"glu32.lib");
/*Make the class name into a global variable*/
const wchar* szClassName = "OpenGL";
const wchar* szAppName = "OpenGL测试";
extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleDtor();
extern (C) void _moduleUnitTests();
extern (Windows) int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
int result;
gc_init(); // initialize garbage collector
_minit(); // initialize module constructor table
try
{
_moduleCtor(); // call module constructors
_moduleUnitTests(); // run unit tests (optional)
result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
_moduleDtor(); // call module destructors
}
catch (Object o) // catch any uncaught exceptions
{
MessageBoxA(null, cast(char *)o.toString(), "Error",
MB_OK | MB_ICONEXCLAMATION);
result = 0; // failed
}
gc_term(); // run finalizers; terminate garbage collector
return result;
}
int myWinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
{
HWND hWnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEXW wincl; /* Data structure for the windowclass */
HDC hDC;
HGLRC hRC;
bool bQuit = false;
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = &WindowProcedure; /* This function is called by windows */
wincl.style = CS_OWNDC; /* Catch double-clicks */
wincl.cbSize = WNDCLASSEXW.sizeof;
/* Use default icon and mouse-pointer */
wincl.hIcon = null;
wincl.hIconSm = null;
wincl.hCursor = null;
wincl.lpszMenuName = null; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = cast(HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassExW (&wincl))
return 0;
/* The class is registered, let's create the program*/
hWnd = CreateWindowExW (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
szAppName, /* Title Text */
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
250, /* The programs width */
250, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
null, /* No menu */
hThisInstance, /* Program Instance handler */
null /* No Window Creation data */
);
/* enable OpenGL for the window */
EnableOpenGL (hWnd, &hDC, &hRC);
/* Make the window visible on the screen */
ShowWindow (hWnd, nFunsterStil);
while (!bQuit)
{
if (PeekMessage(&messages, null, 0, 0, PM_REMOVE))
{
if (messages.message == WM_QUIT)
{
bQuit = true;
}
else
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessageW(&messages);
}
}
else
{
draw(hDC);
}
}
/* shutdown OpenGL */
DisableOpenGL (hWnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow (hWnd);
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/*This function is called by the Windows function DispatchMessage()*/
extern(Windows) LRESULT WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProcW (hwnd, message, wParam, lParam);
}
return 0;
}
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC (hWnd);
/* set the pixel format for the DC */
memset(&pfd, pfd.sizeof,1);
pfd.nSize = pfd.sizeof;
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 = 0;
//pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat (*hDC, &pfd);
SetPixelFormat (*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
}
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (null,null);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}
void draw(HDC hDC)
{
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix ();
glRotatef (0.0f, 0.0f, 0.0f, 1.0f);
glBegin (GL_TRIANGLES);
glColor3f (1.0f, 0.0f, 0.0f);
glVertex2f (0.0f, 1.0f);
glColor3f (0.0f, 1.0f, 0.0f);
glVertex2f (0.87f, -0.5f);
glColor3f (0.0f, 0.0f, 1.0f);
glVertex2f (-0.87f, -0.5f);
glEnd ();
glPopMatrix ();
SwapBuffers (hDC);
Sleep (1);
}
=0= 用D的……上次看到这个去下载了GDC来……
BUT就忘了编译……为什么不能够用C写……这样可以省力啊…… c的话,对于我个人来说有三个理由吧。
1.c的基本数据类看着别扭,unsign char ...不如直接ubyte多好。还有c不是强类型。
2.c里面没有委托可用。
3.c多线程的时候不是一般的麻烦。
而现在D的麻烦只是在库上,一旦越过了,后面就没有太麻烦的问题了。必竟D是号称能和ruby比开发效率,和c++比运行效率的新语言嘛。虽然我对此没有任何体会。
ps.如果是用c,我就直接去用irrlicht了,绝对不会多看dx&opengl一眼。 不解ING……
主要是用C可能比较适合偶看而已……,D今天看FX的那段闭包完全看不懂
如果光是函数里面嵌套函数也就罢了,什么delegate(int)……
之后又一堆东东,所以结果容易变成语法课了啊…… int delegate(int) ptr就是int (*ptr)(int)啊...这样容易明白些么?
在D有完全闭包前,它的delegate/function pointer很难说比C/C++的有多少改良...本来就是一回事。
不过在有完全闭包后,D里面的delegate就比C的要有更强的能力,在作为参数传递的时候也会传递更多信息。
……不过我觉得shawind应该没用到什么需要这种能力的地方……C里的函数指针估计是完全够用 是的,每个人的习惯不一样,喜爱的语言也不一样。
delegate(int)就是申明了一个委托类型。在c#,d这类语言中,用委托比在c中只能使用函数指针要安全很多。
居说c++的boost库里也实现了多线程和(委托?)之类的东西。但是上次尝试编译krkr2的时候,boost在我的心目里留下了很不友好的印像,所以一直都没有怎么接触。 因为我是用完全面向对像的思路来考虑实现引擎的。委托带有它周围的环境信息,在有很多类的时候,比较不容易指错地方。当然高手用c也能完成这种任务,但我只是菜鸟来着,完全不会Debug...... 尝试编译krkr2么?(苦笑
那里面boost应该不是带来什么麻烦,如果你用对了版本的话。麻烦是麻烦在另外的一些依赖上吧。我极其厌恶的一些东西,例如VCL什么的……也有一些库被稍微改过?这个得问问米粒看他知不知道。
C不是强类型……==,什么是强类型?
另外D里的delegate比C的函数指针安全么?hmm...没看出来。
Delegates are an aggregate of two pieces of data: an object reference and a function pointer.
===========================我是分隔线============================
委托带有它周围的环境信息,在有很多类的时候,比较不容易指错地方。
这个值得商榷。能给出一个例子,来说明一下怎样会指错,而D里的delegate如何协助不指错吗? 我是卡在了boost上,后面就没有耐心去做了。
c或许也算强类型的一种,可是在D中声明了struct,class后,就可以把它当作新的数据类型来使用,还有D中用typedef int i; 把i当作一个全新的类型,c中的类型显然是没有这么“强”的。
委托的例子的话,就比如说,有两个类,一个是人物A,一个是人物B,都有一个类似的方法,move(int x, int y); 如果我要区别使用这两方法,用委托应该比用函数指针好吧。我是这么想的,还没有做过这样的实验。 根据米粒的指导,用Boost 1.30基本上没出什么问题……不过始终我还是编译不出krkr2的内核的。也罢。
Alright,那来看看:
class A {
bool move(int x, int y) {
return true;
}
}
class B {
bool move(int x, int y) {
return false;
}
}
bool delegate(int, int) dg;
void main(char[][] args) {
A a = new A;
B b = new B;
dg = &a.move;
printf("%d\\n", dg(1, 2));
dg = &b.move;
printf("%d\\n", dg(3, 4));
}
并没有区别A与B。事实上函数指针就该这么用。对一个函数指针或者委托,重要的只是参数个数和类型,以及返回类型;至于所指向的成员方法属于什么类型的类,不是函数指针需要关心的。