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) if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0; return 0;
engineStartParams.width = sk::globals.width; engineOpenParams.width = sk::globals.width;
engineStartParams.height = sk::globals.height; engineOpenParams.height = sk::globals.height;
engineStartParams.windowtitle = sk::globals.windowtitle; engineOpenParams.windowtitle = sk::globals.windowtitle;
engineStartParams.window = &window; engineOpenParams.window = &window;
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR) if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0; return 0;
@ -253,7 +253,7 @@ namespace sk {
void void
SetMousePosition(int x, int y) 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) if(EventHandler(INITIALIZE, nil) == EVENTERROR)
return 0; return 0;
engineStartParams.width = sk::globals.width; engineOpenParams.width = sk::globals.width;
engineStartParams.height = sk::globals.height; engineOpenParams.height = sk::globals.height;
engineStartParams.windowtitle = sk::globals.windowtitle; engineOpenParams.windowtitle = sk::globals.windowtitle;
engineStartParams.window = &window; engineOpenParams.window = &window;
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR) if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
return 0; return 0;
@ -316,7 +316,7 @@ namespace sk {
void void
SetMousePosition(int x, int y) 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; return false;
if(AppEventHandler(sk::PLUGINATTACH, nil) == EVENTERROR) if(AppEventHandler(sk::PLUGINATTACH, nil) == EVENTERROR)
return false; return false;
if(!rw::Engine::open()) if(!rw::Engine::open(&engineOpenParams))
return false; 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; return false;
rw::Image::setSearchPath("./"); rw::Image::setSearchPath("./");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
#define WITH_D3D
#include "../rwbase.h" #include "../rwbase.h"
#include "../rwplg.h" #include "../rwplg.h"
#include "../rwerror.h" #include "../rwerror.h"
@ -20,11 +21,25 @@ namespace d3d {
#ifdef RW_D3D9 #ifdef RW_D3D9
struct DisplayMode
{
D3DDISPLAYMODE mode;
uint32 flags;
};
struct D3d9Globals struct D3d9Globals
{ {
HWND window; 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; } d3d9Globals;
// Keep track of rasters exclusively in video memory // Keep track of rasters exclusively in video memory
@ -96,6 +111,7 @@ static D3DMATERIAL9 d3dmaterial;
static uint32 blendMap[] = { static uint32 blendMap[] = {
D3DBLEND_ZERO, // actually invalid
D3DBLEND_ZERO, D3DBLEND_ZERO,
D3DBLEND_ONE, D3DBLEND_ONE,
D3DBLEND_SRCCOLOR, D3DBLEND_SRCCOLOR,
@ -116,6 +132,7 @@ static uint32 alphafuncMap[] = {
}; };
static uint32 cullmodeMap[] = { static uint32 cullmodeMap[] = {
D3DCULL_NONE, // actually invalid
D3DCULL_NONE, D3DCULL_NONE,
D3DCULL_CW, D3DCULL_CW,
D3DCULL_CCW D3DCULL_CCW
@ -721,29 +738,13 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
BOOL icon = IsIconic(d3d9Globals.window); BOOL icon = IsIconic(d3d9Globals.window);
Raster *ras = cam->frameBuffer; Raster *ras = cam->frameBuffer;
if(!icon && if(!icon &&
(r.right != d3d9Globals.presentWidth || r.bottom != d3d9Globals.presentHeight)){ (r.right != d3d9Globals.present.BackBufferWidth || r.bottom != d3d9Globals.present.BackBufferHeight)){
releaseVidmemRasters(); releaseVidmemRasters();
D3DPRESENT_PARAMETERS d3dpp; d3d9Globals.present.BackBufferWidth = r.right;
d3dpp.BackBufferWidth = r.right; d3d9Globals.present.BackBufferHeight = r.bottom;
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;
// TODO: check result // TODO: check result
d3d::d3ddevice->Reset(&d3dpp); d3d::d3ddevice->Reset(&d3d9Globals.present);
d3d9Globals.presentWidth = r.right;
d3d9Globals.presentHeight = r.bottom;
resetD3d9Device(); resetD3d9Device();
} }
@ -760,82 +761,209 @@ showRaster(Raster *raster)
d3ddevice->Present(nil, nil, 0, nil); d3ddevice->Present(nil, nil, 0, nil);
} }
// taken from Frank Luna's d3d9 book
//
// Device
//
static int 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; HWND win = params->window;
bool windowed = true;
d3d9Globals.window = win; d3d9Globals.window = win;
d3d9Globals.windowed = windowed; d3d9Globals.numAdapters = 0;
d3d9Globals.modes = nil;
d3d9Globals.numModes = 0;
d3d9Globals.currentMode = 0;
HRESULT hr = 0; d3d9Globals.d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
IDirect3D9 *d3d9 = 0; if(d3d9Globals.d3d9 == nil){
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d9){
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed")); RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
return 0; return 0;
} }
D3DCAPS9 caps; d3d9Globals.numAdapters = d3d9Globals.d3d9->GetAdapterCount();
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); d3d9Globals.adapter = 0;
int vp = 0;
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
RECT rect; for(d3d9Globals.adapter = 0; d3d9Globals.adapter < d3d9Globals.numAdapters; d3d9Globals.adapter++)
GetClientRect(win, &rect); if(d3d9Globals.d3d9->GetDeviceCaps(d3d9Globals.adapter, D3DDEVTYPE_HAL, &d3d9Globals.caps) == D3D_OK)
int width = rect.right - rect.left; goto found;
int height = rect.bottom - rect.top; // no adapter
d3d9Globals.d3d9->Release();
d3d9Globals.d3d9 = nil;
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
return 0;
d3d9Globals.presentWidth = width; found:
d3d9Globals.presentHeight = height; makeVideoModeList();
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;
return 1; return 1;
} }
static int static int
closeD3D(void) closeD3D(void)
{ {
d3d::d3ddevice->Release(); d3d9Globals.d3d9->Release();
d3d::d3ddevice = nil; 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; return 1;
} }
@ -1027,6 +1155,9 @@ termD3D(void)
{ {
closeIm3D(); closeIm3D();
closeIm2D(); closeIm2D();
d3d::d3ddevice->Release();
d3d::d3ddevice = nil;
return 1; return 1;
} }
@ -1037,21 +1168,69 @@ finalizeD3D(void)
} }
static int static int
deviceSystem(DeviceReq req, void *arg0) deviceSystem(DeviceReq req, void *arg, int32 n)
{ {
D3DADAPTER_IDENTIFIER9 adapter;
VideoMode *rwmode;
switch(req){ switch(req){
case DEVICEOPEN: case DEVICEOPEN:
return openD3D((EngineStartParams*)arg0); return openD3D((EngineOpenParams*)arg);
case DEVICECLOSE: case DEVICECLOSE:
return closeD3D(); return closeD3D();
case DEVICEINIT: case DEVICEINIT:
return initD3D(); return startD3D() && initD3D();
case DEVICETERM: case DEVICETERM:
return termD3D(); return termD3D();
case DEVICEFINALIZE: case DEVICEFINALIZE:
return finalizeD3D(); 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; return 1;
} }

View File

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

View File

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

View File

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

View File

@ -99,9 +99,8 @@ Engine::init(void)
} }
// This is where RW allocates the engine and e.g. opens d3d // This is where RW allocates the engine and e.g. opens d3d
// TODO: this will probably take an argument with device specific data
bool32 bool32
Engine::open(void) Engine::open(EngineOpenParams *p)
{ {
if(engine || Engine::state != Initialized){ if(engine || Engine::state != Initialized){
RWERROR((ERR_ENGINEOPEN)); RWERROR((ERR_ENGINEOPEN));
@ -125,7 +124,8 @@ Engine::open(void)
engine->device = null::renderdevice; engine->device = null::renderdevice;
#endif #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 // TODO: init driver functions
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
@ -150,24 +150,22 @@ Engine::open(void)
} }
// This is where RW creates the actual rendering device // This is where RW creates the actual rendering device
// ans calls the engine plugin ctors // and calls the engine plugin ctors
bool32 bool32
Engine::start(EngineStartParams *p) Engine::start(void)
{ {
if(engine == nil || Engine::state != Opened){ if(engine == nil || Engine::state != Opened){
RWERROR((ERR_ENGINESTART)); RWERROR((ERR_ENGINESTART));
return 0; return 0;
} }
// TODO: put this into Open? engine->device.system(DEVICEINIT, nil, 0);
engine->device.system(DEVICEOPEN, (void*)p);
engine->device.system(DEVICEINIT, nil);
Engine::s_plglist.construct(engine); Engine::s_plglist.construct(engine);
for(uint i = 0; i < NUM_PLATFORMS; i++) for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].construct(rw::engine->driver[i]); Driver::s_plglist[i].construct(rw::engine->driver[i]);
engine->device.system(DEVICEFINALIZE, nil); engine->device.system(DEVICEFINALIZE, nil, 0);
Engine::state = Started; Engine::state = Started;
return 1; return 1;
@ -177,30 +175,100 @@ void
Engine::term(void) Engine::term(void)
{ {
// TODO // TODO
if(engine || Engine::state != Initialized){
RWERROR((ERR_GENERAL));
return;
}
Engine::state = Dead; Engine::state = Dead;
} }
void void
Engine::close(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++) for(uint i = 0; i < NUM_PLATFORMS; i++)
rwFree(rw::engine->driver[i]); rwFree(rw::engine->driver[i]);
rwFree(engine); rwFree(engine);
engine = nil;
Engine::state = Initialized; Engine::state = Initialized;
} }
void void
Engine::stop(void) Engine::stop(void)
{ {
engine->device.system(DEVICETERM, nil); if(engine == nil || Engine::state != Started){
engine->device.system(DEVICECLOSE, nil); RWERROR((ERR_GENERAL));
return;
}
engine->device.system(DEVICETERM, nil, 0);
for(uint i = 0; i < NUM_PLATFORMS; i++) for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].destruct(rw::engine->driver[i]); Driver::s_plglist[i].destruct(rw::engine->driver[i]);
Engine::s_plglist.destruct(engine); Engine::s_plglist.destruct(engine);
Engine::state = Opened; 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 { namespace null {
void beginUpdate(Camera*) { } void beginUpdate(Camera*) { }
@ -273,8 +341,16 @@ rasterToImage(Raster*)
} }
int 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; return 1;
} }

