Ed Trice wrote: That sounds like a good solution. Do you have a screenshot of your program? I searched lazily but couldn't find anything but trees
Yeah,
http://talkchess.com/forum/viewtopic.ph ... 05&t=62588
though I uploaded new versions to that archive since then and there are now a bunch more options. (Coordinates next to the board, move list, some default timecontrols, black background option, uses about 80MB less RAM, better proportioned pieces etc.)
Some minimal WinAPI and OpenGL code to do this. I use (Free)Pascal but the API and OpenGL calls should be close to identical in any C variant.
Pretty sure it won't get any Windows or OpenGL expert seal of approval but it seems to work.
It creates a dynamic chunk of memory at pointer screen^ that is spixx wide and spixy high starting in the upper left corner. Starting at 0 so you can draw to spixx-1 and spixy-1.
Here a pixel is 4 bytes/32 bit but OpenGL also lets you choose different pixel types such as floating point etc.
Some global variables.:
Code: Select all
Type screent=array[0..68000000] of longword; {Ready for ultra mega wide 8K..}
Var
screen:^screent;
WindowClass:WndClass;
hWindow:HWnd;
wMessage:Msg;
scrnrect:Rect;
contextw:HDC;
contextgl:HGLRC;
spixx,spixy:longword;
stopit:byte;
Here I call resize from the startup procedure as well as from the Window procedure so it's separate.
Code: Select all
procedure resize;
begin
freemem(screen,spixx*spixy*4);
GetClientRect(hWindow,scrnrect);
spixx:=scrnrect.right-scrnrect.left;
spixy:=scrnrect.bottom-scrnrect.top;
getmem(screen,spixx*spixy*4);
glViewport(0,0,spixx,spixy);
glMatrixMode(GL_PROJECTION);glLoadIdentity;
glOrtho(0,spixx-1,spixy-1,0,-1,1);
glMatrixMode(GL_MODELVIEW);glLoadIdentity;
glRasterPos2s(0,0);
end;
The Window procedure.
Code: Select all
function WindowProc(Window:HWnd;AMessage:UINT;WParam:WPARAM;
LParam:LPARAM):LRESULT;stdcall;export;
begin
if AMessage=wm_Destroy then begin PostQuitMessage(0);stopit:=1;end;
if (AMessage=wm_Sizing)or(AMessage=wm_Size)or(AMessage=wm_Move) then
resize;
WindowProc:=DefWindowProc(Window,AMessage,WParam,LParam);
end;
And message pump.
Code: Select all
procedure windowsmessagepump;
begin
while PeekMessage(@wMessage,0,0,0,PM_REMOVE) do begin
TranslateMessage(wMessage);DispatchMessage(wMessage);end;
end;
Start. Create a 1024 by 768 window and the OpenGL thing ontop. At the end before doing anything it calls resize then it's ready for action.
Code: Select all
procedure startup;
var PixelFormat:GLuint;
h_Instance:HINST;
pfd:TPIXELFORMATDESCRIPTOR;
begin
stopit:=0;spixx:=1024;spixy:=768;
getmem(screen,spixx*spixy*4);
WindowClass.Style:=cs_hRedraw or cs_vRedraw;
WindowClass.lpfnWndProc:=WndProc(@WindowProc);
WindowClass.cbClsExtra:=0;
WindowClass.cbWndExtra:=0;
WindowClass.hInstance:=system.MainInstance;
WindowClass.hIcon:=LoadIcon(0,idi_application);
WindowClass.hCursor:=LoadCursor(0,idc_arrow);
WindowClass.hbrBackground:=GetStockObject(BLACK_BRUSH);
WindowClass.lpszMenuName:=nil;
WindowClass.lpszClassName:='Test';
if RegisterClass(WindowClass)=0 then exit;
hWindow:=CreateWindow('Test','Test',ws_OverlappedWindow,cw_UseDefault,
cw_UseDefault,spixx,spixy,0,0,system.MainInstance,nil);
if hWindow<>0 then begin
ShowWindow(hWindow,CmdShow);ShowWindow(hWindow,SW_SHOW);
UpdateWindow(hWindow);end else exit;
contextw:=GetDC(hWindow);
pfd.nSize:=SizeOf(TPIXELFORMATDESCRIPTOR);pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL;
pfd.iPixelType:=PFD_TYPE_RGBA;
pfd.cColorBits:=32;pfd.cRedBits:=0;
pfd.cRedShift:=0;pfd.cGreenBits:=0;
pfd.cGreenShift:=0;pfd.cBlueBits:=0;
pfd.cBlueShift:=0;pfd.cAlphaBits:=0;
pfd.cAlphaShift:=0;pfd.cAccumBits:=0;
pfd.cAccumRedBits:=0;pfd.cAccumGreenBits:=0;
pfd.cAccumBlueBits:=0;pfd.cAccumAlphaBits:=0;
pfd.cDepthBits:=16;pfd.cStencilBits:=0;
pfd.cAuxBuffers:=0;pfd.iLayerType:=PFD_MAIN_PLANE;
pfd.bReserved:=0;pfd.dwLayerMask:=0;
pfd.dwVisibleMask:=0;pfd.dwDamageMask:=0;
PixelFormat:=ChoosePixelFormat(contextw,@pfd);
SetPixelFormat(contextw,PixelFormat,@pfd);
contextgl:=wglCreateContext(contextw);
wglMakeCurrent(contextw,contextgl);
glClearColor(0,0,0,1);glShadeModel(GL_FLAT);
glDepthFunc(GL_ALWAYS);glDisable(GL_DEPTH_TEST);
glPointSize(1);glLineWidth(1);glpixelzoom(1,-1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);glLoadIdentity;
resize;
end;
procedure stoppen;
begin
freemem(screen,spixx*spixy*4);
wglMakeCurrent(contextw,0);wglDeleteContext(contextgl);
ReleaseDC(hWindow,contextw);DestroyWindow(hWindow);
end;
Draw the screen buffer to screen and clear it in this case with black. (0)
Code: Select all
procedure drawscrn;
begin
gldrawpixels(spixx,spixy,GL_RGBA,GL_UNSIGNED_BYTE,@screen^);
glflush;
filldword(screen^,spixx*spixy,0);
end;
And a main part.
Code: Select all
begin
startup;
repeat
{do and draw something..}
drawscrn;
Windowsmessagepump;
until stopit=1;
stoppen;
end.