View Full Version : Drawing in GAPI
Donone
05-03-2007, 11:22 AM
Having trouble drawing a line in GAPI.
I am confused by Surface and there seems to be no overview.
I have tried various combinations of... NewSurface, G_BeginScene/G_Update, G_Line etc but nothing shows with a newsurface or without.
Do I always have to have a surface made by me to then draw on like a canvas or is there a default surface anyway and a new one is only required for a different background?
Are the surface functions simply to allow drawing without using an external program to provide background bitmaps (because I note there is a SaveSurface)?
I would be grateful for a short sequence showing the precise requirements for me to draw a line in the blank (black) background provided by the game template in the gameapi tutorial. That should allow me to proceed.
Thank you.
quangdx
05-03-2007, 03:41 PM
#include "GameAPI.ppl"
func mainproc(hWnd$, Msg$, wParam$, lParam$)
case (Msg$)
WM_CLOSE:
ShutGameAPI(hWnd$);
WM_KEYDOWN:
KeysPressed$[wParam$] = 1;
WM_KEYUP:
KeysPressed$[wParam$] = 0;
end;
return (true);
end;
func GameProc(hWnd$, Msg$, wParam$, lParam$)
case (Msg$)
WM_PAINT:
G_Clear(0);
G_Line(Random(240),Random(320),Random(240),Random( 320),G_RGB(Random(255),Random(255),Random(255)));
WM_TIMER:
if(KeysPressed$[keys.vkA$])
PostMessage(hWnd$, WM_CLOSE, 0, 0);
end;
end;
return (true);
end;
func WinMain
h$ = newform({Drawing Lines}, {GAPIClass}, &mainproc);
ShowWindow(h$, SW_SHOW);
InitGameAPIEx(h$,&GameProc,240,320,false,20,50);
ShowFPS(true, G_RGB(255, 255, 255));
return (true);
end;
quangdx
05-03-2007, 03:44 PM
WM_PAINT gets processed 50 times per second, as called in InitGameAPIEx.
all drawing is done on to the default surface, buffer%, and at the end of WM_PAINT it draws it to the visible screen automatically.
you only need to use G_BeginScene/G_Update if you want to do any screen manipulation outside of WM_PAINT.
hope that helps.
kornalius
05-03-2007, 03:57 PM
What are you trying to do exactly? Are you trying to simply draw a line on the screen or a surface?
Surfaces are memory buffers that you can draw to using the G_SetRenderTarget(SurfaceHandle$). This will allow all gameapi functions to draw to that new surface.
Drawing to the screen is done within the WM_PAINT event of the GameProc.
If you want to manually draw on the screen, you need to use the following:
G_BeginScene;
G_Line(...);
Delay(5000); // To see your drawing
G_Update;
Even if you use G_BeginScene and G_Update, the GameAPI will automatically erase your drawing. Every FPS it calls the WM_PAINT event to allow for custom drawing.
For example, in the Simple2.ppl demo, the GameProc contains the text output in the WM_PAINT.
func GameProc(hWnd$, Msg$, wParam$, lParam$)
case (Msg$)
WM_PAINT:
// Clear screen first
G_Clear(0);
// Render all loaded sprites on screen.
RenderSprites;
// Output some text.
g_textout(NULL, "Click the planes!", DVT_CENTER, 0, 2, g_rgb(255, 255, 255));
g_textout(NULL, "Arrows to move map origins", DVT_CENTER, 0, 14, g_rgb(255, 255, 255));
g_textout(NULL, "A to exit", DVT_CENTER, 0, 26, g_rgb(255, 255, 255));
g_textout(NULL, "B to change speed", DVT_CENTER, 0, 38, g_rgb(255, 255, 255));
end;
return (true);
end;
You need to clear the screen, render all the sprites then do your custom drawing. You only render sprites if you use them in your program.
kornalius
05-03-2007, 03:58 PM
Wow, Quandx was pretty fast on this one, thank you.
Donone
05-03-2007, 04:24 PM
Well thank you both very much for your, as always, quick and friendly response. Between you the question is answered beautifully and the problem solved in that it now works.
One small point, if I want to draw say, a grid, as background, a pre-prepared bmp will consume memory for the whole area of pixels. If I draw the grid with straight lines as you have shown, though initially slower (presumably) it surely will consume less memory during the rest of the game. Is this true or false?
Is there a recommendation for a good program to produce such a bitmap if that is the best way?
[Edit] BTW the reason I had a problem was I did not use WM_PAINT. I recall reading somewhere that it (one of the commands) should NOT be done in WM_PAINT (so got confused).
PointOfLight
05-03-2007, 04:44 PM
You're right.* The manual update functions (G_UPDATE and G_UPDATERECT) should not be called within a call to WM_PAINT.* The reason for this is because they will in turn call WM_PAINT, and I think you can see where this is going :)
As for the question of a grid, there's really no reason you'd want to use a bitmap to draw your grid.* Line drawing should be fast enough, and if you use a bitmap for that purpose it's just additional memory that you're needlessly consuming.* In fact, there's actually a function called DrawGrid that will render a grid for you.* The call is:
DrawGrid(WidthOfCell$, HeightOfCell$, ColorOfLine$, Isometric$);
Just set Isometric$ to false to draw a normal top down grid.
Donone
05-03-2007, 04:59 PM
Thank you PointOfLight, I am happy with that. The DrawGrid function does not appear to be documented (I searched but did not find). If there are functions that have not yet found their way to the help file (I know it is impossible to keep up with Kornalius), how does one discover their existence?
[Edit] I used
//Draw grid 20x20x12
for(i$,0,20)
G_Line(i$*12,0,i$*12,240,G_RGB(255,255,255)); G_Line(0,i$*12,240,i$*12,G_RGB(255,255,255));
end;
PointOfLight
05-03-2007, 06:23 PM
You're absolutely right.* I am really trying hard to get this help file up to date.* In the case of DrawGrid, however, I think it must have slipped Alain's mind (or it's a really new function), because I didn't know about it until just a couple of weeks ago myself.* At least, I don't remember hearing about it...
As for grid rendering code, I'm sure the function DrawGrid actually does something similar behind the scenes to what you posted.
Donone
05-03-2007, 06:27 PM
Thanks PointOfLight.
The Drawgrid function is a little limited in that it fills the screen area, whereas mine does only the portion I require. I suppose a couple of extra X,Y parameters added to Drawgrid would permit this also.
PointOfLight
05-04-2007, 12:48 AM
Alain, Donone has a good point.* What would be the possability of putting a couple extra parameters in the DrawGrid function that would either (1) let you specify a X border and Y border around the grid, or (2) allow you to specify the Left,Top and Right,Bottom coordinates of the area you want grided?* I'm not suggesting to allow for both, but just one or the other.
Donone
05-04-2007, 08:53 AM
If this goes ahead, please note that if cell width/height are pre-calculated to fit the screen exactly, DrawGrid does not draw the last line in each direction
Don't think me presumptious for the following.
I have produced the following routine... to overcome this. It would be great if there is a better way.
//Draws a grid of defined size and position. First & last lines visible
//Cell width/height; XY source; XY num of cells
Proc dsDrawGrid(CellW$,CellH$,Xs$,Ys$,CellsX$,CellsY$,C olour$)
G_Line(Xs$,Ys$,Xs$,Ys$+CellsY$*CellH$,Colour$);
for(i$,1,CellsX$)
G_Line(Xs$+i$*CellW$-1,Ys$,Xs$+i$*CellW$-1,Ys$+CellsY$*CellH$-1,Colour$);
end;
G_Line(Xs$,Ys$,Xs$+CellsX$*CellW$,Ys$,Colour$);
for(i$,1,CellsY$)
G_Line(Xs$,Ys$+i$*CellH$-1,Xs$+CellsX$*CellW$-1,Ys$+i$*CellH$-1,Colour$);
end;
end;
also note that with both routines if the calculation is not done manually correctly then part cells show. This may or may not be desirable.
vBulletin® v3.8.4, Copyright ©2000-2012, Jelsoft Enterprises Ltd.