[Previous] [Next] [Up] [Home] S3D Pascal Bindings

Quickstart

The official documentation is very sparse, but as a quickstart here is what you need to do:

And that is about it. Beyond that it is mainly setting state and drawing triangles. In terms of memory management, S3D relies on DirectDraw to do the video memory allocation/etc so in general the process is allocating a DirectDraw surface and filling a TS3DTK_SURFACE variable with info about it. The S3D API itself does not actually know about DirectDraw, it is only used indirectly to obtain the memory offsets and to perform surface flipping. In theory it might be possible to allocate a big surface and chop it to smaller pieces with multiple TS3DTK_SURFACEs.

The only tricky bit is calculating the video memory offset. This is only shown in the example that comes with the S3D SDK, but what you need to do is to call the Lock method with the DDLOCK_SURFACEMEMORYPTR and DDLOCK_WAIT flags (the wait flag isn't strictly necessary but the lock can actually fail if the GPU was using the surface and i had that happen to me a few times, so it doesn't hurt). Then cast the lpSurface to a ULONG and call S3DTK_LinearToPhysical with the upper 20 bits (so that the lower 12 bits remain as-is) and then subtract from the framebuffer's base. A utility function can be something like:

function LinearToPhysical(Linear: ULONG): ULONG;
begin
  Result:=S3DTK_LinearToPhysical(Linear and $FFFFF000) +
                                (Linear and $FFF);
end;

and used like (Surface is a IDirectDrawSurface, ddsd is a TDDSurfaceDesc variable and s3ds is a TS3DTK_SURFACE variable):

ddsd.dwSize:=SizeOf(ddsd);
if Failed(Surface.Lock(nil, ddsd, DDLOCK_SURFACEMEMORYPTR or
                                  DDLOCK_WAIT, 0)) then
  Halt; // ...or a more graceful way to handle the error :-P
s3ds.sfOffset:=LinearToPhysical(ULONG(ddsd.lpSurface)) - 
               FramebufferPhysical;
Surface.Unlock(nil);

The FramebufferPhysical variable is a global you obtain after the library and renderer have been created (S3D is a pointer to TS3DTK_FUNCTION_LIST and FramebufferLinear is a PByte - though it can be any pointer type really):

S3D^.S3DTK_GetState(S3D, 
                    S3DTK_VIDEOMEMORYADDRESS,
                    ULONG(@LinearAddress));
FramebufferPhysical:=LinearToPhysical(ULONG(LinearAddress));

See S3DTK_GetState for information about the states you can query.


[Previous] [Next] [Up] [Home] S3D Pascal Bindings