subsystems and videomodes implemented (except SDL2); smaller fixes too

This commit is contained in:
aap 2020-04-15 09:47:43 +02:00
parent 5685e6109e
commit 2d345499d2
34 changed files with 778 additions and 229 deletions

View File

@ -217,10 +217,10 @@ main(int argc, char *argv[])
if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0;
engineStartParams.width = sk::globals.width;
engineStartParams.height = sk::globals.height;
engineStartParams.windowtitle = sk::globals.windowtitle;
engineStartParams.window = &window;
engineOpenParams.width = sk::globals.width;
engineOpenParams.height = sk::globals.height;
engineOpenParams.windowtitle = sk::globals.windowtitle;
engineOpenParams.window = &window;
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0;
@ -253,7 +253,7 @@ namespace sk {
void
SetMousePosition(int x, int y)
{
glfwSetCursorPos(*engineStartParams.window, (double)x, (double)y);
glfwSetCursorPos(*engineOpenParams.window, (double)x, (double)y);
}
}

View File

@ -215,10 +215,10 @@ main(int argc, char *argv[])
if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0;
engineStartParams.width = sk::globals.width;
engineStartParams.height = sk::globals.height;
engineStartParams.windowtitle = sk::globals.windowtitle;
engineStartParams.window = &window;
engineOpenParams.width = sk::globals.width;
engineOpenParams.height = sk::globals.height;
engineOpenParams.windowtitle = sk::globals.windowtitle;
engineOpenParams.window = &window;
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0;
@ -316,7 +316,7 @@ namespace sk {
void
SetMousePosition(int x, int y)
{
SDL_WarpMouseInWindow(*engineStartParams.window, x, y);
SDL_WarpMouseInWindow(*engineOpenParams.window, x, y);
}
}

View File

@ -13,9 +13,34 @@ InitRW(void)
return false;
if(AppEventHandler(sk::PLUGINATTACH, nil) == EVENTERROR)
return false;
if(!rw::Engine::open())
if(!rw::Engine::open(&engineOpenParams))
return false;
if(!rw::Engine::start(&engineStartParams))
SubSystemInfo info;
int i, n;
n = Engine::getNumSubSystems();
for(i = 0; i < n; i++)
if(Engine::getSubSystemInfo(&info, i))
printf("subsystem: %s\n", info.name);
int want = -1;
VideoMode mode;
n = Engine::getNumVideoModes();
for(i = 0; i < n; i++)
if(Engine::getVideoModeInfo(&mode, i)){
if(mode.width == 640 && mode.height == 480 && mode.depth == 32)
want = i;
printf("mode: %dx%dx%d %d\n", mode.width, mode.height, mode.depth, mode.flags);
}
// if(want >= 0) Engine::setVideoMode(want);
Engine::getVideoModeInfo(&mode, Engine::getCurrentVideoMode());
if(mode.flags & VIDEOMODEEXCLUSIVE){
globals.width = mode.width;
globals.height = mode.height;
}
if(!rw::Engine::start())
return false;
rw::Image::setSearchPath("./");

View File

