mirror of
https://github.com/aap/librw.git
synced 2025-12-18 16:39:51 +00:00
implemented im2d for d3d, fun little software T&L renderer
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user