mirror of
https://github.com/aap/librw.git
synced 2024-11-25 13:15:43 +00:00
implemented im2d for d3d, fun little software T&L renderer
This commit is contained in:
parent
ea48c140c1
commit
c53d29b1cf
@ -17,10 +17,8 @@ InitRW(void)
|
|||||||
return false;
|
return false;
|
||||||
if(!rw::Engine::start(&engineStartParams))
|
if(!rw::Engine::start(&engineStartParams))
|
||||||
return false;
|
return false;
|
||||||
rw::engine->loadTextures = 1;
|
|
||||||
|
|
||||||
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
|
rw::Image::setSearchPath("./");
|
||||||
rw::Image::setSearchPath(".");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +127,20 @@ MakeWindow(HINSTANCE instance, int width, int height, const char *title)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int offx = 100;
|
||||||
|
int offy = 100;
|
||||||
|
RECT rect;
|
||||||
|
rect.left = 0;
|
||||||
|
rect.top = 0;
|
||||||
|
rect.right = width;
|
||||||
|
rect.bottom = height;
|
||||||
|
DWORD style = WS_OVERLAPPEDWINDOW;
|
||||||
|
AdjustWindowRect(&rect, style, FALSE);
|
||||||
|
rect.right += -rect.left;
|
||||||
|
rect.bottom += -rect.top;
|
||||||
HWND win;
|
HWND win;
|
||||||
win = CreateWindow("librwD3D9", title,
|
win = CreateWindow("librwD3D9", title, style,
|
||||||
WS_BORDER | WS_CAPTION | WS_SYSMENU |
|
offx, offy, rect.right, rect.bottom, 0, 0, instance, 0);
|
||||||
WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|
|
||||||
0, 0, width, height, 0, 0, instance, 0);
|
|
||||||
if(!win){
|
if(!win){
|
||||||
MessageBox(0, "CreateWindow() - FAILED", 0, 0);
|
MessageBox(0, "CreateWindow() - FAILED", 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -284,6 +284,9 @@ Camera::create(void)
|
|||||||
cam->fogPlane = 5.0f;
|
cam->fogPlane = 5.0f;
|
||||||
cam->projection = Camera::PERSPECTIVE;
|
cam->projection = Camera::PERSPECTIVE;
|
||||||
|
|
||||||
|
cam->frameBuffer = nil;
|
||||||
|
cam->zBuffer = nil;
|
||||||
|
|
||||||
// clump extension
|
// clump extension
|
||||||
cam->clump = nil;
|
cam->clump = nil;
|
||||||
cam->inClump.init();
|
cam->inClump.init();
|
||||||
@ -315,6 +318,10 @@ Camera::clone(void)
|
|||||||
cam->farPlane = this->farPlane;
|
cam->farPlane = this->farPlane;
|
||||||
cam->fogPlane = this->fogPlane;
|
cam->fogPlane = this->fogPlane;
|
||||||
cam->projection = this->projection;
|
cam->projection = this->projection;
|
||||||
|
|
||||||
|
cam->frameBuffer = this->frameBuffer;
|
||||||
|
cam->zBuffer = this->zBuffer;
|
||||||
|
|
||||||
s_plglist.copy(cam, this);
|
s_plglist.copy(cam, this);
|
||||||
return cam;
|
return cam;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "../rwobjects.h"
|
#include "../rwobjects.h"
|
||||||
#include "../rwengine.h"
|
#include "../rwengine.h"
|
||||||
#include "rwd3d.h"
|
#include "rwd3d.h"
|
||||||
|
#include "rwd3dimpl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 0
|
#define PLUGIN_ID 0
|
||||||
|
|
||||||
@ -275,6 +276,7 @@ setRasterStage(uint32 stage, Raster *raster)
|
|||||||
void
|
void
|
||||||
setTexture(uint32 stage, Texture *tex)
|
setTexture(uint32 stage, Texture *tex)
|
||||||
{
|
{
|
||||||
|
// TODO: support mipmaps
|
||||||
static DWORD filternomip[] = {
|
static DWORD filternomip[] = {
|
||||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||||
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||||
@ -289,10 +291,10 @@ setTexture(uint32 stage, Texture *tex)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(tex->raster){
|
if(tex->raster){
|
||||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->getFilter()]);
|
||||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->getFilter()]);
|
||||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[tex->getAddressU()]);
|
||||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[tex->getAddressV()]);
|
||||||
}
|
}
|
||||||
setRasterStage(stage, tex->raster);
|
setRasterStage(stage, tex->raster);
|
||||||
}
|
}
|
||||||
@ -528,6 +530,14 @@ initD3D(void)
|
|||||||
// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
|
// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
|
||||||
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
|
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
|
||||||
|
|
||||||
|
openIm2D();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
finalizeD3D(void)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,6 +549,8 @@ deviceSystem(DeviceReq req, void *arg0)
|
|||||||
return startD3D((EngineStartParams*)arg0);
|
return startD3D((EngineStartParams*)arg0);
|
||||||
case DEVICEINIT:
|
case DEVICEINIT:
|
||||||
return initD3D();
|
return initD3D();
|
||||||
|
case DEVICEFINALIZE:
|
||||||
|
return finalizeD3D();
|
||||||
case DEVICESTOP:
|
case DEVICESTOP:
|
||||||
return stopD3D();
|
return stopD3D();
|
||||||
}
|
}
|
||||||
@ -553,7 +565,7 @@ Device renderdevice = {
|
|||||||
d3d::showRaster,
|
d3d::showRaster,
|
||||||
d3d::setRwRenderState,
|
d3d::setRwRenderState,
|
||||||
d3d::getRwRenderState,
|
d3d::getRwRenderState,
|
||||||
null::im2DRenderIndexedPrimitive,
|
d3d::im2DRenderIndexedPrimitive,
|
||||||
d3d::deviceSystem,
|
d3d::deviceSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
102
src/d3d/d3dim2d.cpp
Normal file
102
src/d3d/d3dim2d.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "../rwbase.h"
|
||||||
|
#include "../rwplg.h"
|
||||||
|
#include "../rwpipeline.h"
|
||||||
|
#include "../rwobjects.h"
|
||||||
|
#include "../rwengine.h"
|
||||||
|
#include "rwd3d.h"
|
||||||
|
#include "rwd3d9.h"
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace d3d {
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
|
||||||
|
// might want to tweak this
|
||||||
|
#define NUMINDICES 10000
|
||||||
|
#define NUMVERTICES 10000
|
||||||
|
|
||||||
|
static int primTypeMap[] = {
|
||||||
|
D3DPT_POINTLIST, // invalid
|
||||||
|
D3DPT_LINELIST,
|
||||||
|
D3DPT_LINESTRIP,
|
||||||
|
D3DPT_TRIANGLELIST,
|
||||||
|
D3DPT_TRIANGLESTRIP,
|
||||||
|
D3DPT_TRIANGLEFAN,
|
||||||
|
D3DPT_POINTLIST, // actually not supported!
|
||||||
|
};
|
||||||
|
|
||||||
|
static IDirect3DVertexDeclaration9 *im2ddecl;
|
||||||
|
static IDirect3DVertexBuffer9 *im2dvertbuf;
|
||||||
|
static IDirect3DIndexBuffer9 *im2dindbuf;
|
||||||
|
|
||||||
|
void
|
||||||
|
openIm2D(void)
|
||||||
|
{
|
||||||
|
D3DVERTEXELEMENT9 elements[4] = {
|
||||||
|
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
|
||||||
|
{ 0, offsetof(Im2DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
|
||||||
|
{ 0, offsetof(Im2DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||||
|
D3DDECL_END()
|
||||||
|
};
|
||||||
|
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im2ddecl);
|
||||||
|
im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, D3DPOOL_MANAGED);
|
||||||
|
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||||
|
void *vertices, int32 numVertices, void *indices, int32 numIndices)
|
||||||
|
{
|
||||||
|
if(numVertices > NUMVERTICES ||
|
||||||
|
numIndices > NUMINDICES){
|
||||||
|
// TODO: error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), 0);
|
||||||
|
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
|
||||||
|
unlockIndices(im2dindbuf);
|
||||||
|
|
||||||
|
uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_NOSYSLOCK);
|
||||||
|
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex));
|
||||||
|
unlockVertices(im2dvertbuf);
|
||||||
|
|
||||||
|
d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
|
||||||
|
d3ddevice->SetIndices(im2dindbuf);
|
||||||
|
d3ddevice->SetVertexDeclaration(im2ddecl);
|
||||||
|
d3d::setTexture(0, engine->imtexture);
|
||||||
|
d3d::flushCache();
|
||||||
|
|
||||||
|
uint32 primCount = 0;
|
||||||
|
switch(primType){
|
||||||
|
case PRIMTYPELINELIST:
|
||||||
|
primCount = numIndices/2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPEPOLYLINE:
|
||||||
|
primCount = numIndices-1;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRILIST:
|
||||||
|
primCount = numIndices/3;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRISTRIP:
|
||||||
|
primCount = numIndices-2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRIFAN:
|
||||||
|
primCount = numIndices-2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPEPOINTLIST:
|
||||||
|
primCount = numIndices;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
|
||||||
|
0, numVertices,
|
||||||
|
0, primCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,24 @@ extern IDirect3DDevice9 *d3ddevice;
|
|||||||
extern Device renderdevice;
|
extern Device renderdevice;
|
||||||
|
|
||||||
void lightingCB(void);
|
void lightingCB(void);
|
||||||
|
|
||||||
|
struct Im2DVertex
|
||||||
|
{
|
||||||
|
float32 x, y, z;
|
||||||
|
float32 w;
|
||||||
|
D3DCOLOR color;
|
||||||
|
float32 u, v;
|
||||||
|
|
||||||
|
void setScreenX(float32 x) { this->x = x; }
|
||||||
|
void setScreenY(float32 y) { this->y = y; }
|
||||||
|
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 setU(float32 u) { this->u = u; }
|
||||||
|
void setV(float32 v) { this->v = v; }
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
enum {
|
enum {
|
||||||
D3DLOCK_NOSYSLOCK = 0, // ignored
|
D3DLOCK_NOSYSLOCK = 0, // ignored
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
namespace d3d {
|
namespace d3d {
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
void openIm2D(void);
|
||||||
|
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||||
|
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||||
|
#endif
|
||||||
|
|
||||||
void rasterCreate(Raster *raster);
|
void rasterCreate(Raster *raster);
|
||||||
uint8 *rasterLock(Raster *raster, int32 level);
|
uint8 *rasterLock(Raster *raster, int32 level);
|
||||||
void rasterUnlock(Raster *raster, int32 level);
|
void rasterUnlock(Raster *raster, int32 level);
|
||||||
|
@ -41,7 +41,7 @@ void *mustmalloc_h(size_t sz, uint32 hint)
|
|||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
ret = rwMalloc(sz, hint);
|
ret = rwMalloc(sz, hint);
|
||||||
if(ret)
|
if(ret || sz == 0)
|
||||||
return ret;
|
return ret;
|
||||||
fprintf(stderr, "Error: out of memory\n");
|
fprintf(stderr, "Error: out of memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -51,7 +51,7 @@ void *mustrealloc_h(void *p, size_t sz, uint32 hint)
|
|||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
ret = rwRealloc(p, sz, hint);
|
ret = rwRealloc(p, sz, hint);
|
||||||
if(ret)
|
if(ret || sz == 0)
|
||||||
return ret;
|
return ret;
|
||||||
fprintf(stderr, "Error: out of memory\n");
|
fprintf(stderr, "Error: out of memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -83,7 +83,8 @@ Engine::init(void)
|
|||||||
Engine::s_plglist.last = nil;
|
Engine::s_plglist.last = nil;
|
||||||
|
|
||||||
// core plugin attach here
|
// core plugin attach here
|
||||||
Engine::registerPlugin(0, ID_FRAMEMODULE, Frame::_open, Frame::_close);
|
Frame::registerModule();
|
||||||
|
Texture::registerModule();
|
||||||
|
|
||||||
// driver plugin attach
|
// driver plugin attach
|
||||||
ps2::registerPlatformPlugins();
|
ps2::registerPlatformPlugins();
|
||||||
@ -111,10 +112,7 @@ Engine::open(void)
|
|||||||
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
||||||
engine->currentCamera = nil;
|
engine->currentCamera = nil;
|
||||||
engine->currentWorld = nil;
|
engine->currentWorld = nil;
|
||||||
engine->currentTexDictionary = nil;
|
|
||||||
engine->imtexture = nil;
|
engine->imtexture = nil;
|
||||||
engine->loadTextures = 1;
|
|
||||||
engine->makeDummies = 1;
|
|
||||||
|
|
||||||
// Initialize device
|
// Initialize device
|
||||||
// Device and possibly OS specific!
|
// Device and possibly OS specific!
|
||||||
@ -177,10 +175,7 @@ void
|
|||||||
Engine::term(void)
|
Engine::term(void)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
Engine::state = Dead;
|
||||||
Driver::s_plglist[i].destruct(rw::engine->driver[i]);
|
|
||||||
Engine::s_plglist.destruct(engine);
|
|
||||||
Engine::state = Opened;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -197,7 +192,10 @@ void
|
|||||||
Engine::stop(void)
|
Engine::stop(void)
|
||||||
{
|
{
|
||||||
engine->device.system(DEVICESTOP, nil);
|
engine->device.system(DEVICESTOP, nil);
|
||||||
Engine::state = Dead;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace null {
|
namespace null {
|
||||||
|
@ -13,10 +13,14 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
|
PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
|
||||||
void *Frame::_open(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); return object; }
|
static void *frameOpen(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); return object; }
|
||||||
void *Frame::_close(void *object, int32 offset, int32 size) { return object; }
|
static void *frameClose(void *object, int32 offset, int32 size) { return object; }
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Frame::registerModule(void)
|
||||||
|
{
|
||||||
|
Engine::registerPlugin(0, ID_FRAMEMODULE, frameOpen, frameClose);
|
||||||
|
}
|
||||||
|
|
||||||
Frame*
|
Frame*
|
||||||
Frame::create(void)
|
Frame::create(void)
|
||||||
|
@ -70,7 +70,6 @@ static UniformObject uniformObject;
|
|||||||
int32 u_matColor;
|
int32 u_matColor;
|
||||||
int32 u_surfaceProps;
|
int32 u_surfaceProps;
|
||||||
|
|
||||||
|
|
||||||
Shader *simpleShader;
|
Shader *simpleShader;
|
||||||
|
|
||||||
static bool32 stateDirty = 1;
|
static bool32 stateDirty = 1;
|
||||||
@ -304,6 +303,17 @@ setActiveTexture(int32 n)
|
|||||||
void
|
void
|
||||||
setTexture(int32 n, Texture *tex)
|
setTexture(int32 n, Texture *tex)
|
||||||
{
|
{
|
||||||
|
// TODO: support mipmaps
|
||||||
|
static GLint filternomip[] = {
|
||||||
|
0, GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR
|
||||||
|
};
|
||||||
|
|
||||||
|
static GLint wrap[] = {
|
||||||
|
0, GL_REPEAT, GL_MIRRORED_REPEAT,
|
||||||
|
GL_CLAMP, GL_CLAMP_TO_BORDER
|
||||||
|
};
|
||||||
bool32 alpha;
|
bool32 alpha;
|
||||||
setActiveTexture(GL_TEXTURE0+n);
|
setActiveTexture(GL_TEXTURE0+n);
|
||||||
if(tex == nil || tex->raster->platform != PLATFORM_GL3 ||
|
if(tex == nil || tex->raster->platform != PLATFORM_GL3 ||
|
||||||
@ -315,6 +325,13 @@ setTexture(int32 n, Texture *tex)
|
|||||||
nativeRasterOffset);
|
nativeRasterOffset);
|
||||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
||||||
alpha = natras->hasAlpha;
|
alpha = natras->hasAlpha;
|
||||||
|
if(tex->filterAddressing != natras->filterAddressing){
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filternomip[tex->getFilter()]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filternomip[tex->getFilter()]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap[tex->getAddressU()]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap[tex->getAddressV()]);
|
||||||
|
natras->filterAddressing = tex->filterAddressing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n == 0){
|
if(n == 0){
|
||||||
@ -518,25 +535,6 @@ initOpenGL(void)
|
|||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
|
||||||
glGenTextures(1, &whitetex);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
|
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
|
||||||
|
|
||||||
im2DInit();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
finalizeOpenGL(void)
|
|
||||||
{
|
|
||||||
#include "shaders/simple_gl3.inc"
|
|
||||||
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
|
|
||||||
|
|
||||||
glGenBuffers(1, &ubo_state);
|
glGenBuffers(1, &ubo_state);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
|
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
|
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
|
||||||
@ -558,6 +556,25 @@ finalizeOpenGL(void)
|
|||||||
GL_DYNAMIC_DRAW);
|
GL_DYNAMIC_DRAW);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
|
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
glGenTextures(1, &whitetex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
||||||
|
|
||||||
|
#include "shaders/simple_gl3.inc"
|
||||||
|
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
|
||||||
|
|
||||||
|
openIm2D();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
finalizeOpenGL(void)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,19 +16,20 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
namespace gl3 {
|
namespace gl3 {
|
||||||
|
|
||||||
uint32 im2DVbo, im2DIbo;
|
static uint32 im2DVbo, im2DIbo;
|
||||||
|
static int32 u_xform;
|
||||||
|
|
||||||
#define STARTINDICES 1024
|
#define STARTINDICES 10000
|
||||||
#define STARTVERTICES 1024
|
#define STARTVERTICES 10000
|
||||||
|
|
||||||
static Shader *im2dShader;
|
static Shader *im2dShader;
|
||||||
static AttribDesc attribDesc[3] = {
|
static AttribDesc attribDesc[3] = {
|
||||||
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 3,
|
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 4,
|
||||||
sizeof(Im2DVertex), 0 },
|
sizeof(Im2DVertex), 0 },
|
||||||
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||||
sizeof(Im2DVertex), offsetof(Im2DVertex, r) },
|
sizeof(Im2DVertex), offsetof(Im2DVertex, r) },
|
||||||
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||||
sizeof(Im2DVertex), offsetof(Im2DVertex, r) },
|
sizeof(Im2DVertex), offsetof(Im2DVertex, u) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int primTypeMap[] = {
|
static int primTypeMap[] = {
|
||||||
@ -42,8 +43,10 @@ static int primTypeMap[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
im2DInit(void)
|
openIm2D(void)
|
||||||
{
|
{
|
||||||
|
u_xform = registerUniform("u_xform");
|
||||||
|
|
||||||
#include "shaders/im2d_gl3.inc"
|
#include "shaders/im2d_gl3.inc"
|
||||||
im2dShader = Shader::fromStrings(im2d_vert_src, im2d_frag_src);
|
im2dShader = Shader::fromStrings(im2d_vert_src, im2d_frag_src);
|
||||||
|
|
||||||
@ -65,6 +68,11 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||||||
void *vertices, int32 numVertices,
|
void *vertices, int32 numVertices,
|
||||||
void *indices, int32 numIndices)
|
void *indices, int32 numIndices)
|
||||||
{
|
{
|
||||||
|
GLfloat xform[4];
|
||||||
|
Camera *cam;
|
||||||
|
cam = (Camera*)engine->currentCamera;
|
||||||
|
|
||||||
|
// TODO: fixed size
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
||||||
indices, GL_DYNAMIC_DRAW);
|
indices, GL_DYNAMIC_DRAW);
|
||||||
@ -73,9 +81,15 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||||||
glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex),
|
glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex),
|
||||||
vertices, GL_DYNAMIC_DRAW);
|
vertices, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
setAttribPointers(attribDesc, 3);
|
xform[0] = 2.0f/cam->frameBuffer->width;
|
||||||
im2dShader->use();
|
xform[1] = -2.0f/cam->frameBuffer->height;
|
||||||
|
xform[2] = -1.0f;
|
||||||
|
xform[3] = 1.0f;
|
||||||
|
|
||||||
|
im2dShader->use();
|
||||||
|
setAttribPointers(attribDesc, 3);
|
||||||
|
|
||||||
|
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||||
setTexture(0, engine->imtexture);
|
setTexture(0, engine->imtexture);
|
||||||
|
|
||||||
flushCache();
|
flushCache();
|
||||||
|
@ -23,9 +23,27 @@ int32 nativeRasterOffset;
|
|||||||
void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
|
switch(raster->type){
|
||||||
|
case Raster::CAMERA:
|
||||||
|
// TODO: set/check width, height, depth, format?
|
||||||
|
raster->flags |= Raster::DONTALLOCATE;
|
||||||
|
break;
|
||||||
|
case Raster::ZBUFFER:
|
||||||
|
// TODO: set/check width, height, depth, format?
|
||||||
|
raster->flags |= Raster::DONTALLOCATE;
|
||||||
|
break;
|
||||||
|
case Raster::TEXTURE:
|
||||||
|
// continue below
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "unsupported format");
|
||||||
|
}
|
||||||
|
|
||||||
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){
|
||||||
@ -54,11 +72,10 @@ rasterCreate(Raster *raster)
|
|||||||
|
|
||||||
glGenTextures(1, &natras->texid);
|
glGenTextures(1, &natras->texid);
|
||||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
||||||
raster->width, raster->height,
|
raster->width, raster->height,
|
||||||
0, natras->format, natras->type, nil);
|
0, natras->format, natras->type, nil);
|
||||||
|
natras->filterAddressing = ~0;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,11 +78,23 @@ struct InstanceDataHeader : rw::InstanceDataHeader
|
|||||||
InstanceData *inst;
|
InstanceData *inst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef RW_GL3
|
||||||
|
|
||||||
struct Im2DVertex
|
struct Im2DVertex
|
||||||
{
|
{
|
||||||
float32 x, y, z;
|
float32 x, y, z, w;
|
||||||
uint8 r, g, b, a;
|
uint8 r, g, b, a;
|
||||||
float32 u, v;
|
float32 u, v;
|
||||||
|
|
||||||
|
void setScreenX(float32 x) { this->x = x; }
|
||||||
|
void setScreenY(float32 y) { this->y = y; }
|
||||||
|
void setScreenZ(float32 z) { this->z = z; }
|
||||||
|
void setCameraZ(float32 z) { this->w = z; }
|
||||||
|
void setRecipCameraZ(float32 recipz) { }
|
||||||
|
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) {
|
||||||
|
this->r = r; this->g = g; this->b = b; this->a = a; }
|
||||||
|
void setU(float32 u) { this->u = u; }
|
||||||
|
void setV(float32 v) { this->v = v; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void setAttribPointers(AttribDesc *attribDescs, int32 numAttribs);
|
void setAttribPointers(AttribDesc *attribDescs, int32 numAttribs);
|
||||||
@ -105,6 +117,8 @@ void setTexture(int32 n, Texture *tex);
|
|||||||
|
|
||||||
void flushCache(void);
|
void flushCache(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class ObjPipeline : public rw::ObjPipeline
|
class ObjPipeline : public rw::ObjPipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -136,6 +150,8 @@ struct Gl3Raster
|
|||||||
uint32 texid;
|
uint32 texid;
|
||||||
|
|
||||||
bool32 hasAlpha;
|
bool32 hasAlpha;
|
||||||
|
// cached filtermode and addressing
|
||||||
|
uint32 filterAddressing;
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerNativeRaster(void);
|
void registerNativeRaster(void);
|
||||||
|
@ -5,7 +5,7 @@ namespace gl3 {
|
|||||||
|
|
||||||
extern Shader *simpleShader;
|
extern Shader *simpleShader;
|
||||||
extern uint32 im2DVbo, im2DIbo;
|
extern uint32 im2DVbo, im2DIbo;
|
||||||
void im2DInit(void);
|
void openIm2D(void);
|
||||||
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||||
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
layout(std140) uniform Im2DState
|
//layout(std140) uniform Im2DState
|
||||||
{
|
//{
|
||||||
int u_alphaTest;
|
// int u_alphaTest;
|
||||||
float u_alphaRef;
|
// float u_alphaRef;
|
||||||
mat4 u_xform;
|
// mat4 u_xform;
|
||||||
};
|
//};
|
||||||
|
|
||||||
layout(location = 0) in vec3 in_pos;
|
uniform vec4 u_xform;
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 in_pos;
|
||||||
layout(location = 2) in vec4 in_color;
|
layout(location = 2) in vec4 in_color;
|
||||||
layout(location = 3) in vec2 in_tex0;
|
layout(location = 3) in vec2 in_tex0;
|
||||||
|
|
||||||
@ -17,7 +19,9 @@ out vec2 v_tex0;
|
|||||||
void
|
void
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
gl_Position = vec4(in_pos, 1.0);
|
gl_Position = in_pos;
|
||||||
|
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
|
||||||
|
gl_Position.xyz *= gl_Position.w;
|
||||||
v_color = in_color;
|
v_color = in_color;
|
||||||
v_tex0 = in_tex0;
|
v_tex0 = in_tex0;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
const char *im2d_vert_src =
|
const char *im2d_vert_src =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
|
|
||||||
"layout(std140) uniform Im2DState\n"
|
"//layout(std140) uniform Im2DState\n"
|
||||||
"{\n"
|
"//{\n"
|
||||||
" int u_alphaTest;\n"
|
"// int u_alphaTest;\n"
|
||||||
" float u_alphaRef;\n"
|
"// float u_alphaRef;\n"
|
||||||
" mat4 u_xform;\n"
|
"// mat4 u_xform;\n"
|
||||||
"};\n"
|
"//};\n"
|
||||||
|
|
||||||
"layout(location = 0) in vec3 in_pos;\n"
|
"uniform vec4 u_xform;\n"
|
||||||
|
|
||||||
|
"layout(location = 0) in vec4 in_pos;\n"
|
||||||
"layout(location = 2) in vec4 in_color;\n"
|
"layout(location = 2) in vec4 in_color;\n"
|
||||||
"layout(location = 3) in vec2 in_tex0;\n"
|
"layout(location = 3) in vec2 in_tex0;\n"
|
||||||
|
|
||||||
@ -18,7 +20,9 @@ const char *im2d_vert_src =
|
|||||||
"void\n"
|
"void\n"
|
||||||
"main(void)\n"
|
"main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = vec4(in_pos, 1.0);\n"
|
" gl_Position = in_pos;\n"
|
||||||
|
" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
|
||||||
|
" gl_Position.xyz *= gl_Position.w;\n"
|
||||||
" v_color = in_color;\n"
|
" v_color = in_color;\n"
|
||||||
" v_tex0 = in_tex0;\n"
|
" v_tex0 = in_tex0;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
28
src/rwbase.h
28
src/rwbase.h
@ -8,6 +8,19 @@
|
|||||||
|
|
||||||
#ifdef RW_GL3
|
#ifdef RW_GL3
|
||||||
#define RW_OPENGL
|
#define RW_OPENGL
|
||||||
|
#define RWDEVICE gl3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
#define RWDEVICE d3d
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RW_D3D8
|
||||||
|
#define RWDEVICE d3d
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RW_PS2
|
||||||
|
#define RWDEVICE ps2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RW_WDGL
|
#ifdef RW_WDGL
|
||||||
@ -64,7 +77,21 @@ struct RGBAf
|
|||||||
float32 blue;
|
float32 blue;
|
||||||
float32 alpha;
|
float32 alpha;
|
||||||
};
|
};
|
||||||
|
inline RGBAf makeRGBAf(float32 r, float32 g, float32 b, float32 a) { RGBAf c = { r, g, b, a }; return c; }
|
||||||
inline bool32 equal(const RGBAf &c1, const RGBAf &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; }
|
inline bool32 equal(const RGBAf &c1, const RGBAf &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; }
|
||||||
|
inline RGBAf add(const RGBAf &a, const RGBAf &b) { return makeRGBAf(a.red+b.red, a.green+b.green, a.blue+b.blue, a.alpha+b.alpha); }
|
||||||
|
inline RGBAf modulate(const RGBAf &a, const RGBAf &b) { return makeRGBAf(a.red*b.red, a.green*b.green, a.blue*b.blue, a.alpha*b.alpha); }
|
||||||
|
inline RGBAf scale(const RGBAf &a, float32 f) { return makeRGBAf(a.red*f, a.green*f, a.blue*f, a.alpha*f); }
|
||||||
|
inline void clamp(RGBAf *a) {
|
||||||
|
if(a->red > 1.0f) a->red = 1.0f;
|
||||||
|
if(a->red < 0.0f) a->red = 0.0f;
|
||||||
|
if(a->green > 1.0f) a->green = 1.0f;
|
||||||
|
if(a->green < 0.0f) a->green = 0.0f;
|
||||||
|
if(a->blue > 1.0f) a->blue = 1.0f;
|
||||||
|
if(a->blue < 0.0f) a->blue = 0.0f;
|
||||||
|
if(a->alpha > 1.0f) a->alpha = 1.0f;
|
||||||
|
if(a->alpha < 0.0f) a->alpha = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
inline void convColor(RGBA *i, RGBAf *f){
|
inline void convColor(RGBA *i, RGBAf *f){
|
||||||
int32 c;
|
int32 c;
|
||||||
@ -467,6 +494,7 @@ enum CoreModuleID
|
|||||||
{
|
{
|
||||||
ID_NAMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x00),
|
ID_NAMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x00),
|
||||||
ID_FRAMEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x03),
|
ID_FRAMEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x03),
|
||||||
|
ID_TEXTUREMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x08),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ECODE(c, s) c,
|
#define ECODE(c, s) c,
|
||||||
|
@ -135,11 +135,6 @@ struct Engine
|
|||||||
Texture *imtexture;
|
Texture *imtexture;
|
||||||
LinkList frameDirtyList;
|
LinkList frameDirtyList;
|
||||||
|
|
||||||
TexDictionary *currentTexDictionary;
|
|
||||||
// load textures from files
|
|
||||||
bool32 loadTextures;
|
|
||||||
// create dummy textures to store just names
|
|
||||||
bool32 makeDummies;
|
|
||||||
// Dynamically allocated because of plugins
|
// Dynamically allocated because of plugins
|
||||||
Driver *driver[NUM_PLATFORMS];
|
Driver *driver[NUM_PLATFORMS];
|
||||||
Device device;
|
Device device;
|
||||||
@ -170,6 +165,9 @@ inline void SetRenderState(int32 state, uint32 value){
|
|||||||
inline uint32 GetRenderState(int32 state){
|
inline uint32 GetRenderState(int32 state){
|
||||||
return engine->device.getRenderState(state); }
|
return engine->device.getRenderState(state); }
|
||||||
|
|
||||||
|
inline float32 GetNearZ(void) { return engine->device.zNear; }
|
||||||
|
inline float32 GetFarZ(void) { return engine->device.zNear; }
|
||||||
|
|
||||||
// These must be macros because we might want to pass __FILE__ and __LINE__ later
|
// These must be macros because we might want to pass __FILE__ and __LINE__ later
|
||||||
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
|
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
|
||||||
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
|
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
|
||||||
|
@ -137,8 +137,7 @@ struct Frame
|
|||||||
void purgeClone(void);
|
void purgeClone(void);
|
||||||
|
|
||||||
#ifndef RWPUBLIC
|
#ifndef RWPUBLIC
|
||||||
static void *_open(void*, int32, int32);
|
static void registerModule(void);
|
||||||
static void *_close(void*, int32, int32);
|
|
||||||
#endif
|
#endif
|
||||||
static void syncDirty(void);
|
static void syncDirty(void);
|
||||||
};
|
};
|
||||||
@ -282,30 +281,6 @@ struct TexDictionary;
|
|||||||
|
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
PLUGINBASE
|
|
||||||
Raster *raster;
|
|
||||||
TexDictionary *dict;
|
|
||||||
LLLink inDict;
|
|
||||||
char name[32];
|
|
||||||
char mask[32];
|
|
||||||
uint32 filterAddressing; // VVVVUUUU FFFFFFFF
|
|
||||||
int32 refCount;
|
|
||||||
|
|
||||||
static Texture *create(Raster *raster);
|
|
||||||
void destroy(void);
|
|
||||||
static Texture *fromDict(LLLink *lnk){
|
|
||||||
return LLLinkGetData(lnk, Texture, inDict); }
|
|
||||||
static Texture *streamRead(Stream *stream);
|
|
||||||
bool streamWrite(Stream *stream);
|
|
||||||
uint32 streamGetSize(void);
|
|
||||||
static Texture *read(const char *name, const char *mask);
|
|
||||||
static Texture *streamReadNative(Stream *stream);
|
|
||||||
void streamWriteNative(Stream *stream);
|
|
||||||
uint32 streamGetSizeNative(void);
|
|
||||||
|
|
||||||
static Texture *(*findCB)(const char *name);
|
|
||||||
static Texture *(*readCB)(const char *name, const char *mask);
|
|
||||||
|
|
||||||
enum FilterMode {
|
enum FilterMode {
|
||||||
NEAREST = 1,
|
NEAREST = 1,
|
||||||
LINEAR,
|
LINEAR,
|
||||||
@ -320,6 +295,40 @@ struct Texture
|
|||||||
CLAMP,
|
CLAMP,
|
||||||
BORDER
|
BORDER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PLUGINBASE
|
||||||
|
Raster *raster;
|
||||||
|
TexDictionary *dict;
|
||||||
|
LLLink inDict;
|
||||||
|
char name[32];
|
||||||
|
char mask[32];
|
||||||
|
uint32 filterAddressing; // VVVVUUUU FFFFFFFF
|
||||||
|
int32 refCount;
|
||||||
|
|
||||||
|
static Texture *create(Raster *raster);
|
||||||
|
void destroy(void);
|
||||||
|
static Texture *fromDict(LLLink *lnk){
|
||||||
|
return LLLinkGetData(lnk, Texture, inDict); }
|
||||||
|
FilterMode getFilter(void) { return (FilterMode)(filterAddressing & 0xFF); }
|
||||||
|
void setFilter(FilterMode f) { filterAddressing = filterAddressing & ~0xFF | f; }
|
||||||
|
Addressing getAddressU(void) { return (Addressing)((filterAddressing >> 8) & 0xF); }
|
||||||
|
Addressing getAddressV(void) { return (Addressing)((filterAddressing >> 12) & 0xF); }
|
||||||
|
void setAddressU(Addressing u) { filterAddressing = filterAddressing & ~0xF00 | u<<8; }
|
||||||
|
void setAddressV(Addressing v) { filterAddressing = filterAddressing & ~0xF000 | v<<12; }
|
||||||
|
static Texture *streamRead(Stream *stream);
|
||||||
|
bool streamWrite(Stream *stream);
|
||||||
|
uint32 streamGetSize(void);
|
||||||
|
static Texture *read(const char *name, const char *mask);
|
||||||
|
static Texture *streamReadNative(Stream *stream);
|
||||||
|
void streamWriteNative(Stream *stream);
|
||||||
|
uint32 streamGetSizeNative(void);
|
||||||
|
|
||||||
|
static Texture *(*findCB)(const char *name);
|
||||||
|
static Texture *(*readCB)(const char *name, const char *mask);
|
||||||
|
|
||||||
|
#ifndef RWPUBLIC
|
||||||
|
static void registerModule(void);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -624,12 +633,15 @@ struct Camera
|
|||||||
V3d frustumCorners[8];
|
V3d frustumCorners[8];
|
||||||
BBox frustumBoundBox;
|
BBox frustumBoundBox;
|
||||||
|
|
||||||
|
Raster *frameBuffer;
|
||||||
|
Raster *zBuffer;
|
||||||
|
|
||||||
// clump link handled by plugin in RW
|
// clump link handled by plugin in RW
|
||||||
Clump *clump;
|
Clump *clump;
|
||||||
LLLink inClump;
|
LLLink inClump;
|
||||||
|
|
||||||
// world extension
|
// world extension
|
||||||
/* 3 unknowns */
|
/* RW: frustum sectors, space, position */
|
||||||
World *world;
|
World *world;
|
||||||
ObjectWithFrame::Sync originalSync;
|
ObjectWithFrame::Sync originalSync;
|
||||||
void (*originalBeginUpdate)(Camera*);
|
void (*originalBeginUpdate)(Camera*);
|
||||||
|
@ -15,19 +15,54 @@
|
|||||||
#include "d3d/rwd3d8.h"
|
#include "d3d/rwd3d8.h"
|
||||||
#include "d3d/rwd3d9.h"
|
#include "d3d/rwd3d9.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/* srsly? */
|
|
||||||
#define strdup _strdup
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PLUGIN_ID 0
|
#define PLUGIN_ID 0
|
||||||
|
|
||||||
|
// TODO: maintain a global list of all texdicts
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
||||||
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
|
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
|
||||||
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
|
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
|
||||||
|
|
||||||
|
struct TextureGlobals
|
||||||
|
{
|
||||||
|
TexDictionary *initialTexDict;
|
||||||
|
TexDictionary *currentTexDict;
|
||||||
|
// load textures from files
|
||||||
|
bool32 loadTextures;
|
||||||
|
// create dummy textures to store just names
|
||||||
|
bool32 makeDummies;
|
||||||
|
};
|
||||||
|
int32 textureModuleOffset;
|
||||||
|
|
||||||
|
#define TEXTUREGLOBAL(v) (PLUGINOFFSET(TextureGlobals, engine, textureModuleOffset)->v)
|
||||||
|
|
||||||
|
static void*
|
||||||
|
textureOpen(void *object, int32 offset, int32 size)
|
||||||
|
{
|
||||||
|
TexDictionary *texdict;
|
||||||
|
textureModuleOffset = offset;
|
||||||
|
texdict = TexDictionary::create();
|
||||||
|
TEXTUREGLOBAL(initialTexDict) = texdict;
|
||||||
|
TexDictionary::setCurrent(texdict);
|
||||||
|
TEXTUREGLOBAL(loadTextures) = 1;
|
||||||
|
TEXTUREGLOBAL(makeDummies) = 0;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
static void*
|
||||||
|
textureClose(void *object, int32 offset, int32 size)
|
||||||
|
{
|
||||||
|
TEXTUREGLOBAL(initialTexDict)->destroy();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Texture::registerModule(void)
|
||||||
|
{
|
||||||
|
Engine::registerPlugin(sizeof(TextureGlobals), ID_TEXTUREMODULE, textureOpen, textureClose);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// TexDictionary
|
// TexDictionary
|
||||||
//
|
//
|
||||||
@ -49,8 +84,8 @@ TexDictionary::create(void)
|
|||||||
void
|
void
|
||||||
TexDictionary::destroy(void)
|
TexDictionary::destroy(void)
|
||||||
{
|
{
|
||||||
if(engine->currentTexDictionary == this)
|
if(TEXTUREGLOBAL(currentTexDict) == this)
|
||||||
engine->currentTexDictionary = nil;
|
TEXTUREGLOBAL(currentTexDict) = nil;
|
||||||
FORLIST(lnk, this->textures)
|
FORLIST(lnk, this->textures)
|
||||||
Texture::fromDict(lnk)->destroy();
|
Texture::fromDict(lnk)->destroy();
|
||||||
s_plglist.destruct(this);
|
s_plglist.destruct(this);
|
||||||
@ -145,13 +180,13 @@ TexDictionary::streamGetSize(void)
|
|||||||
void
|
void
|
||||||
TexDictionary::setCurrent(TexDictionary *txd)
|
TexDictionary::setCurrent(TexDictionary *txd)
|
||||||
{
|
{
|
||||||
engine->currentTexDictionary = txd;
|
PLUGINOFFSET(TextureGlobals, engine, textureModuleOffset)->currentTexDict = txd;
|
||||||
}
|
}
|
||||||
|
|
||||||
TexDictionary*
|
TexDictionary*
|
||||||
TexDictionary::getCurrent(void)
|
TexDictionary::getCurrent(void)
|
||||||
{
|
{
|
||||||
return engine->currentTexDictionary;
|
return PLUGINOFFSET(TextureGlobals, engine, textureModuleOffset)->currentTexDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -200,8 +235,8 @@ Texture::destroy(void)
|
|||||||
static Texture*
|
static Texture*
|
||||||
defaultFindCB(const char *name)
|
defaultFindCB(const char *name)
|
||||||
{
|
{
|
||||||
if(engine->currentTexDictionary)
|
if(TEXTUREGLOBAL(currentTexDict))
|
||||||
return engine->currentTexDictionary->find(name);
|
return TEXTUREGLOBAL(currentTexDict)->find(name);
|
||||||
// TODO: RW searches *all* TXDs otherwise
|
// TODO: RW searches *all* TXDs otherwise
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@ -238,11 +273,11 @@ Texture::read(const char *name, const char *mask)
|
|||||||
tex->refCount++;
|
tex->refCount++;
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
if(engine->loadTextures){
|
if(TEXTUREGLOBAL(loadTextures)){
|
||||||
tex = Texture::readCB(name, mask);
|
tex = Texture::readCB(name, mask);
|
||||||
if(tex == nil)
|
if(tex == nil)
|
||||||
goto dummytex;
|
goto dummytex;
|
||||||
}else dummytex: if(engine->makeDummies){
|
}else dummytex: if(TEXTUREGLOBAL(makeDummies)){
|
||||||
tex = Texture::create(nil);
|
tex = Texture::create(nil);
|
||||||
if(tex == nil)
|
if(tex == nil)
|
||||||
return nil;
|
return nil;
|
||||||
@ -252,10 +287,10 @@ Texture::read(const char *name, const char *mask)
|
|||||||
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
|
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
|
||||||
tex->raster = raster;
|
tex->raster = raster;
|
||||||
}
|
}
|
||||||
if(tex && engine->currentTexDictionary){
|
if(tex && TEXTUREGLOBAL(currentTexDict)){
|
||||||
if(tex->dict)
|
if(tex->dict)
|
||||||
tex->inDict.remove();
|
tex->inDict.remove();
|
||||||
engine->currentTexDictionary->add(tex);
|
TEXTUREGLOBAL(currentTexDict)->add(tex);
|
||||||
}
|
}
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ void
|
|||||||
Camera::update(void)
|
Camera::update(void)
|
||||||
{
|
{
|
||||||
if(m_rwcam){
|
if(m_rwcam){
|
||||||
m_rwcam->nearPlane = m_near;
|
m_rwcam->setNearPlane(m_near);
|
||||||
m_rwcam->farPlane = m_far;
|
m_rwcam->setFarPlane(m_far);
|
||||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||||
|
|
||||||
rw::Frame *f = m_rwcam->getFrame();
|
rw::Frame *f = m_rwcam->getFrame();
|
||||||
|
@ -5,10 +5,16 @@
|
|||||||
|
|
||||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
rw::Clump *clump;
|
struct SceneGlobals {
|
||||||
rw::World *world;
|
rw::World *world;
|
||||||
|
rw::Camera *camera;
|
||||||
|
rw::Clump *clump;
|
||||||
|
} Scene;
|
||||||
|
rw::Texture *tex;
|
||||||
rw::EngineStartParams engineStartParams;
|
rw::EngineStartParams engineStartParams;
|
||||||
|
|
||||||
|
void tlTest(rw::Clump *clump);
|
||||||
|
|
||||||
void
|
void
|
||||||
Init(void)
|
Init(void)
|
||||||
{
|
{
|
||||||
@ -152,6 +158,8 @@ InitRW(void)
|
|||||||
if(!sk::InitRW())
|
if(!sk::InitRW())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
tex = rw::Texture::read("maze", nil);
|
||||||
|
|
||||||
char *filename = "teapot.dff";
|
char *filename = "teapot.dff";
|
||||||
if(sk::args.argc > 1)
|
if(sk::args.argc > 1)
|
||||||
filename = sk::args.argv[1];
|
filename = sk::args.argv[1];
|
||||||
@ -161,31 +169,43 @@ InitRW(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||||
clump = rw::Clump::streamRead(&in);
|
Scene.clump = rw::Clump::streamRead(&in);
|
||||||
assert(clump);
|
assert(Scene.clump);
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
// TEST - Set texture to the all materials of the clump
|
||||||
|
FORLIST(lnk, Scene.clump->atomics){
|
||||||
|
rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||||
|
for(int i = 0; i < a->geometry->matList.numMaterials; i++)
|
||||||
|
a->geometry->matList.materials[i]->setTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
dumpUserData(clump);
|
Scene.clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||||
setupClump(clump);
|
|
||||||
|
|
||||||
world = rw::World::create();
|
dumpUserData(Scene.clump);
|
||||||
|
setupClump(Scene.clump);
|
||||||
|
|
||||||
|
Scene.world = rw::World::create();
|
||||||
|
|
||||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||||
ambient->setColor(0.2f, 0.2f, 0.2f);
|
ambient->setColor(0.2f, 0.2f, 0.2f);
|
||||||
world->addLight(ambient);
|
Scene.world->addLight(ambient);
|
||||||
|
|
||||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||||
direct->setFrame(rw::Frame::create());
|
direct->setFrame(rw::Frame::create());
|
||||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||||
world->addLight(direct);
|
Scene.world->addLight(direct);
|
||||||
|
|
||||||
camera = new Camera;
|
camera = new Camera;
|
||||||
camera->m_rwcam = rw::Camera::create();
|
Scene.camera = rw::Camera::create();
|
||||||
camera->m_rwcam->setFrame(rw::Frame::create());
|
camera->m_rwcam = Scene.camera;
|
||||||
|
Scene.camera->frameBuffer =
|
||||||
|
rw::Raster::create(sk::globals.width, sk::globals.height, 0, rw::Raster::CAMERA);
|
||||||
|
Scene.camera->zBuffer =
|
||||||
|
rw::Raster::create(sk::globals.width, sk::globals.height, 0, rw::Raster::ZBUFFER);
|
||||||
|
Scene.camera->setFrame(rw::Frame::create());
|
||||||
camera->m_aspectRatio = 640.0f/480.0f;
|
camera->m_aspectRatio = 640.0f/480.0f;
|
||||||
camera->m_near = 0.1f;
|
camera->m_near = 0.1f;
|
||||||
camera->m_far = 450.0f;
|
camera->m_far = 450.0f;
|
||||||
@ -196,7 +216,7 @@ InitRW(void)
|
|||||||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||||
camera->update();
|
camera->update();
|
||||||
|
|
||||||
world->addCamera(camera->m_rwcam);
|
Scene.world->addCamera(camera->m_rwcam);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -204,15 +224,37 @@ InitRW(void)
|
|||||||
void
|
void
|
||||||
im2dtest(void)
|
im2dtest(void)
|
||||||
{
|
{
|
||||||
static rw::gl3::Im2DVertex verts[] = {
|
using namespace rw::RWDEVICE;
|
||||||
{ -0.5, -0.5, 0.0, 255, 0, 0, 255, 0.0, 0.0 },
|
int i;
|
||||||
{ 0.5, -0.5, 0.0, 0, 255, 0, 255, 0.0, 0.0 },
|
static struct
|
||||||
{ -0.5, 0.5, 0.0, 0, 0, 255, 255, 0.0, 0.0 },
|
{
|
||||||
{ 0.5, 0.5, 0.0, 0, 255, 255, 255, 0.0, 0.0 },
|
float x, y;
|
||||||
|
rw::uint8 r, g, b, a;
|
||||||
|
float u, v;
|
||||||
|
} vs[4] = {
|
||||||
|
{ 0.0f, 0.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||||
|
{ 640.0f, 0.0f, 0, 255, 0, 128, 1.0f, 0.0f },
|
||||||
|
{ 0.0f, 480.0f, 0, 0, 255, 128, 0.0f, 1.0f },
|
||||||
|
{ 640.0f, 480.0f, 0, 255, 255, 128, 1.0f, 1.0f },
|
||||||
};
|
};
|
||||||
|
static Im2DVertex verts[4];
|
||||||
static short indices[] = {
|
static short indices[] = {
|
||||||
0, 1, 2, 3
|
0, 1, 2, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for(i = 0; i < 4; i++){
|
||||||
|
verts[i].setScreenX(vs[i].x);
|
||||||
|
verts[i].setScreenY(vs[i].y);
|
||||||
|
verts[i].setScreenZ(rw::GetNearZ());
|
||||||
|
verts[i].setCameraZ(Scene.camera->nearPlane);
|
||||||
|
verts[i].setRecipCameraZ(1.0f/Scene.camera->nearPlane);
|
||||||
|
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||||
|
verts[i].setU(vs[i].u);
|
||||||
|
verts[i].setV(vs[i].v);
|
||||||
|
}
|
||||||
|
|
||||||
|
rw::engine->imtexture = tex;
|
||||||
|
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||||
&verts, 4, &indices, 4);
|
&verts, 4, &indices, 4);
|
||||||
}
|
}
|
||||||
@ -225,8 +267,9 @@ Draw(float timeDelta)
|
|||||||
camera->update();
|
camera->update();
|
||||||
camera->m_rwcam->beginUpdate();
|
camera->m_rwcam->beginUpdate();
|
||||||
|
|
||||||
clump->render();
|
Scene.clump->render();
|
||||||
im2dtest();
|
im2dtest();
|
||||||
|
// tlTest(Scene.clump);
|
||||||
|
|
||||||
camera->m_rwcam->endUpdate();
|
camera->m_rwcam->endUpdate();
|
||||||
camera->m_rwcam->showRaster();
|
camera->m_rwcam->showRaster();
|
||||||
|
BIN
tools/clumpview/maze.tga
Normal file
BIN
tools/clumpview/maze.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
134
tools/clumpview/tests.cpp
Normal file
134
tools/clumpview/tests.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include <rw.h>
|
||||||
|
#include <skeleton.h>
|
||||||
|
|
||||||
|
using namespace rw;
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is a test to implement T&L in software and render with Im2D
|
||||||
|
|
||||||
|
#define MAX_LIGHTS 8
|
||||||
|
|
||||||
|
struct Directional {
|
||||||
|
V3d at;
|
||||||
|
RGBAf color;
|
||||||
|
};
|
||||||
|
static Directional directionals[MAX_LIGHTS];
|
||||||
|
static int32 numDirectionals;
|
||||||
|
static RGBAf ambLight;
|
||||||
|
|
||||||
|
static void
|
||||||
|
enumLights(Matrix *lightmat)
|
||||||
|
{
|
||||||
|
int32 n;
|
||||||
|
World *world;
|
||||||
|
|
||||||
|
world = (World*)engine->currentWorld;
|
||||||
|
ambLight.red = 0.0;
|
||||||
|
ambLight.green = 0.0;
|
||||||
|
ambLight.blue = 0.0;
|
||||||
|
ambLight.alpha = 0.0;
|
||||||
|
numDirectionals = 0;
|
||||||
|
// only unpositioned lights right now
|
||||||
|
FORLIST(lnk, world->directionalLights){
|
||||||
|
Light *l = Light::fromWorld(lnk);
|
||||||
|
if(l->getType() == Light::DIRECTIONAL){
|
||||||
|
if(numDirectionals >= MAX_LIGHTS)
|
||||||
|
continue;
|
||||||
|
n = numDirectionals++;
|
||||||
|
V3d::transformVectors(&directionals[n].at, &l->getFrame()->getLTM()->at, 1, lightmat);
|
||||||
|
directionals[n].color = l->color;
|
||||||
|
directionals[n].color.alpha = 0.0f;
|
||||||
|
}else if(l->getType() == Light::AMBIENT){
|
||||||
|
ambLight.red += l->color.red;
|
||||||
|
ambLight.green += l->color.green;
|
||||||
|
ambLight.blue += l->color.blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drawAtomic(Atomic *a)
|
||||||
|
{
|
||||||
|
using namespace RWDEVICE;
|
||||||
|
Im2DVertex *im2dverts;
|
||||||
|
V3d *xvert;
|
||||||
|
Matrix xform;
|
||||||
|
Matrix lightmat;
|
||||||
|
Camera *cam = (Camera*)engine->currentCamera;
|
||||||
|
Geometry *g = a->geometry;
|
||||||
|
MeshHeader *mh = g->meshHeader;
|
||||||
|
Mesh *m = mh->getMeshes();
|
||||||
|
int32 width = cam->frameBuffer->width;
|
||||||
|
int32 height = cam->frameBuffer->height;
|
||||||
|
RGBA *prelight;
|
||||||
|
V3d *normals;
|
||||||
|
TexCoords *texcoords;
|
||||||
|
|
||||||
|
Matrix::mult(&xform, a->getFrame()->getLTM(), &cam->viewMatrix);
|
||||||
|
Matrix::invert(&lightmat, a->getFrame()->getLTM());
|
||||||
|
|
||||||
|
enumLights(&lightmat);
|
||||||
|
|
||||||
|
xvert = rwNewT(V3d, g->numVertices, MEMDUR_FUNCTION);
|
||||||
|
im2dverts = rwNewT(Im2DVertex, g->numVertices, MEMDUR_FUNCTION);
|
||||||
|
|
||||||
|
prelight = g->colors;
|
||||||
|
normals = g->morphTargets[0].normals;
|
||||||
|
texcoords = g->texCoords[0];
|
||||||
|
|
||||||
|
V3d::transformPoints(xvert, g->morphTargets[0].vertices, g->numVertices, &xform);
|
||||||
|
for(int32 i = 0; i < g->numVertices; i++){
|
||||||
|
float32 recipZ = 1.0f/xvert[i].z;
|
||||||
|
|
||||||
|
im2dverts[i].setScreenX(xvert[i].x * recipZ * width);
|
||||||
|
im2dverts[i].setScreenY((xvert[i].y * recipZ * height));
|
||||||
|
im2dverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||||
|
im2dverts[i].setCameraZ(xvert[i].z);
|
||||||
|
im2dverts[i].setRecipCameraZ(recipZ);
|
||||||
|
im2dverts[i].setColor(255, 0, 0, 255);
|
||||||
|
im2dverts[i].setU(texcoords[i].u);
|
||||||
|
im2dverts[i].setV(texcoords[i].v);
|
||||||
|
}
|
||||||
|
for(int32 i = 0; i < mh->numMeshes; i++){
|
||||||
|
for(int32 j = 0; j < m[i].numIndices; j++){
|
||||||
|
int32 idx = m[i].indices[j];
|
||||||
|
RGBA col;
|
||||||
|
RGBAf colf, color;
|
||||||
|
if(prelight)
|
||||||
|
convColor(&color, &prelight[idx]);
|
||||||
|
else{
|
||||||
|
color.red = color.green = color.blue = 0.0f;
|
||||||
|
color.alpha = 1.0f;
|
||||||
|
}
|
||||||
|
color = add(color, ambLight);
|
||||||
|
if(normals)
|
||||||
|
for(int32 k = 0; k < numDirectionals; k++){
|
||||||
|
float32 f = dot(normals[idx], neg(directionals[k].at));
|
||||||
|
if(f <= 0.0f) continue;
|
||||||
|
colf = scale(directionals[k].color, f);
|
||||||
|
color = add(color, colf);
|
||||||
|
}
|
||||||
|
convColor(&colf, &m[i].material->color);
|
||||||
|
color = modulate(color, colf);
|
||||||
|
clamp(&color);
|
||||||
|
convColor(&col, &color);
|
||||||
|
im2dverts[idx].setColor(col.red, col.green, col.blue, col.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
engine->imtexture = m[i].material->texture;
|
||||||
|
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||||
|
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
rwFree(xvert);
|
||||||
|
rwFree(im2dverts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tlTest(Clump *clump)
|
||||||
|
{
|
||||||
|
FORLIST(lnk, clump->atomics){
|
||||||
|
Atomic *a = Atomic::fromClump(lnk);
|
||||||
|
drawAtomic(a);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user