@ -1,4 +1,4 @@
extern rw::EngineStartParams engineStartParams;
extern rw::EngineOpenParams engineOpenParams;
namespace sk {

View File

@ -254,7 +254,7 @@ WinMain(HINSTANCE instance, HINSTANCE,
MessageBox(0, "MakeWindow() - FAILED", 0, 0);
return 0;
}
engineStartParams.window = win;
engineOpenParams.window = win;
initkeymap();
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
@ -283,7 +283,7 @@ void
SetMousePosition(int x, int y)
{
POINT pos = { x, y };
ClientToScreen(engineStartParams.window, &pos);
ClientToScreen(engineOpenParams.window, &pos);
SetCursorPos(pos.x, pos.y);
}

View File

@ -310,7 +310,7 @@ Matrix::transpose(Matrix *dst, const Matrix *src)
}
Matrix*
Matrix::rotate(V3d *axis, float32 angle, CombineOp op)
Matrix::rotate(const V3d *axis, float32 angle, CombineOp op)
{
Matrix tmp, rot;
makeRotation(&rot, axis, angle);
@ -351,7 +351,7 @@ Matrix::rotate(const Quat &q, CombineOp op)
return this;
}
Matrix*
Matrix::translate(V3d *translation, CombineOp op)
Matrix::translate(const V3d *translation, CombineOp op)
{
Matrix tmp;
Matrix trans = identMat;
@ -374,7 +374,7 @@ Matrix::translate(V3d *translation, CombineOp op)
}
Matrix*
Matrix::scale(V3d *scale, CombineOp op)
Matrix::scale(const V3d *scale, CombineOp op)
{
Matrix tmp;
Matrix scl = identMat;
@ -398,7 +398,7 @@ Matrix::scale(V3d *scale, CombineOp op)
}
Matrix*
Matrix::transform(Matrix *mat, CombineOp op)
Matrix::transform(const Matrix *mat, CombineOp op)
{
Matrix tmp;
switch(op){
@ -534,7 +534,7 @@ Matrix::invertGeneral(Matrix *dst, const Matrix *src)
}
void
Matrix::makeRotation(Matrix *dst, V3d *axis, float32 angle)
Matrix::makeRotation(Matrix *dst, const V3d *axis, float32 angle)
{
V3d v = normalize(*axis);
angle = angle*(float)M_PI/180.0f;

View File

@ -415,10 +415,10 @@ Camera::setProjection(int32 proj)
}
int32
Camera::frustumTestSphere(Sphere *s)
Camera::frustumTestSphere(const Sphere *s) const
{
int32 res = SPHEREINSIDE;
FrustumPlane *p = this->frustumPlanes;
const FrustumPlane *p = this->frustumPlanes;
for(int32 i = 0; i < 6; i++){
float32 dist = dot(p->plane.normal, s->center) - p->plane.distance;
if(s->radius < dist)

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwerror.h"
@ -20,11 +21,25 @@ namespace d3d {
#ifdef RW_D3D9
struct DisplayMode
{
D3DDISPLAYMODE mode;
uint32 flags;
};
struct D3d9Globals
{
HWND window;
bool windowed;
int presentWidth, presentHeight;
IDirect3D9 *d3d9;
int numAdapters;
int adapter;
D3DCAPS9 caps;
DisplayMode *modes;
int numModes;
int currentMode;
D3DPRESENT_PARAMETERS present;
} d3d9Globals;
// Keep track of rasters exclusively in video memory
@ -96,6 +111,7 @@ static D3DMATERIAL9 d3dmaterial;
static uint32 blendMap[] = {
D3DBLEND_ZERO, // actually invalid
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
@ -116,6 +132,7 @@ static uint32 alphafuncMap[] = {
};
static uint32 cullmodeMap[] = {
D3DCULL_NONE, // actually invalid
D3DCULL_NONE,
D3DCULL_CW,
D3DCULL_CCW
@ -721,29 +738,13 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
BOOL icon = IsIconic(d3d9Globals.window);
Raster *ras = cam->frameBuffer;
if(!icon &&
(r.right != d3d9Globals.presentWidth || r.bottom != d3d9Globals.presentHeight)){
(r.right != d3d9Globals.present.BackBufferWidth || r.bottom != d3d9Globals.present.BackBufferHeight)){
releaseVidmemRasters();
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = r.right;
d3dpp.BackBufferHeight = r.bottom;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = d3d9Globals.window;
d3dpp.Windowed = d3d9Globals.windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
// d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3d9Globals.present.BackBufferWidth = r.right;
d3d9Globals.present.BackBufferHeight = r.bottom;
// TODO: check result
d3d::d3ddevice->Reset(&d3dpp);
d3d9Globals.presentWidth = r.right;
d3d9Globals.presentHeight = r.bottom;
d3d::d3ddevice->Reset(&d3d9Globals.present);
resetD3d9Device();
}
@ -760,82 +761,209 @@ showRaster(Raster *raster)
d3ddevice->Present(nil, nil, 0, nil);
}
// taken from Frank Luna's d3d9 book
//
// Device
//
static int
openD3D(EngineStartParams *params)
findFormatDepth(uint32 format)
{
// not all formats actually
switch(format){
case D3DFMT_R8G8B8: return 24;
case D3DFMT_A8R8G8B8: return 32;
case D3DFMT_X8R8G8B8: return 32;
case D3DFMT_R5G6B5: return 16;
case D3DFMT_X1R5G5B5: return 16;
case D3DFMT_A1R5G5B5: return 16;
case D3DFMT_A4R4G4B4: return 16;
case D3DFMT_R3G3B2: return 8;
case D3DFMT_A8: return 8;
case D3DFMT_A8R3G3B2: return 16;
case D3DFMT_X4R4G4B4: return 16;
case D3DFMT_A2B10G10R10: return 32;
case D3DFMT_A8B8G8R8: return 32;
case D3DFMT_X8B8G8R8: return 32;
case D3DFMT_G16R16: return 32;
case D3DFMT_A2R10G10B10: return 32;
case D3DFMT_A16B16G16R16: return 64;
case D3DFMT_L8: return 8;
case D3DFMT_D16: return 16;
case D3DFMT_D24X8: return 32;
case D3DFMT_D32: return 32;
default: return 0;
}
}
// the commented ones don't "work"
static D3DFORMAT fbFormats[] = {
// D3DFMT_A1R5G5B5,
/// D3DFMT_A2R10G10B10, // works but let's not use it...
// D3DFMT_A8R8G8B8,
D3DFMT_R5G6B5,
// D3DFMT_X1R5G5B5,
D3DFMT_X8R8G8B8
};
static void
addVideoMode(D3DDISPLAYMODE *mode)
{
int i;
for(i = 1; i < d3d9Globals.numModes; i++){
if(d3d9Globals.modes[i].mode.Width == mode->Width &&
d3d9Globals.modes[i].mode.Height == mode->Height &&
d3d9Globals.modes[i].mode.Format == mode->Format){
// had this format already, remember highest refresh rate
if(mode->RefreshRate > d3d9Globals.modes[i].mode.RefreshRate)
d3d9Globals.modes[i].mode.RefreshRate = mode->RefreshRate;
return;
}
}
// none found, add
d3d9Globals.modes[d3d9Globals.numModes].mode = *mode;
d3d9Globals.modes[d3d9Globals.numModes].flags = VIDEOMODEEXCLUSIVE;
d3d9Globals.numModes++;
}
static void
makeVideoModeList(void)
{
int i, j;
D3DDISPLAYMODE mode;
d3d9Globals.numModes = 1;
for(i = 0; i < nelem(fbFormats); i++)
d3d9Globals.numModes += d3d9Globals.d3d9->GetAdapterModeCount(d3d9Globals.adapter, fbFormats[i]);
rwFree(d3d9Globals.modes);
d3d9Globals.modes = rwNewT(DisplayMode, d3d9Globals.numModes, ID_DRIVER | MEMDUR_EVENT);
// first mode is current mode as windowed
d3d9Globals.d3d9->GetAdapterDisplayMode(d3d9Globals.adapter, &d3d9Globals.modes[0].mode);
d3d9Globals.modes[0].flags = 0;
d3d9Globals.numModes = 1;
for(i = 0; i < nelem(fbFormats); i++){
int n = d3d9Globals.d3d9->GetAdapterModeCount(d3d9Globals.adapter, fbFormats[i]);
for(j = 0; j < n; j++){
d3d9Globals.d3d9->EnumAdapterModes(d3d9Globals.adapter, fbFormats[i], j, &mode);
addVideoMode(&mode);
}
}
}
static int
openD3D(EngineOpenParams *params)
{
HWND win = params->window;
bool windowed = true;
d3d9Globals.window = win;
d3d9Globals.windowed = windowed;
d3d9Globals.numAdapters = 0;
d3d9Globals.modes = nil;
d3d9Globals.numModes = 0;
d3d9Globals.currentMode = 0;
HRESULT hr = 0;
IDirect3D9 *d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d9){
d3d9Globals.d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(d3d9Globals.d3d9 == nil){
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
return 0;
}
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
int vp = 0;
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
d3d9Globals.numAdapters = d3d9Globals.d3d9->GetAdapterCount();
d3d9Globals.adapter = 0;
RECT rect;
GetClientRect(win, &rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
for(d3d9Globals.adapter = 0; d3d9Globals.adapter < d3d9Globals.numAdapters; d3d9Globals.adapter++)
if(d3d9Globals.d3d9->GetDeviceCaps(d3d9Globals.adapter, D3DDEVTYPE_HAL, &d3d9Globals.caps) == D3D_OK)
goto found;
// no adapter
d3d9Globals.d3d9->Release();
d3d9Globals.d3d9 = nil;
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
return 0;
d3d9Globals.presentWidth = width;
d3d9Globals.presentHeight = height;
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = win;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
// d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
IDirect3DDevice9 *dev;
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, win,
vp, &d3dpp, &dev);
if(FAILED(hr)){
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
win, vp, &d3dpp, &dev);
if(FAILED(hr)){
RWERROR((ERR_GENERAL, "CreateDevice() failed"));
d3d9->Release();
return 0;
}
}
d3d9->Release();
d3d::d3ddevice = dev;
found:
makeVideoModeList();
return 1;
}
static int
closeD3D(void)
{
d3d::d3ddevice->Release();
d3d::d3ddevice = nil;
d3d9Globals.d3d9->Release();
d3d9Globals.d3d9 = nil;
return 1;
}
static int
startD3D(void)
{
HRESULT hr;
int vp;
if(d3d9Globals.caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
uint32 width, height, depth;
D3DFORMAT format, zformat;
format = d3d9Globals.modes[d3d9Globals.currentMode].mode.Format;
// Use window size in windowed mode, otherwise get size from video mode
if(d3d9Globals.modes[d3d9Globals.currentMode].flags & VIDEOMODEEXCLUSIVE){
width = d3d9Globals.modes[d3d9Globals.currentMode].mode.Width;
height = d3d9Globals.modes[d3d9Globals.currentMode].mode.Height;
}else{
RECT rect;
GetClientRect(d3d9Globals.window, &rect);
width = rect.right - rect.left;
height = rect.bottom - rect.top;
}
bool windowed = !(d3d9Globals.modes[d3d9Globals.currentMode].flags & VIDEOMODEEXCLUSIVE);
// See if we can get an alpha channel
if(format == D3DFMT_X8R8G8B8){
if(d3d9Globals.d3d9->CheckDeviceType(d3d9Globals.adapter, D3DDEVTYPE_HAL, format, D3DFMT_A8R8G8B8, windowed) == D3D_OK)
format = D3DFMT_A8R8G8B8;
}
depth = findFormatDepth(format);
// TOOD: use something more sophisticated maybe?
if(depth == 32)
zformat = D3DFMT_D24S8;
else
zformat = D3DFMT_D16;
d3d9Globals.present.BackBufferWidth = width;
d3d9Globals.present.BackBufferHeight = height;
d3d9Globals.present.BackBufferFormat = format;
d3d9Globals.present.BackBufferCount = 1;
d3d9Globals.present.MultiSampleType = D3DMULTISAMPLE_NONE;
d3d9Globals.present.MultiSampleQuality = 0;
d3d9Globals.present.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d9Globals.present.hDeviceWindow = d3d9Globals.window;
d3d9Globals.present.Windowed = windowed;
d3d9Globals.present.EnableAutoDepthStencil = true;
d3d9Globals.present.AutoDepthStencilFormat = zformat;
d3d9Globals.present.Flags = 0;
d3d9Globals.present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
// d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
IDirect3DDevice9 *dev;
hr = d3d9Globals.d3d9->CreateDevice(d3d9Globals.adapter, D3DDEVTYPE_HAL,
d3d9Globals.window, vp, &d3d9Globals.present, &dev);
if(FAILED(hr)){
RWERROR((ERR_GENERAL, "CreateDevice() failed"));
return 0;
}
d3d::d3ddevice = dev;
return 1;
}
@ -1027,6 +1155,9 @@ termD3D(void)
{
closeIm3D();
closeIm2D();
d3d::d3ddevice->Release();
d3d::d3ddevice = nil;
return 1;
}
@ -1037,21 +1168,69 @@ finalizeD3D(void)
}
static int
deviceSystem(DeviceReq req, void *arg0)
deviceSystem(DeviceReq req, void *arg, int32 n)
{
D3DADAPTER_IDENTIFIER9 adapter;
VideoMode *rwmode;
switch(req){
case DEVICEOPEN:
return openD3D((EngineStartParams*)arg0);
return openD3D((EngineOpenParams*)arg);
case DEVICECLOSE:
return closeD3D();
case DEVICEINIT:
return initD3D();
return startD3D() && initD3D();
case DEVICETERM:
return termD3D();
case DEVICEFINALIZE:
return finalizeD3D();
case DEVICEGETNUMSUBSYSTEMS:
return d3d9Globals.numAdapters;
case DEVICEGETCURRENTSUBSYSTEM:
return d3d9Globals.adapter;
case DEVICESETSUBSYSTEM:
if(n >= d3d9Globals.numAdapters)
return 0;
d3d9Globals.adapter = n;
if(d3d9Globals.d3d9->GetDeviceCaps(d3d9Globals.adapter, D3DDEVTYPE_HAL, &d3d9Globals.caps) != D3D_OK)
return 0;
makeVideoModeList();
return 1;
case DEVICEGETSUBSSYSTEMINFO:
if(n >= d3d9Globals.numAdapters)
return 0;
if(d3d9Globals.d3d9->GetAdapterIdentifier(d3d9Globals.adapter, 0, &adapter) != D3D_OK)
return 0;
strncpy(((SubSystemInfo*)arg)->name, adapter.Description, sizeof(SubSystemInfo::name));
return 1;
case DEVICEGETNUMVIDEOMODES:
return d3d9Globals.numModes;
case DEVICEGETCURRENTVIDEOMODE:
return d3d9Globals.currentMode;
case DEVICESETVIDEOMODE:
if(n >= d3d9Globals.numModes)
return 0;
d3d9Globals.currentMode = n;
return 1;
case DEVICEGETVIDEOMODEINFO:
rwmode = (VideoMode*)arg;
rwmode->width = d3d9Globals.modes[n].mode.Width;
rwmode->height = d3d9Globals.modes[n].mode.Height;
rwmode->depth = findFormatDepth(d3d9Globals.modes[n].mode.Format);
rwmode->flags = d3d9Globals.modes[n].flags;
return 1;
}
return 1;
}

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <cassert>
#define WITH_D3D
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"

View File

@ -1,37 +1,56 @@
#ifdef RW_D3D9
#define NOMINMAX 1
#ifdef WITH_D3D
#include <d3d9.h>
#endif
#endif
namespace rw {
#ifdef RW_D3D9
struct EngineStartParams
#ifdef _WINDOWS_
struct EngineOpenParams
{
HWND window;
};
#else
struct EngineOpenParams
{
uint32 please_include_windows_h;
};
#endif
#else
#ifdef _D3D9_H_
#error "please don't include d3d9.h for non-d3d9 platforms"
#endif
#endif
namespace d3d {
extern bool32 isP8supported;
#ifdef RW_D3D9
extern IDirect3DDevice9 *d3ddevice;
extern Device renderdevice;
#ifdef RW_D3D9
#ifdef _D3D9_H_
extern IDirect3DDevice9 *d3ddevice;
void setD3dMaterial(D3DMATERIAL9 *mat9);
#endif
void lightingCB(bool32 normals);
#define COLOR_ARGB(a, r, g, b) ((rw::uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
struct Im3DVertex
{
V3d position;
D3DCOLOR color;
uint32 color;
float32 u, v;
void setX(float32 x) { this->position.x = x; }
void setY(float32 y) { this->position.y = y; }
void setZ(float32 z) { this->position.z = z; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); }
void setU(float32 u) { this->u = u; }
void setV(float32 v) { this->v = v; }
@ -48,7 +67,7 @@ struct Im2DVertex
{
float32 x, y, z;
float32 w;
D3DCOLOR color;
uint32 color;
float32 u, v;
void setScreenX(float32 x) { this->x = x; }
@ -56,7 +75,7 @@ struct Im2DVertex
void setScreenZ(float32 z) { this->z = z; }
void setCameraZ(float32 z) { }
void setRecipCameraZ(float32 recipz) { this->w = recipz; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); }
void setU(float32 u, float recipZ) { this->u = u; }
void setV(float32 v, float recipZ) { this->v = v; }
@ -70,8 +89,6 @@ struct Im2DVertex
float getV(void) { return this->v; }
};
void setD3dMaterial(D3DMATERIAL9 *mat9);
#else
enum {
D3DLOCK_NOSYSLOCK = 0, // ignored
@ -120,7 +137,6 @@ enum {
D3DDECLUSAGE_DEPTH, // 12
D3DDECLUSAGE_SAMPLE // 13
};
#endif
extern int vertFormatMap[];

View File

@ -99,9 +99,8 @@ Engine::init(void)
}
// This is where RW allocates the engine and e.g. opens d3d
// TODO: this will probably take an argument with device specific data
bool32
Engine::open(void)
Engine::open(EngineOpenParams *p)
{
if(engine || Engine::state != Initialized){
RWERROR((ERR_ENGINEOPEN));
@ -125,7 +124,8 @@ Engine::open(void)
engine->device = null::renderdevice;
#endif
// TODO: open device; create d3d object/get video mode
// TODO: create d3d object/get video mode
engine->device.system(DEVICEOPEN, (void*)p, 0);
// TODO: init driver functions
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
@ -150,24 +150,22 @@ Engine::open(void)
}
// This is where RW creates the actual rendering device
// ans calls the engine plugin ctors
// and calls the engine plugin ctors
bool32
Engine::start(EngineStartParams *p)
Engine::start(void)
{
if(engine == nil || Engine::state != Opened){
RWERROR((ERR_ENGINESTART));
return 0;
}
// TODO: put this into Open?
engine->device.system(DEVICEOPEN, (void*)p);
engine->device.system(DEVICEINIT, nil);
engine->device.system(DEVICEINIT, nil, 0);
Engine::s_plglist.construct(engine);
for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].construct(rw::engine->driver[i]);
engine->device.system(DEVICEFINALIZE, nil);
engine->device.system(DEVICEFINALIZE, nil, 0);
Engine::state = Started;
return 1;
@ -177,30 +175,100 @@ void
Engine::term(void)
{
// TODO
if(engine || Engine::state != Initialized){
RWERROR((ERR_GENERAL));
return;
}
Engine::state = Dead;
}
void
Engine::close(void)
{
// TODO
if(engine == nil || Engine::state != Opened){
RWERROR((ERR_GENERAL));
return;
}
engine->device.system(DEVICECLOSE, nil, 0);
for(uint i = 0; i < NUM_PLATFORMS; i++)
rwFree(rw::engine->driver[i]);
rwFree(engine);
engine = nil;
Engine::state = Initialized;
}
void
Engine::stop(void)
{
engine->device.system(DEVICETERM, nil);
engine->device.system(DEVICECLOSE, nil);
if(engine == nil || Engine::state != Started){
RWERROR((ERR_GENERAL));
return;
}
engine->device.system(DEVICETERM, nil, 0);
for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].destruct(rw::engine->driver[i]);
Engine::s_plglist.destruct(engine);
Engine::state = Opened;
}
int32
Engine::getNumSubSystems(void)
{
return engine->device.system(DEVICEGETNUMSUBSYSTEMS, nil, 0);
}
int32
Engine::getCurrentSubSystem(void)
{
return engine->device.system(DEVICEGETCURRENTSUBSYSTEM, nil, 0);
}
bool32
Engine::setSubSystem(int32 subsys)
{
return engine->device.system(DEVICESETSUBSYSTEM, nil, subsys);
}
SubSystemInfo*
Engine::getSubSystemInfo(SubSystemInfo *info, int32 subsys)
{
if(engine->device.system(DEVICEGETSUBSSYSTEMINFO, info, subsys))
return info;
return nil;
}
int32
Engine::getNumVideoModes(void)
{
return engine->device.system(DEVICEGETNUMVIDEOMODES, nil, 0);
}
int32
Engine::getCurrentVideoMode(void)
{
return engine->device.system(DEVICEGETCURRENTVIDEOMODE, nil, 0);
}
bool32
Engine::setVideoMode(int32 mode)
{
return engine->device.system(DEVICESETVIDEOMODE, nil, mode);
}
VideoMode*
Engine::getVideoModeInfo(VideoMode *info, int32 mode)
{
if(engine->device.system(DEVICEGETVIDEOMODEINFO, info, mode))
return info;
return nil;
}
namespace null {
void beginUpdate(Camera*) { }
@ -273,8 +341,16 @@ rasterToImage(Raster*)
}
int
deviceSystem(DeviceReq req, void *arg0)
deviceSystem(DeviceReq req, void *arg0, int32 n)
{
switch(req){
case DEVICEGETNUMSUBSYSTEMS:
return 0;
case DEVICEGETCURRENTSUBSYSTEM:
return 0;
case DEVICEGETSUBSSYSTEMINFO:
return 0;
}
return 1;
}

View File

@ -258,28 +258,28 @@ Frame::syncDirty(void)
}
void
Frame::rotate(V3d *axis, float32 angle, CombineOp op)
Frame::rotate(const V3d *axis, float32 angle, CombineOp op)
{
this->matrix.rotate(axis, angle, op);
updateObjects();
}
void
Frame::translate(V3d *trans, CombineOp op)
Frame::translate(const V3d *trans, CombineOp op)
{
this->matrix.translate(trans, op);
updateObjects();
}
void
Frame::scale(V3d *scl, CombineOp op)
Frame::scale(const V3d *scl, CombineOp op)
{
this->matrix.scale(scl, op);
updateObjects();
}
void
Frame::transform(Matrix *mat, CombineOp op)
Frame::transform(const Matrix *mat, CombineOp op)
{
this->matrix.transform(mat, op);
updateObjects();

View File

@ -330,21 +330,7 @@ Geometry::calculateBoundingSphere(void)
{
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i];
V3d min = { 1000000.0f, 1000000.0f, 1000000.0f };
V3d max = { -1000000.0f, -1000000.0f, -1000000.0f };
V3d *v = m->vertices;
for(int32 j = 0; j < this->numVertices; j++){
if(v->x > max.x) max.x = v->x;
if(v->x < min.x) min.x = v->x;
if(v->y > max.y) max.y = v->y;
if(v->y < min.y) min.y = v->y;
if(v->z > max.z) max.z = v->z;
if(v->z < min.z) min.z = v->z;
v++;
}
m->boundingSphere.center = scale(add(min, max), 1/2.0f);
max = sub(max, m->boundingSphere.center);
m->boundingSphere.radius = length(max);
m->boundingSphere = m->calculateBoundingSphere();
}
}
@ -673,6 +659,29 @@ Geometry::removeUnusedMaterials(void)
rwFree(map);
}
Sphere
MorphTarget::calculateBoundingSphere(void) const
{
Sphere sphere;
V3d min = { 1000000.0f, 1000000.0f, 1000000.0f };
V3d max = { -1000000.0f, -1000000.0f, -1000000.0f };
V3d *v = this->vertices;
for(int32 j = 0; j < this->parent->numVertices; j++){
if(v->x > max.x) max.x = v->x;
if(v->x < min.x) min.x = v->x;
if(v->y > max.y) max.y = v->y;
if(v->y < min.y) min.y = v->y;
if(v->z > max.z) max.z = v->z;
if(v->z < min.z) min.z = v->z;
v++;
}
sphere.center = scale(add(min, max), 1/2.0f);
max = sub(max, sphere.center);
sphere.radius = length(max);
return sphere;
}
//
// MaterialList
//

View File

@ -26,6 +26,13 @@
namespace rw {
namespace gl3 {
struct DisplayMode
{
GLFWvidmode mode;
int32 depth;
uint32 flags;
};
struct GlGlobals
{
#ifdef LIBRW_SDL2
@ -33,8 +40,21 @@ struct GlGlobals
SDL_GLContext glcontext;
#else
GLFWwindow *window;
GLFWmonitor *monitor;
int numMonitors;
int currentMonitor;
DisplayMode *modes;
int numModes;
int currentMode;
#endif
int presentWidth, presentHeight;
// for opening the window
int winWidth, winHeight;
const char *winTitle;
GLFWwindow **pWindow;
} glGlobals;
struct UniformState
@ -119,6 +139,7 @@ static RwStateCache rwStateCache;
static int32 activeTexture;
static uint32 blendMap[] = {
GL_ZERO, // actually invalid
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
@ -728,10 +749,10 @@ beginUpdate(Camera *cam)
#ifdef LIBRW_SDL2
static int
openSDL2(EngineStartParams *startparams)
openSDL2(EngineOpenParams *openparams)
{
if (!startparams){
RWERROR((ERR_GENERAL, "startparams invalid"));
if (!openparams){
RWERROR((ERR_GENERAL, "openparams invalid"));
return 0;
}
@ -752,9 +773,9 @@ openSDL2(EngineStartParams *startparams)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
int flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL;
if (startparams->fullscreen)
if (openparams->fullscreen)
flags |= SDL_WINDOW_FULLSCREEN;
win = SDL_CreateWindow(startparams->windowtitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, startparams->width, startparams->height, flags);
win = SDL_CreateWindow(openparams->windowtitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, openparams->width, openparams->height, flags);
if(win == nil){
RWERROR((ERR_ENGINEOPEN, SDL_GetError()));
SDL_QuitSubSystem(SDL_INIT_VIDEO);
@ -781,7 +802,7 @@ openSDL2(EngineStartParams *startparams)
}
glGlobals.window = win;
glGlobals.glcontext = ctx;
*startparams->window = win;
*openparams->window = win;
return 1;
}
@ -794,11 +815,64 @@ closeSDL2(void)
return 1;
}
#else
static int
openGLFW(EngineStartParams *startparams)
static void
addVideoMode(const GLFWvidmode *mode)
{
GLenum status;
GLFWwindow *win;
int i;
for(i = 1; i < glGlobals.numModes; i++){
if(glGlobals.modes[i].mode.width == mode->width &&
glGlobals.modes[i].mode.height == mode->height &&
glGlobals.modes[i].mode.redBits == mode->redBits &&
glGlobals.modes[i].mode.greenBits == mode->greenBits &&
glGlobals.modes[i].mode.blueBits == mode->blueBits){
// had this mode already, remember highest refresh rate
if(mode->refreshRate > glGlobals.modes[i].mode.refreshRate)
glGlobals.modes[i].mode.refreshRate = mode->refreshRate;
return;
}
}
// none found, add
glGlobals.modes[glGlobals.numModes].mode = *mode;
glGlobals.modes[glGlobals.numModes].flags = VIDEOMODEEXCLUSIVE;
glGlobals.numModes++;
}
static void
makeVideoModeList(void)
{
int i, num;
const GLFWvidmode *modes;
modes = glfwGetVideoModes(glGlobals.monitor, &num);
rwFree(glGlobals.modes);
glGlobals.modes = rwNewT(DisplayMode, num, ID_DRIVER | MEMDUR_EVENT);
glGlobals.modes[0].mode = *glfwGetVideoMode(glGlobals.monitor);
glGlobals.modes[0].flags = 0;
glGlobals.numModes = 1;
for(i = 0; i < num; i++)
addVideoMode(&modes[i]);
for(i = 0; i < glGlobals.numModes; i++){
num = glGlobals.modes[i].mode.redBits +
glGlobals.modes[i].mode.greenBits +
glGlobals.modes[i].mode.blueBits;
// set depth to power of two
for(glGlobals.modes[i].depth = 1; glGlobals.modes[i].depth < num; glGlobals.modes[i].depth <<= 1);
}
}
static int
openGLFW(EngineOpenParams *openparams)
{
glGlobals.winWidth = openparams->width;
glGlobals.winHeight = openparams->height;
glGlobals.winTitle = openparams->windowtitle;
glGlobals.pWindow = openparams->window;
/* Init GLFW */
if(!glfwInit()){
@ -811,20 +885,42 @@ openGLFW(EngineStartParams *startparams)
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
win = glfwCreateWindow(startparams->width, startparams->height, startparams->windowtitle, 0, 0);
glGlobals.monitor = glfwGetMonitors(&glGlobals.numMonitors)[0];
makeVideoModeList();
return 1;
}
static int
closeGLFW(void)
{
glfwTerminate();
return 1;
}
static int
startGLFW(void)
{
GLenum status;
GLFWwindow *win;
DisplayMode *mode;
mode = &glGlobals.modes[glGlobals.currentMode];
glfwWindowHint(GLFW_RED_BITS, mode->mode.redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->mode.greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->mode.blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, mode->mode.refreshRate);
if(mode->flags & VIDEOMODEEXCLUSIVE)
win = glfwCreateWindow(mode->mode.width, mode->mode.height, glGlobals.winTitle, glGlobals.monitor, nil);
else
win = glfwCreateWindow(glGlobals.winWidth, glGlobals.winHeight, glGlobals.winTitle, nil, nil);
if(win == nil){
RWERROR((ERR_GENERAL, "glfwCreateWindow() failed"));
glfwTerminate();
return 0;
}
if(startparams->fullscreen){
int nbmonitors;
auto monitors = glfwGetMonitors(&nbmonitors);
if (nbmonitors){
const GLFWvidmode* mode = glfwGetVideoMode(monitors[0]);
glfwSetWindowMonitor(win, monitors[0], 0, 0, mode->width, mode->height, mode->refreshRate);
}
}
glfwMakeContextCurrent(win);
/* Init GLEW */
@ -833,25 +929,22 @@ openGLFW(EngineStartParams *startparams)
if(status != GLEW_OK){
RWERROR((ERR_GENERAL, glewGetErrorString(status)));
glfwDestroyWindow(win);
glfwTerminate();
return 0;
}
if(!GLEW_VERSION_3_3){
RWERROR((ERR_GENERAL, "OpenGL 3.3 needed"));
glfwDestroyWindow(win);
glfwTerminate();
return 0;
}
glGlobals.window = win;
*startparams->window = win;
*glGlobals.pWindow = win;
return 1;
}
static int
closeGLFW(void)
stopGLFW(void)
{
glfwDestroyWindow(glGlobals.window);
glfwTerminate();
return 1;
}
#endif
@ -925,34 +1018,105 @@ finalizeOpenGL(void)
return 1;
}
#ifdef LIBRW_SDL2
static int
deviceSystem(DeviceReq req, void *arg0)
deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
{
switch(req){
case DEVICEOPEN:
#ifdef LIBRW_SDL2
return openSDL2((EngineStartParams*)arg0);
#else
return openGLFW((EngineStartParams*)arg0);
#endif
return openSDL2((EngineOpenParams*)arg);
case DEVICECLOSE:
#ifdef LIBRW_SDL2
return closeSDL2();
#else
return closeGLFW();
#endif
case DEVICEINIT:
return initOpenGL();
case DEVICETERM:
return termOpenGL();
case DEVICEFINALIZE:
return finalizeOpenGL();
// TODO: implement subsystems and video modes
default:
assert(0 && "not implemented");
return 0;
}
return 1;
}
#else
static int
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
{
GLFWmonitor **monitors;
VideoMode *rwmode;
int num;
switch(req){
case DEVICEOPEN:
return openGLFW((EngineOpenParams*)arg);
case DEVICECLOSE:
return closeGLFW();
case DEVICEINIT:
return startGLFW() && initOpenGL();
case DEVICETERM:
return termOpenGL() && stopGLFW();
case DEVICEFINALIZE:
return finalizeOpenGL();
case DEVICEGETNUMSUBSYSTEMS:
return glGlobals.numMonitors;
case DEVICEGETCURRENTSUBSYSTEM:
return glGlobals.currentMonitor;
case DEVICESETSUBSYSTEM:
monitors = glfwGetMonitors(&glGlobals.numMonitors);
if(n >= glGlobals.numMonitors)
return 0;
glGlobals.currentMonitor = n;
glGlobals.monitor = monitors[glGlobals.currentMonitor];
return 1;
case DEVICEGETSUBSSYSTEMINFO:
monitors = glfwGetMonitors(&glGlobals.numMonitors);
if(n >= glGlobals.numMonitors)
return 0;
strncpy(((SubSystemInfo*)arg)->name, glfwGetMonitorName(monitors[n]), sizeof(SubSystemInfo::name));
return 1;
case DEVICEGETNUMVIDEOMODES:
return glGlobals.numModes;
case DEVICEGETCURRENTVIDEOMODE:
return glGlobals.currentMode;
case DEVICESETVIDEOMODE:
if(n >= glGlobals.numModes)
return 0;
glGlobals.currentMode = n;
return 1;
case DEVICEGETVIDEOMODEINFO:
rwmode = (VideoMode*)arg;
rwmode->width = glGlobals.modes[n].mode.width;
rwmode->height = glGlobals.modes[n].mode.height;
rwmode->depth = glGlobals.modes[n].depth;
rwmode->flags = glGlobals.modes[n].flags;
return 1;
default:
assert(0 && "not implemented");
return 0;
}
return 1;
}
#endif
Device renderdevice = {
-1.0f, 1.0f,
gl3::beginUpdate,
@ -968,7 +1132,11 @@ Device renderdevice = {
gl3::im3DTransform,
gl3::im3DRenderIndexed,
gl3::im3DEnd,
gl3::deviceSystem
#ifdef LIBRW_SDL2
gl3::deviceSystemSDL2
#else
gl3::deviceSystemGLFW
#endif
};
}

View File

@ -43,6 +43,7 @@ rasterCreate(Raster *raster)
// TODO: set/check width, height, depth, format?
raster->flags |= Raster::DONTALLOCATE;
break;
case Raster::NORMAL:
case Raster::TEXTURE:
// continue below
break;
@ -53,8 +54,6 @@ rasterCreate(Raster *raster)
if(raster->flags & Raster::DONTALLOCATE)
return;
assert(raster->type == Raster::TEXTURE);
#ifdef RW_OPENGL
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
switch(raster->format & 0xF00){

View File

@ -10,7 +10,7 @@
namespace rw {
#ifdef RW_GL3
struct EngineStartParams
struct EngineOpenParams
{
#ifdef LIBRW_SDL2
SDL_Window **window;
@ -18,7 +18,6 @@ struct EngineStartParams
GLFWwindow **window;
#endif
int width, height;
bool32 fullscreen;
const char *windowtitle;
};
#endif

View File

@ -1,7 +1,7 @@
namespace rw {
#ifdef RW_PS2
struct EngineStartParams
struct EngineOpenParams
{
};
#endif

View File

@ -322,11 +322,11 @@ struct Matrix
static Matrix *mult(Matrix *dst, const Matrix *src1, const Matrix *src2);
static Matrix *invert(Matrix *dst, const Matrix *src);
static Matrix *transpose(Matrix *dst, const Matrix *src);
Matrix *rotate(V3d *axis, float32 angle, CombineOp op);
Matrix *rotate(const V3d *axis, float32 angle, CombineOp op);
Matrix *rotate(const Quat &q, CombineOp op);
Matrix *translate(V3d *translation, CombineOp op);
Matrix *scale(V3d *scl, CombineOp op);
Matrix *transform(Matrix *mat, CombineOp op);
Matrix *translate(const V3d *translation, CombineOp op);
Matrix *scale(const V3d *scl, CombineOp op);
Matrix *transform(const Matrix *mat, CombineOp op);
Quat getRotation(void);
void lookAt(const V3d &dir, const V3d &up);
@ -334,7 +334,7 @@ struct Matrix
static void mult_(Matrix *dst, const Matrix *src1, const Matrix *src2);
static void invertOrthonormal(Matrix *dst, const Matrix *src);
static Matrix *invertGeneral(Matrix *dst, const Matrix *src);
static void makeRotation(Matrix *dst, V3d *axis, float32 angle);
static void makeRotation(Matrix *dst, const V3d *axis, float32 angle);
static void makeRotation(Matrix *dst, const Quat &q);
private:
float32 normalError(void);

View File

@ -2,22 +2,34 @@ namespace rw {
enum DeviceReq
{
// Device/Context creation
DEVICEOPEN,
// Device/Context shutdown
DEVICECLOSE,
// Device initialization before Engine/Driver plugins are opened
DEVICEINIT,
// Device de-initialization after Engine/Driver plugins are closed
DEVICETERM,
// Device/Context creation
DEVICEOPEN,
// Device/Context shutdown
DEVICECLOSE,
// Device initialization after Engine/Driver plugins are opened
DEVICEFINALIZE
DEVICEFINALIZE,
// TODO? counterpart to FINALIZE?
// Video adapters
DEVICEGETNUMSUBSYSTEMS,
DEVICEGETCURRENTSUBSYSTEM,
DEVICESETSUBSYSTEM,
DEVICEGETSUBSSYSTEMINFO,
// Video modes
DEVICEGETNUMVIDEOMODES,
DEVICEGETCURRENTVIDEOMODE,
DEVICESETVIDEOMODE,
DEVICEGETVIDEOMODEINFO
};
typedef int DeviceSystem(DeviceReq req, void *arg0);
typedef int DeviceSystem(DeviceReq req, void *arg, int32 n);
struct Camera;
struct Image;
@ -75,7 +87,7 @@ struct Driver
}
};
struct EngineStartParams;
struct EngineOpenParams;
enum MemHint
{
@ -101,6 +113,25 @@ struct MemoryFunctions
void *(*rwmustrealloc)(void *p, size_t sz, uint32 hint);
};
struct SubSystemInfo
{
char name[80];
};
enum VideoModeFlags
{
VIDEOMODEEXCLUSIVE = 1
};
struct VideoMode
{
int32 width;
int32 height;
int32 depth;
uint32 flags;
};
// This is for platform independent things
// TODO: move more stuff into this
struct Engine
@ -124,12 +155,23 @@ struct Engine
static State state;
static bool32 init(void);
static bool32 open(void);
static bool32 start(EngineStartParams*);
static bool32 open(EngineOpenParams*);
static bool32 start(void);
static void term(void);
static void close(void);
static void stop(void);
static int32 getNumSubSystems(void);
static int32 getCurrentSubSystem(void);
static bool32 setSubSystem(int32 subsys);
static SubSystemInfo *getSubSystemInfo(SubSystemInfo *info, int32 subsys);
static int32 getNumVideoModes(void);
static int32 getCurrentVideoMode(void);
static bool32 setVideoMode(int32 mode);
static VideoMode *getVideoModeInfo(VideoMode *info, int32 mode);
static PluginList s_plglist;
static int32 registerPlugin(int32 size, uint32 id,
Constructor ctor, Destructor dtor){

View File

@ -62,16 +62,16 @@ struct Frame
Frame *addChild(Frame *f, bool32 append = 0);
Frame *removeChild(void);
Frame *forAllChildren(Callback cb, void *data);
Frame *getParent(void){
Frame *getParent(void) const {
return (Frame*)this->object.parent; }
int32 count(void);
bool32 dirty(void) {
bool32 dirty(void) const {
return !!(this->root->object.privateFlags & HIERARCHYSYNC); }
Matrix *getLTM(void);
void rotate(V3d *axis, float32 angle, CombineOp op);
void translate(V3d *trans, CombineOp op);
void scale(V3d *scale, CombineOp op);
void transform(Matrix *mat, CombineOp op);
void rotate(const V3d *axis, float32 angle, CombineOp op);
void translate(const V3d *trans, CombineOp op);
void scale(const V3d *scale, CombineOp op);
void transform(const Matrix *mat, CombineOp op);
void updateObjects(void);
@ -350,6 +350,8 @@ struct MorphTarget
Sphere boundingSphere;
V3d *vertices;
V3d *normals;
Sphere calculateBoundingSphere(void) const;
};
struct InstanceDataHeader
@ -482,7 +484,7 @@ struct Atomic
this->object.setFrame(f);
this->object.object.privateFlags |= WORLDBOUNDDIRTY;
}
Frame *getFrame(void) { return (Frame*)this->object.object.parent; }
Frame *getFrame(void) const { return (Frame*)this->object.object.parent; }
static Atomic *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Atomic, inClump); }
void removeFromClump(void);
@ -498,7 +500,7 @@ struct Atomic
this->renderCB = defaultRenderCB;
};
void setFlags(uint32 flags) { this->object.object.flags = flags; }
uint32 getFlags(void) { return this->object.object.flags; }
uint32 getFlags(void) const { return this->object.object.flags; }
static Atomic *streamReadClump(Stream *stream,
FrameList_ *frameList, Geometry **geometryList);
bool streamWriteClump(Stream *stream, FrameList_ *frmlst);
@ -530,7 +532,7 @@ struct Light
static Light *create(int32 type);
void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); }
Frame *getFrame(void){ return (Frame*)this->object.object.parent; }
Frame *getFrame(void) const { return (Frame*)this->object.object.parent; }
static Light *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Light, inClump); }
static Light *fromWorld(LLLink *lnk){
@ -617,7 +619,7 @@ struct Camera
Camera *clone(void);
void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); }
Frame *getFrame(void){ return (Frame*)this->object.object.parent; }
Frame *getFrame(void)const { return (Frame*)this->object.object.parent; }
static Camera *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Camera, inClump); }
void beginUpdate(void) { this->beginUpdateCB(this); }
@ -629,7 +631,7 @@ struct Camera
void setViewWindow(const V2d *window);
void setViewOffset(const V2d *offset);
void setProjection(int32 proj);
int32 frustumTestSphere(Sphere *s);
int32 frustumTestSphere(const Sphere *s) const;
static Camera *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
@ -669,7 +671,7 @@ struct Clump
}
void setFrame(Frame *f){
this->object.parent = f; }
Frame *getFrame(void){
Frame *getFrame(void) const {
return (Frame*)this->object.parent; }
static Clump *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
@ -687,8 +689,11 @@ struct World
LinkList directionalLights; // these do not (type < 0x80)
static World *create(void);
void destroy(void);
void addLight(Light *light);
void removeLight(Light *light);
void addCamera(Camera *cam);
void removeCamera(Camera *cam);
};
struct TexDictionary