View File

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

View File

@ -330,21 +330,7 @@ Geometry::calculateBoundingSphere(void)
{ {
for(int32 i = 0; i < this->numMorphTargets; i++){ for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i]; MorphTarget *m = &this->morphTargets[i];
V3d min = { 1000000.0f, 1000000.0f, 1000000.0f }; m->boundingSphere = m->calculateBoundingSphere();
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);
} }
} }
@ -673,6 +659,29 @@ Geometry::removeUnusedMaterials(void)
rwFree(map); 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 // MaterialList
// //

View File

@ -26,6 +26,13 @@
namespace rw { namespace rw {
namespace gl3 { namespace gl3 {
struct DisplayMode
{
GLFWvidmode mode;
int32 depth;
uint32 flags;
};
struct GlGlobals struct GlGlobals
{ {
#ifdef LIBRW_SDL2 #ifdef LIBRW_SDL2
@ -33,8 +40,21 @@ struct GlGlobals
SDL_GLContext glcontext; SDL_GLContext glcontext;
#else #else
GLFWwindow *window; GLFWwindow *window;
GLFWmonitor *monitor;
int numMonitors;
int currentMonitor;
DisplayMode *modes;
int numModes;
int currentMode;
#endif #endif
int presentWidth, presentHeight; int presentWidth, presentHeight;
// for opening the window
int winWidth, winHeight;
const char *winTitle;
GLFWwindow **pWindow;
} glGlobals; } glGlobals;
struct UniformState struct UniformState
@ -119,6 +139,7 @@ static RwStateCache rwStateCache;
static int32 activeTexture; static int32 activeTexture;
static uint32 blendMap[] = { static uint32 blendMap[] = {
GL_ZERO, // actually invalid
GL_ZERO, GL_ZERO,
GL_ONE, GL_ONE,
GL_SRC_COLOR, GL_SRC_COLOR,
@ -728,10 +749,10 @@ beginUpdate(Camera *cam)
#ifdef LIBRW_SDL2 #ifdef LIBRW_SDL2
static int static int
openSDL2(EngineStartParams *startparams) openSDL2(EngineOpenParams *openparams)
{ {
if (!startparams){ if (!openparams){
RWERROR((ERR_GENERAL, "startparams invalid")); RWERROR((ERR_GENERAL, "openparams invalid"));
return 0; return 0;
} }
@ -752,9 +773,9 @@ openSDL2(EngineStartParams *startparams)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
int flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL; int flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL;
if (startparams->fullscreen) if (openparams->fullscreen)
flags |= SDL_WINDOW_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){ if(win == nil){
RWERROR((ERR_ENGINEOPEN, SDL_GetError())); RWERROR((ERR_ENGINEOPEN, SDL_GetError()));
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);
@ -781,7 +802,7 @@ openSDL2(EngineStartParams *startparams)
} }
glGlobals.window = win; glGlobals.window = win;
glGlobals.glcontext = ctx; glGlobals.glcontext = ctx;
*startparams->window = win; *openparams->window = win;
return 1; return 1;
} }
@ -794,11 +815,64 @@ closeSDL2(void)
return 1; return 1;
} }
#else #else
static int
openGLFW(EngineStartParams *startparams) static void
addVideoMode(const GLFWvidmode *mode)
{ {
GLenum status; int i;
GLFWwindow *win;
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 */ /* Init GLFW */
if(!glfwInit()){ if(!glfwInit()){
@ -811,20 +885,42 @@ openGLFW(EngineStartParams *startparams)
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 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){ if(win == nil){
RWERROR((ERR_GENERAL, "glfwCreateWindow() failed")); RWERROR((ERR_GENERAL, "glfwCreateWindow() failed"));
glfwTerminate();
return 0; 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); glfwMakeContextCurrent(win);
/* Init GLEW */ /* Init GLEW */
@ -833,25 +929,22 @@ openGLFW(EngineStartParams *startparams)
if(status != GLEW_OK){ if(status != GLEW_OK){
RWERROR((ERR_GENERAL, glewGetErrorString(status))); RWERROR((ERR_GENERAL, glewGetErrorString(status)));
glfwDestroyWindow(win); glfwDestroyWindow(win);
glfwTerminate();
return 0; return 0;
} }
if(!GLEW_VERSION_3_3){ if(!GLEW_VERSION_3_3){
RWERROR((ERR_GENERAL, "OpenGL 3.3 needed")); RWERROR((ERR_GENERAL, "OpenGL 3.3 needed"));
glfwDestroyWindow(win); glfwDestroyWindow(win);
glfwTerminate();
return 0; return 0;
} }
glGlobals.window = win; glGlobals.window = win;
*startparams->window = win; *glGlobals.pWindow = win;
return 1; return 1;
} }
static int static int
closeGLFW(void) stopGLFW(void)
{ {
glfwDestroyWindow(glGlobals.window); glfwDestroyWindow(glGlobals.window);
glfwTerminate();
return 1; return 1;
} }
#endif #endif
@ -925,34 +1018,105 @@ finalizeOpenGL(void)
return 1; return 1;
} }
#ifdef LIBRW_SDL2
static int static int
deviceSystem(DeviceReq req, void *arg0) deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
{ {
switch(req){ switch(req){
case DEVICEOPEN: case DEVICEOPEN:
#ifdef LIBRW_SDL2 return openSDL2((EngineOpenParams*)arg);
return openSDL2((EngineStartParams*)arg0);
#else
return openGLFW((EngineStartParams*)arg0);
#endif
case DEVICECLOSE: case DEVICECLOSE:
#ifdef LIBRW_SDL2
return closeSDL2(); return closeSDL2();
#else
return closeGLFW();
#endif
case DEVICEINIT: case DEVICEINIT:
return initOpenGL(); return initOpenGL();
case DEVICETERM: case DEVICETERM:
return termOpenGL(); return termOpenGL();
case DEVICEFINALIZE: // TODO: implement subsystems and video modes
return finalizeOpenGL();
default:
assert(0 && "not implemented");
return 0;
} }
return 1; 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 = { Device renderdevice = {
-1.0f, 1.0f, -1.0f, 1.0f,
gl3::beginUpdate, gl3::beginUpdate,
@ -968,7 +1132,11 @@ Device renderdevice = {
gl3::im3DTransform, gl3::im3DTransform,
gl3::im3DRenderIndexed, gl3::im3DRenderIndexed,
gl3::im3DEnd, 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? // TODO: set/check width, height, depth, format?
raster->flags |= Raster::DONTALLOCATE; raster->flags |= Raster::DONTALLOCATE;
break; break;
case Raster::NORMAL:
case Raster::TEXTURE: case Raster::TEXTURE:
// continue below // continue below
break; break;
@ -53,8 +54,6 @@ rasterCreate(Raster *raster)
if(raster->flags & Raster::DONTALLOCATE) if(raster->flags & Raster::DONTALLOCATE)
return; return;
assert(raster->type == Raster::TEXTURE);
#ifdef RW_OPENGL #ifdef RW_OPENGL
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset); Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
switch(raster->format & 0xF00){ switch(raster->format & 0xF00){

View File

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

View File

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

View File

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

View File

@ -2,22 +2,34 @@ namespace rw {
enum DeviceReq enum DeviceReq
{ {
// Device/Context creation
DEVICEOPEN,
// Device/Context shutdown
DEVICECLOSE,
// Device initialization before Engine/Driver plugins are opened // Device initialization before Engine/Driver plugins are opened
DEVICEINIT, DEVICEINIT,
// Device de-initialization after Engine/Driver plugins are closed // Device de-initialization after Engine/Driver plugins are closed
DEVICETERM, DEVICETERM,
// Device/Context creation
DEVICEOPEN,
// Device/Context shutdown
DEVICECLOSE,
// Device initialization after Engine/Driver plugins are opened // Device initialization after Engine/Driver plugins are opened
DEVICEFINALIZE DEVICEFINALIZE,
// TODO? counterpart to FINALIZE? // 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 Camera;
struct Image; struct Image;
@ -75,7 +87,7 @@ struct Driver
} }
}; };
struct EngineStartParams; struct EngineOpenParams;
enum MemHint enum MemHint
{ {
@ -101,6 +113,25 @@ struct MemoryFunctions
void *(*rwmustrealloc)(void *p, size_t sz, uint32 hint); 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 // This is for platform independent things
// TODO: move more stuff into this // TODO: move more stuff into this
struct Engine struct Engine
@ -124,12 +155,23 @@ struct Engine
static State state; static State state;
static bool32 init(void); static bool32 init(void);
static bool32 open(void); static bool32 open(EngineOpenParams*);
static bool32 start(EngineStartParams*); static bool32 start(void);
static void term(void); static void term(void);
static void close(void); static void close(void);
static void stop(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 PluginList s_plglist;
static int32 registerPlugin(int32 size, uint32 id, static int32 registerPlugin(int32 size, uint32 id,
Constructor ctor, Destructor dtor){ Constructor ctor, Destructor dtor){

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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