mirror of https://github.com/aap/librw.git
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;
|
||||
if(!rw::Engine::start(&engineStartParams))
|
||||
return false;
|
||||
rw::engine->loadTextures = 1;
|
||||
|
||||
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
|
||||
rw::Image::setSearchPath(".");
|
||||
rw::Image::setSearchPath("./");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,11 +127,20 @@ MakeWindow(HINSTANCE instance, int width, int height, const char *title)
|
|||
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;
|
||||
win = CreateWindow("librwD3D9", title,
|
||||
WS_BORDER | WS_CAPTION | WS_SYSMENU |
|
||||
WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|
||||
0, 0, width, height, 0, 0, instance, 0);
|
||||
win = CreateWindow("librwD3D9", title, style,
|
||||
offx, offy, rect.right, rect.bottom, 0, 0, instance, 0);
|
||||
if(!win){
|
||||
MessageBox(0, "CreateWindow() - FAILED", 0, 0);
|
||||
return 0;
|
||||
|
|
|
@ -284,6 +284,9 @@ Camera::create(void)
|
|||
cam->fogPlane = 5.0f;
|
||||
cam->projection = Camera::PERSPECTIVE;
|
||||
|
||||
cam->frameBuffer = nil;
|
||||
cam->zBuffer = nil;
|
||||
|
||||
// clump extension
|
||||
cam->clump = nil;
|
||||
cam->inClump.init();
|
||||
|
@ -315,6 +318,10 @@ Camera::clone(void)
|
|||
cam->farPlane = this->farPlane;
|
||||
cam->fogPlane = this->fogPlane;
|
||||
cam->projection = this->projection;
|
||||
|
||||
cam->frameBuffer = this->frameBuffer;
|
||||
cam->zBuffer = this->zBuffer;
|
||||
|
||||
s_plglist.copy(cam, this);
|
||||
return cam;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3dimpl.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
|
@ -275,6 +276,7 @@ setRasterStage(uint32 stage, Raster *raster)
|
|||
void
|
||||
setTexture(uint32 stage, Texture *tex)
|
||||
{
|
||||
// TODO: support mipmaps
|
||||
static DWORD filternomip[] = {
|
||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
|
@ -289,10 +291,10 @@ setTexture(uint32 stage, Texture *tex)
|
|||
return;
|
||||
}
|
||||
if(tex->raster){
|
||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->getFilter()]);
|
||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->getFilter()]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[tex->getAddressU()]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[tex->getAddressV()]);
|
||||
}
|
||||
setRasterStage(stage, tex->raster);
|
||||
}
|
||||
|
@ -528,6 +530,14 @@ initD3D(void)
|
|||
// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
|
||||
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
|
||||
|
||||
openIm2D();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
finalizeD3D(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -539,6 +549,8 @@ deviceSystem(DeviceReq req, void *arg0)
|
|||
return startD3D((EngineStartParams*)arg0);
|
||||
case DEVICEINIT:
|
||||
return initD3D();
|
||||
case DEVICEFINALIZE:
|
||||
return finalizeD3D();
|
||||
case DEVICESTOP:
|
||||
return stopD3D();
|
||||
}
|
||||
|
@ -553,7 +565,7 @@ Device renderdevice = {
|
|||
d3d::showRaster,
|
||||
d3d::setRwRenderState,
|
||||
d3d::getRwRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
d3d::im2DRenderIndexedPrimitive,
|
||||
d3d::deviceSystem,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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
|
||||
enum {
|
||||
D3DLOCK_NOSYSLOCK = 0, // ignored
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
namespace rw {
|
||||
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);
|
||||
uint8 *rasterLock(Raster *raster, int32 level);
|
||||
void rasterUnlock(Raster *raster, int32 level);
|
||||
|
|
|
@ -41,7 +41,7 @@ void *mustmalloc_h(size_t sz, uint32 hint)
|
|||
{
|
||||
void *ret;
|
||||
ret = rwMalloc(sz, hint);
|
||||
if(ret)
|
||||
if(ret || sz == 0)
|
||||
return ret;
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
exit(1);
|
||||
|
@ -51,7 +51,7 @@ void *mustrealloc_h(void *p, size_t sz, uint32 hint)
|
|||
{
|
||||
void *ret;
|
||||
ret = rwRealloc(p, sz, hint);
|
||||
if(ret)
|
||||
if(ret || sz == 0)
|
||||
return ret;
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
exit(1);
|
||||
|
@ -83,7 +83,8 @@ Engine::init(void)
|
|||
Engine::s_plglist.last = nil;
|
||||
|
||||
// core plugin attach here
|
||||
Engine::registerPlugin(0, ID_FRAMEMODULE, Frame::_open, Frame::_close);
|
||||
Frame::registerModule();
|
||||
Texture::registerModule();
|
||||
|
||||
// driver plugin attach
|
||||
ps2::registerPlatformPlugins();
|
||||
|
@ -111,10 +112,7 @@ Engine::open(void)
|
|||
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
||||
engine->currentCamera = nil;
|
||||
engine->currentWorld = nil;
|
||||
engine->currentTexDictionary = nil;
|
||||
engine->imtexture = nil;
|
||||
engine->loadTextures = 1;
|
||||
engine->makeDummies = 1;
|
||||
|
||||
// Initialize device
|
||||
// Device and possibly OS specific!
|
||||
|
@ -177,10 +175,7 @@ void
|
|||
Engine::term(void)
|
||||
{
|
||||
// TODO
|
||||
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;
|
||||
Engine::state = Dead;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -197,7 +192,10 @@ void
|
|||
Engine::stop(void)
|
||||
{
|
||||
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 {
|
||||
|
|
|
@ -13,10 +13,14 @@
|
|||
namespace rw {
|
||||
|
||||
PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
|
||||
void *Frame::_open(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); return object; }
|
||||
void *Frame::_close(void *object, int32 offset, int32 size) { return object; }
|
||||
|
||||
static void *frameOpen(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); 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::create(void)
|
||||
|
|
|
@ -70,7 +70,6 @@ static UniformObject uniformObject;
|
|||
int32 u_matColor;
|
||||
int32 u_surfaceProps;
|
||||
|
||||
|
||||
Shader *simpleShader;
|
||||
|
||||
static bool32 stateDirty = 1;
|
||||
|
@ -304,6 +303,17 @@ setActiveTexture(int32 n)
|
|||
void
|
||||
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;
|
||||
setActiveTexture(GL_TEXTURE0+n);
|
||||
if(tex == nil || tex->raster->platform != PLATFORM_GL3 ||
|
||||
|
@ -315,6 +325,13 @@ setTexture(int32 n, Texture *tex)
|
|||
nativeRasterOffset);
|
||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
||||
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){
|
||||
|
@ -518,25 +535,6 @@ initOpenGL(void)
|
|||
glGenVertexArrays(1, &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);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
|
||||
|
@ -558,6 +556,25 @@ finalizeOpenGL(void)
|
|||
GL_DYNAMIC_DRAW);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,20 @@
|
|||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
uint32 im2DVbo, im2DIbo;
|
||||
static uint32 im2DVbo, im2DIbo;
|
||||
static int32 u_xform;
|
||||
|
||||
#define STARTINDICES 1024
|
||||
#define STARTVERTICES 1024
|
||||
#define STARTINDICES 10000
|
||||
#define STARTVERTICES 10000
|
||||
|
||||
static Shader *im2dShader;
|
||||
static AttribDesc attribDesc[3] = {
|
||||
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 3,
|
||||
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 4,
|
||||
sizeof(Im2DVertex), 0 },
|
||||
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||
sizeof(Im2DVertex), offsetof(Im2DVertex, r) },
|
||||
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||
sizeof(Im2DVertex), offsetof(Im2DVertex, r) },
|
||||
sizeof(Im2DVertex), offsetof(Im2DVertex, u) },
|
||||
};
|
||||
|
||||
static int primTypeMap[] = {
|
||||
|
@ -42,8 +43,10 @@ static int primTypeMap[] = {
|
|||
};
|
||||
|
||||
void
|
||||
im2DInit(void)
|
||||
openIm2D(void)
|
||||
{
|
||||
u_xform = registerUniform("u_xform");
|
||||
|
||||
#include "shaders/im2d_gl3.inc"
|
||||
im2dShader = Shader::fromStrings(im2d_vert_src, im2d_frag_src);
|
||||
|
||||
|
@ -65,6 +68,11 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||
void *vertices, int32 numVertices,
|
||||
void *indices, int32 numIndices)
|
||||
{
|
||||
GLfloat xform[4];
|
||||
Camera *cam;
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
|
||||
// TODO: fixed size
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
||||
indices, GL_DYNAMIC_DRAW);
|
||||
|
@ -73,9 +81,15 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||
glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex),
|
||||
vertices, GL_DYNAMIC_DRAW);
|
||||
|
||||
setAttribPointers(attribDesc, 3);
|
||||
im2dShader->use();
|
||||
xform[0] = 2.0f/cam->frameBuffer->width;
|
||||
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);
|
||||
|
||||
flushCache();
|
||||
|
|
|
@ -23,9 +23,27 @@ int32 nativeRasterOffset;
|
|||
void
|
||||
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)
|
||||
return;
|
||||
|
||||
assert(raster->type == Raster::TEXTURE);
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||
switch(raster->format & 0xF00){
|
||||
|
@ -54,11 +72,10 @@ rasterCreate(Raster *raster)
|
|||
|
||||
glGenTextures(1, &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,
|
||||
raster->width, raster->height,
|
||||
0, natras->format, natras->type, nil);
|
||||
natras->filterAddressing = ~0;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#endif
|
||||
|
|
|
@ -78,11 +78,23 @@ struct InstanceDataHeader : rw::InstanceDataHeader
|
|||
InstanceData *inst;
|
||||
};
|
||||
|
||||
#ifdef RW_GL3
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
float32 x, y, z;
|
||||
float32 x, y, z, w;
|
||||
uint8 r, g, b, a;
|
||||
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);
|
||||
|
@ -105,6 +117,8 @@ void setTexture(int32 n, Texture *tex);
|
|||
|
||||
void flushCache(void);
|
||||
|
||||
#endif
|
||||
|
||||
class ObjPipeline : public rw::ObjPipeline
|
||||
{
|
||||
public:
|
||||
|
@ -136,6 +150,8 @@ struct Gl3Raster
|
|||
uint32 texid;
|
||||
|
||||
bool32 hasAlpha;
|
||||
// cached filtermode and addressing
|
||||
uint32 filterAddressing;
|
||||
};
|
||||
|
||||
void registerNativeRaster(void);
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace gl3 {
|
|||
|
||||
extern Shader *simpleShader;
|
||||
extern uint32 im2DVbo, im2DIbo;
|
||||
void im2DInit(void);
|
||||
void openIm2D(void);
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
#version 330
|
||||
|
||||
layout(std140) uniform Im2DState
|
||||
{
|
||||
int u_alphaTest;
|
||||
float u_alphaRef;
|
||||
mat4 u_xform;
|
||||
};
|
||||
//layout(std140) uniform Im2DState
|
||||
//{
|
||||
// int u_alphaTest;
|
||||
// float u_alphaRef;
|
||||
// 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 = 3) in vec2 in_tex0;
|
||||
|
||||
|
@ -17,7 +19,9 @@ out vec2 v_tex0;
|
|||
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_tex0 = in_tex0;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
const char *im2d_vert_src =
|
||||
"#version 330\n"
|
||||
|
||||
"layout(std140) uniform Im2DState\n"
|
||||
"{\n"
|
||||
" int u_alphaTest;\n"
|
||||
" float u_alphaRef;\n"
|
||||
" mat4 u_xform;\n"
|
||||
"};\n"
|
||||
"//layout(std140) uniform Im2DState\n"
|
||||
"//{\n"
|
||||
"// int u_alphaTest;\n"
|
||||
"// float u_alphaRef;\n"
|
||||
"// mat4 u_xform;\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 = 3) in vec2 in_tex0;\n"
|
||||
|
||||
|
@ -18,7 +20,9 @@ const char *im2d_vert_src =
|
|||
"void\n"
|
||||
"main(void)\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_tex0 = in_tex0;\n"
|
||||
"}\n"
|
||||
|
|
28
src/rwbase.h
28
src/rwbase.h
|
@ -8,6 +8,19 @@
|
|||
|
||||
#ifdef RW_GL3
|
||||
#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
|
||||
|
||||
#ifdef RW_WDGL
|
||||
|
@ -64,7 +77,21 @@ struct RGBAf
|
|||
float32 blue;
|
||||
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 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){
|
||||
int32 c;
|
||||
|
@ -467,6 +494,7 @@ enum CoreModuleID
|
|||
{
|
||||
ID_NAMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x00),
|
||||
ID_FRAMEMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x03),
|
||||
ID_TEXTUREMODULE = MAKEPLUGINID(VEND_CRITERIONINT, 0x08),
|
||||
};
|
||||
|
||||
#define ECODE(c, s) c,
|
||||
|
|
|
@ -135,11 +135,6 @@ struct Engine
|
|||
Texture *imtexture;
|
||||
LinkList frameDirtyList;
|
||||
|
||||
TexDictionary *currentTexDictionary;
|
||||
// load textures from files
|
||||
bool32 loadTextures;
|
||||
// create dummy textures to store just names
|
||||
bool32 makeDummies;
|
||||
// Dynamically allocated because of plugins
|
||||
Driver *driver[NUM_PLATFORMS];
|
||||
Device device;
|
||||
|
@ -170,6 +165,9 @@ inline void SetRenderState(int32 state, uint32 value){
|
|||
inline uint32 GetRenderState(int32 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
|
||||
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
|
||||
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
|
||||
|
|
|
@ -137,8 +137,7 @@ struct Frame
|
|||
void purgeClone(void);
|
||||
|
||||
#ifndef RWPUBLIC
|
||||
static void *_open(void*, int32, int32);
|
||||
static void *_close(void*, int32, int32);
|
||||
static void registerModule(void);
|
||||
#endif
|
||||
static void syncDirty(void);
|
||||
};
|
||||
|
@ -282,30 +281,6 @@ struct TexDictionary;
|
|||
|
||||
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 {
|
||||
NEAREST = 1,
|
||||
LINEAR,
|
||||
|
@ -320,6 +295,40 @@ struct Texture
|
|||
CLAMP,
|
||||
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];
|
||||
BBox frustumBoundBox;
|
||||
|
||||
Raster *frameBuffer;
|
||||
Raster *zBuffer;
|
||||
|
||||
// clump link handled by plugin in RW
|
||||
Clump *clump;
|
||||
LLLink inClump;
|
||||
|
||||
// world extension
|
||||
/* 3 unknowns */
|
||||
/* RW: frustum sectors, space, position */
|
||||
World *world;
|
||||
ObjectWithFrame::Sync originalSync;
|
||||
void (*originalBeginUpdate)(Camera*);
|
||||
|
|
|
@ -15,19 +15,54 @@
|
|||
#include "d3d/rwd3d8.h"
|
||||
#include "d3d/rwd3d9.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
/* srsly? */
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
// TODO: maintain a global list of all texdicts
|
||||
|
||||
namespace rw {
|
||||
|
||||
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
||||
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), 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
|
||||
//
|
||||
|
@ -49,8 +84,8 @@ TexDictionary::create(void)
|
|||
void
|
||||
TexDictionary::destroy(void)
|
||||
{
|
||||
if(engine->currentTexDictionary == this)
|
||||
engine->currentTexDictionary = nil;
|
||||
if(TEXTUREGLOBAL(currentTexDict) == this)
|
||||
TEXTUREGLOBAL(currentTexDict) = nil;
|
||||
FORLIST(lnk, this->textures)
|
||||
Texture::fromDict(lnk)->destroy();
|
||||
s_plglist.destruct(this);
|
||||
|
@ -145,13 +180,13 @@ TexDictionary::streamGetSize(void)
|
|||
void
|
||||
TexDictionary::setCurrent(TexDictionary *txd)
|
||||
{
|
||||
engine->currentTexDictionary = txd;
|
||||
PLUGINOFFSET(TextureGlobals, engine, textureModuleOffset)->currentTexDict = txd;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::getCurrent(void)
|
||||
{
|
||||
return engine->currentTexDictionary;
|
||||
return PLUGINOFFSET(TextureGlobals, engine, textureModuleOffset)->currentTexDict;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -200,8 +235,8 @@ Texture::destroy(void)
|
|||
static Texture*
|
||||
defaultFindCB(const char *name)
|
||||
{
|
||||
if(engine->currentTexDictionary)
|
||||
return engine->currentTexDictionary->find(name);
|
||||
if(TEXTUREGLOBAL(currentTexDict))
|
||||
return TEXTUREGLOBAL(currentTexDict)->find(name);
|
||||
// TODO: RW searches *all* TXDs otherwise
|
||||
return nil;
|
||||
}
|
||||
|
@ -238,11 +273,11 @@ Texture::read(const char *name, const char *mask)
|
|||
tex->refCount++;
|
||||
return tex;
|
||||
}
|
||||
if(engine->loadTextures){
|
||||
if(TEXTUREGLOBAL(loadTextures)){
|
||||
tex = Texture::readCB(name, mask);
|
||||
if(tex == nil)
|
||||
goto dummytex;
|
||||
}else dummytex: if(engine->makeDummies){
|
||||
}else dummytex: if(TEXTUREGLOBAL(makeDummies)){
|
||||
tex = Texture::create(nil);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
|
@ -252,10 +287,10 @@ Texture::read(const char *name, const char *mask)
|
|||
raster = Raster::create(0, 0, 0, Raster::DONTALLOCATE);
|
||||
tex->raster = raster;
|
||||
}
|
||||
if(tex && engine->currentTexDictionary){
|
||||
if(tex && TEXTUREGLOBAL(currentTexDict)){
|
||||
if(tex->dict)
|
||||
tex->inDict.remove();
|
||||
engine->currentTexDictionary->add(tex);
|
||||
TEXTUREGLOBAL(currentTexDict)->add(tex);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ void
|
|||
Camera::update(void)
|
||||
{
|
||||
if(m_rwcam){
|
||||
m_rwcam->nearPlane = m_near;
|
||||
m_rwcam->farPlane = m_far;
|
||||
m_rwcam->setNearPlane(m_near);
|
||||
m_rwcam->setFarPlane(m_far);
|
||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||
|
||||
rw::Frame *f = m_rwcam->getFrame();
|
||||
|
|
|
@ -5,10 +5,16 @@
|
|||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
Camera *camera;
|
||||
rw::Clump *clump;
|
||||
struct SceneGlobals {
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
rw::Clump *clump;
|
||||
} Scene;
|
||||
rw::Texture *tex;
|
||||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void tlTest(rw::Clump *clump);
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
|
@ -152,6 +158,8 @@ InitRW(void)
|
|||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
tex = rw::Texture::read("maze", nil);
|
||||
|
||||
char *filename = "teapot.dff";
|
||||
if(sk::args.argc > 1)
|
||||
filename = sk::args.argv[1];
|
||||
|
@ -161,31 +169,43 @@ InitRW(void)
|
|||
return false;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
assert(clump);
|
||||
Scene.clump = rw::Clump::streamRead(&in);
|
||||
assert(Scene.clump);
|
||||
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);
|
||||
setupClump(clump);
|
||||
Scene.clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
|
||||
world = rw::World::create();
|
||||
dumpUserData(Scene.clump);
|
||||
setupClump(Scene.clump);
|
||||
|
||||
Scene.world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
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::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
world->addLight(direct);
|
||||
Scene.world->addLight(direct);
|
||||
|
||||
camera = new Camera;
|
||||
camera->m_rwcam = rw::Camera::create();
|
||||
camera->m_rwcam->setFrame(rw::Frame::create());
|
||||
Scene.camera = rw::Camera::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_near = 0.1f;
|
||||
camera->m_far = 450.0f;
|
||||
|
@ -196,7 +216,7 @@ InitRW(void)
|
|||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
camera->update();
|
||||
|
||||
world->addCamera(camera->m_rwcam);
|
||||
Scene.world->addCamera(camera->m_rwcam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -204,15 +224,37 @@ InitRW(void)
|
|||
void
|
||||
im2dtest(void)
|
||||
{
|
||||
static rw::gl3::Im2DVertex verts[] = {
|
||||
{ -0.5, -0.5, 0.0, 255, 0, 0, 255, 0.0, 0.0 },
|
||||
{ 0.5, -0.5, 0.0, 0, 255, 0, 255, 0.0, 0.0 },
|
||||
{ -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 },
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
static struct
|
||||
{
|
||||
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[] = {
|
||||
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,
|
||||
&verts, 4, &indices, 4);
|
||||
}
|
||||
|
@ -225,8 +267,9 @@ Draw(float timeDelta)
|
|||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
clump->render();
|
||||
Scene.clump->render();
|
||||
im2dtest();
|
||||
// tlTest(Scene.clump);
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
camera->m_rwcam->showRaster();
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
|
@ -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