View File

@ -218,7 +218,7 @@ struct Skin
void findUsedBones(int32 numVertices);
static void setPipeline(Atomic *a, int32 type);
static Skin *get(Geometry *geo){
static Skin *get(const Geometry *geo){
return *PLUGINOFFSET(Skin*, geo, skinGlobals.geoOffset);
}
static void set(Geometry *geo, Skin *skin){
@ -228,7 +228,7 @@ struct Skin
*PLUGINOFFSET(HAnimHierarchy*, atomic,
skinGlobals.atomicOffset) = hier;
}
static HAnimHierarchy *getHierarchy(Atomic *atomic){
static HAnimHierarchy *getHierarchy(const Atomic *atomic){
return *PLUGINOFFSET(HAnimHierarchy*, atomic,
skinGlobals.atomicOffset);
}

View File

@ -29,21 +29,21 @@ enum RenderState
enum AlphaTestFunc
{
ALPHAALWAYS = 0,
ALPHAALWAYS,
ALPHAGREATEREQUAL,
ALPHALESS
};
enum CullMode
{
CULLNONE,
CULLNONE = 1,
CULLBACK,
CULLFRONT
};
enum BlendFunction
{
BLENDZERO = 0,
BLENDZERO = 1,
BLENDONE,
BLENDSRCCOLOR,
BLENDINVSRCCOLOR,

View File

@ -26,9 +26,17 @@ World::create(void)
world->object.init(World::ID, 0);
world->lights.init();
world->directionalLights.init();
s_plglist.construct(world);
return world;
}
void
World::destroy(void)
{
s_plglist.destruct(this);
rwFree(this);
}
void
World::addLight(Light *light)
{
@ -42,6 +50,13 @@ World::addLight(Light *light)
}
}
void
World::removeLight(Light *light)
{
if(light->world == this)
light->inWorld.remove();
}
void
World::addCamera(Camera *cam)
{
@ -50,4 +65,11 @@ World::addCamera(Camera *cam)
cam->getFrame()->updateObjects();
}
void
World::removeCamera(Camera *cam)
{
if(cam->world == this)
cam->world = nil;
}
}

View File

@ -12,9 +12,9 @@ struct SceneGlobals {
} Scene;
rw::Texture *tex, *tex2;
rw::Raster *testras;
rw::EngineStartParams engineStartParams;
rw::EngineOpenParams engineOpenParams;
bool dosoftras = 1;
bool dosoftras = 0;
namespace gen {
void tlTest(rw::Clump *clump);

View File

@ -843,6 +843,8 @@ endSoftras(void)
{
int i;
uint8 *dst = testras->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
if(dst == nil)
return;
uint8 *src = rs::canvas->fb;
for(i = 0; i < rs::canvas->w*rs::canvas->h; i++){
dst[0] = src[1];

View File

@ -7,7 +7,7 @@ struct SceneGlobals {
rw::World *world;
rw::Camera *camera;
} Scene;
rw::EngineStartParams engineStartParams;
rw::EngineOpenParams engineOpenParams;
void
Init(void)

View File

@ -626,7 +626,7 @@ beginCamera(void)
f[3] = 0.0f;
}
rw::EngineStartParams engineStartParams;
rw::EngineOpenParams engineOpenParams;
void
pluginattach(void)
@ -654,9 +654,9 @@ initrw(void)
if(!rw::Engine::init())
return 0;
pluginattach();
if(!rw::Engine::open())
if(!rw::Engine::open(&engineOpenParams))
return 0;
if(!rw::Engine::start(&engineStartParams))
if(!rw::Engine::start())
return 0;
rw::Texture::setLoadTextures(0);