worked on platform drivers

This commit is contained in:
aap
2016-07-05 11:36:43 +02:00
parent ad1ea4ca53
commit abe0bba5af
17 changed files with 611 additions and 384 deletions

View File

@@ -29,6 +29,16 @@ defaultEndUpdateCB(Camera *cam)
static void
cameraSync(ObjectWithFrame*)
{
// TODO: calculate view matrix here (i.e. projection * inverseLTM)
// RW projection matrix looks like this:
// (cf. Camera View Matrix white paper)
// w = viewWindow width
// h = viewWindow height
// o = view offset
//
// 1/2w 0 ox/2w + 1/2 -ox/2w
// 0 -1/2h -oy/2h + 1/2 oy/2h
// 0 0 1 0
}
void
@@ -169,73 +179,6 @@ Camera::streamGetSize(void)
s_plglist.streamGetSize(this);
}
// TODO: remove
void
Camera::updateProjectionMatrix(void)
{
float32 invwx = 1.0f/this->viewWindow.x;
float32 invwy = 1.0f/this->viewWindow.y;
float32 invz = 1.0f/(this->farPlane-this->nearPlane);
if(rw::platform == PLATFORM_D3D8 || rw::platform == PLATFORM_D3D9 ||
rw::platform == PLATFORM_XBOX){
// is this all really correct?
this->projMat[0] = invwx;
this->projMat[1] = 0.0f;
this->projMat[2] = 0.0f;
this->projMat[3] = 0.0f;
this->projMat[4] = 0.0f;
this->projMat[5] = invwy;
this->projMat[6] = 0.0f;
this->projMat[7] = 0.0f;
if(this->projection == PERSPECTIVE){
this->projMat[8] = this->viewOffset.x*invwx;
this->projMat[9] = this->viewOffset.y*invwy;
this->projMat[10] = this->farPlane*invz;
this->projMat[11] = 1.0f;
this->projMat[12] = 0.0f;
this->projMat[13] = 0.0f;
this->projMat[14] = -this->nearPlane*this->projMat[10];
this->projMat[15] = 0.0f;
}else{
this->projMat[8] = 0.0f;
this->projMat[9] = 0.0f;
this->projMat[10] = invz;
this->projMat[11] = 0.0f;
this->projMat[12] = this->viewOffset.x*invwx;
this->projMat[13] = this->viewOffset.y*invwy;
this->projMat[14] = -this->nearPlane*this->projMat[10];
this->projMat[15] = 1.0f;
}
}else if(rw::platform == PLATFORM_WDGL || rw::platform == PLATFORM_GL3){
this->projMat[0] = invwx;
this->projMat[1] = 0.0f;
this->projMat[2] = 0.0f;
this->projMat[3] = 0.0f;
this->projMat[4] = 0.0f;
this->projMat[5] = invwy;
this->projMat[6] = 0.0f;
this->projMat[7] = 0.0f;
if(this->projection == PERSPECTIVE){
this->projMat[8] = this->viewOffset.x*invwx;
this->projMat[9] = this->viewOffset.y*invwy;
this->projMat[10] = (this->farPlane+this->nearPlane)*invz;
this->projMat[11] = 1.0f;
this->projMat[12] = 0.0f;
this->projMat[13] = 0.0f;
this->projMat[14] = -2.0f*this->nearPlane*this->farPlane*invz;
this->projMat[15] = 0.0f;
}else{
}
}
}
void
Camera::setFOV(float32 fov, float32 ratio)
{

View File

@@ -23,7 +23,6 @@ using namespace d3d;
void*
driverOpen(void *o, int32, int32)
{
printf("d3d8 open\n");
driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset;

View File

@@ -30,7 +30,6 @@ using namespace d3d;
void*
driverOpen(void *o, int32, int32)
{
printf("d3d9 open\n");
driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset;

View File

@@ -177,6 +177,82 @@ setMaterial(Material *mat)
}
}
void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
// View Matrix
Matrix inv;
// TODO: this can be simplified, or we use matrix flags....
Matrix::invert(&inv, cam->getFrame()->getLTM());
// Since we're looking into positive Z,
// flip X to ge a left handed view space.
view[0] = -inv.right.x;
view[1] = inv.right.y;
view[2] = inv.right.z;
view[3] = 0.0f;
view[4] = -inv.up.x;
view[5] = inv.up.y;
view[6] = inv.up.z;
view[7] = 0.0f;
view[8] = -inv.at.x;
view[9] = inv.at.y;
view[10] = inv.at.z;
view[11] = 0.0f;
view[12] = -inv.pos.x;
view[13] = inv.pos.y;
view[14] = inv.pos.z;
view[15] = 1.0f;
device->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
// Projection Matrix
float32 invwx = 1.0f/this->viewWindow.x;
float32 invwy = 1.0f/this->viewWindow.y;
float32 invz = 1.0f/(this->farPlane-this->nearPlane);
// is this all really correct? RW code looks a bit different...
proj[0] = invwx;
proj[1] = 0.0f;
proj[2] = 0.0f;
proj[3] = 0.0f;
proj[4] = 0.0f;
proj[5] = invwy;
proj[6] = 0.0f;
proj[7] = 0.0f;
if(this->projection == PERSPECTIVE){
proj[8] = this->viewOffset.x*invwx;
proj[9] = this->viewOffset.y*invwy;
proj[10] = this->farPlane*invz;
proj[11] = 1.0f;
proj[12] = 0.0f;
proj[13] = 0.0f;
proj[14] = -this->nearPlane*this->projMat[10];
proj[15] = 0.0f;
}else{
proj[8] = 0.0f;
proj[9] = 0.0f;
proj[10] = invz;
proj[11] = 0.0f;
proj[12] = this->viewOffset.x*invwx;
proj[13] = this->viewOffset.y*invwy;
proj[14] = -this->nearPlane*this->projMat[10];
proj[15] = 1.0f;
}
device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
}
void
initializeRender(void)
{
driver[PLATFORM_D3D8]->beginUpdate = beginUpdate;
driver[PLATFORM_D3D9]->beginUpdate = beginUpdate;
}
#endif
}
}

View File

@@ -5,6 +5,8 @@
namespace rw {
namespace d3d {
void initializeRender(void);
extern bool32 isP8supported;
#ifdef RW_D3D9

View File

@@ -22,7 +22,6 @@ namespace xbox {
void*
driverOpen(void *o, int32, int32)
{
printf("xbox open\n");
driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline();
driver[PLATFORM_XBOX]->rasterNativeOffset = nativeRasterOffset;

View File

@@ -53,6 +53,9 @@ Driver::open(void)
driver[i]->beginUpdate = null::beginUpdate;
driver[i]->endUpdate = null::endUpdate;
driver[i]->setRenderState = null::setRenderState;
driver[i]->getRenderState = null::getRenderState;
driver[i]->rasterCreate = null::rasterCreate;
driver[i]->rasterLock = null::rasterLock;
driver[i]->rasterUnlock = null::rasterUnlock;
@@ -69,6 +72,8 @@ void beginUpdate(Camera*) { }
void endUpdate(Camera*) { }
void setRenderState(int32, uint32) { }
uint32 getRenderState(int32) { return 0; }
void
rasterCreate(Raster*)

View File

@@ -26,7 +26,6 @@ namespace gl3 {
void*
driverOpen(void *o, int32, int32)
{
printf("gl3 open\n");
#ifdef RW_OPENGL
driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
#endif
@@ -37,8 +36,6 @@ driverOpen(void *o, int32, int32)
driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
initializeRender();
return o;
}

409
src/gl/gl3driver.cpp Normal file
View File

@@ -0,0 +1,409 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#ifdef RW_OPENGL
#include <GL/glew.h>
#include "rwgl3.h"
#include "rwgl3shader.h"
namespace rw {
namespace gl3 {
struct UniformState
{
int alphaFunc;
float32 alphaRef;
};
struct UniformScene
{
float32 proj[16];
float32 view[16];
};
struct UniformLight
{
V3d position;
float32 w;
V3d direction;
int32 pad1;
RGBAf color;
float32 radius;
float32 minusCosAngle;
int32 pad2[2];
};
#define MAX_LIGHTS 8
struct UniformObject
{
Matrix world;
RGBAf ambLight;
int32 numLights;
int32 pad[3];
UniformLight lights[MAX_LIGHTS];
};
GLuint vao;
GLuint ubo_state, ubo_scene, ubo_object;
GLuint whitetex;
UniformState uniformState;
UniformScene uniformScene;
UniformObject uniformObject;
Shader *simpleShader;
static bool32 stateDirty = 1;
static bool32 sceneDirty = 1;
static bool32 objectDirty = 1;
// cached render states
static bool32 vertexAlpha;
static bool32 textureAlpha;
static uint32 srcblend, destblend;
static uint32 zwrite;
static uint32 ztest;
uint32 blendMap[] = {
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA_SATURATE,
};
void
setRenderState(int32 state, uint32 value)
{
switch(state){
case VERTEXALPHA:
if(vertexAlpha != value){
vertexAlpha = value;
if(vertexAlpha)
glEnable(GL_BLEND);
else if(!textureAlpha)
glDisable(GL_BLEND);
}
break;
case SRCBLEND:
if(srcblend != value){
srcblend = value;
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
}
break;
case DESTBLEND:
if(destblend != value){
destblend = value;
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
}
break;
case ZTESTENABLE:
if(ztest != value){
ztest = value;
if(ztest)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
}
break;
case ZWRITEENABLE:
if(zwrite != (value ? GL_TRUE : GL_FALSE)){
zwrite = value ? GL_TRUE : GL_FALSE;
glDepthMask(zwrite);
}
break;
case ALPHATESTFUNC:
uniformState.alphaFunc = value;
stateDirty = 1;
break;
case ALPHATESTREF:
uniformState.alphaRef = value/255.0f;
stateDirty = 1;
break;
case ZTESTFUNC:
break;
}
}
uint32
getRenderState(int32 state)
{
switch(state){
case VERTEXALPHA:
return vertexAlpha;
case SRCBLEND:
return srcblend;
case DESTBLEND:
return destblend;
case ZTESTENABLE:
return ztest;
case ZWRITEENABLE:
return zwrite;
case ALPHATESTFUNC:
return uniformState.alphaFunc;
case ALPHATESTREF:
return uniformState.alphaRef*255.0f;
case ZTESTFUNC:
break;
}
}
void
resetRenderState(void)
{
uniformState.alphaFunc = ALPHAGREATERTHAN;
uniformState.alphaRef = 10.0f/255.0f;
stateDirty = 1;
vertexAlpha = 0;
textureAlpha = 0;
glDisable(GL_BLEND);
srcblend = BLENDSRCALPHA;
destblend = BLENDINVSRCALPHA;
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
zwrite = GL_TRUE;
glDepthMask(zwrite);
ztest = 1;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
for(int i = 0; i < 8; i++){
glActiveTexture(GL_TEXTURE0+i);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
void
setWorldMatrix(Matrix *mat)
{
uniformObject.world = *mat;
objectDirty = 1;
}
void
setAmbientLight(RGBAf *amb)
{
uniformObject.ambLight = *amb;
objectDirty = 1;
}
void
setNumLights(int32 n)
{
uniformObject.numLights = n;
objectDirty = 1;
}
void
setLight(int32 n, Light *light)
{
UniformLight *l;
Frame *f;
Matrix *m;
l = &uniformObject.lights[n];
f = light->getFrame();
if(f){
m = f->getLTM();
l->position = m->pos;
l->direction = m->at;
}
// light has position
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0;
l->color = light->color;
l->radius = light->radius;
l->minusCosAngle = light->minusCosAngle;
objectDirty = 1;
}
void
setProjectionMatrix(float32 *mat)
{
memcpy(&uniformScene.proj, mat, 64);
sceneDirty = 1;
}
void
setViewMatrix(float32 *mat)
{
memcpy(&uniformScene.view, mat, 64);
sceneDirty = 1;
}
void
setTexture(int32 n, Texture *tex)
{
bool32 alpha;
glActiveTexture(GL_TEXTURE0+n);
if(tex == nil){
glBindTexture(GL_TEXTURE_2D, whitetex);
alpha = 0;
}else{
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, tex->raster,
nativeRasterOffset);
glBindTexture(GL_TEXTURE_2D, natras->texid);
alpha = natras->hasAlpha;
}
if(textureAlpha != alpha){
textureAlpha = alpha;
if(textureAlpha)
glEnable(GL_BLEND);
else if(!vertexAlpha)
glDisable(GL_BLEND);
}
}
void
flushCache(void)
{
if(objectDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformObject),
&uniformObject);
objectDirty = 0;
}
if(sceneDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformScene),
&uniformScene);
sceneDirty = 0;
}
if(stateDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformState),
&uniformState);
stateDirty = 0;
}
}
void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
// View Matrix
Matrix inv;
// TODO: this can be simplified, or we use matrix flags....
Matrix::invert(&inv, cam->getFrame()->getLTM());
// Since we're looking into positive Z,
// flip X to ge a left handed view space.
view[0] = -inv.right.x;
view[1] = inv.right.y;
view[2] = inv.right.z;
view[3] = 0.0f;
view[4] = -inv.up.x;
view[5] = inv.up.y;
view[6] = inv.up.z;
view[7] = 0.0f;
view[8] = -inv.at.x;
view[9] = inv.at.y;
view[10] = inv.at.z;
view[11] = 0.0f;
view[12] = -inv.pos.x;
view[13] = inv.pos.y;
view[14] = inv.pos.z;
view[15] = 1.0f;
setViewMatrix(view);
// Projection Matrix
float32 invwx = 1.0f/cam->viewWindow.x;
float32 invwy = 1.0f/cam->viewWindow.y;
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
proj[0] = invwx;
proj[1] = 0.0f;
proj[2] = 0.0f;
proj[3] = 0.0f;
proj[4] = 0.0f;
proj[5] = invwy;
proj[6] = 0.0f;
proj[7] = 0.0f;
if(cam->projection == Camera::PERSPECTIVE){
proj[8] = cam->viewOffset.x*invwx;
proj[9] = cam->viewOffset.y*invwy;
proj[10] = (cam->farPlane+cam->nearPlane)*invz;
proj[11] = 1.0f;
proj[12] = 0.0f;
proj[13] = 0.0f;
proj[14] = -2.0f*cam->nearPlane*cam->farPlane*invz;
proj[15] = 0.0f;
}else{
// TODO
}
setProjectionMatrix(proj);
}
void
initializeRender(void)
{
driver[PLATFORM_GL3]->beginUpdate = beginUpdate;
driver[PLATFORM_GL3]->setRenderState = setRenderState;
driver[PLATFORM_GL3]->getRenderState = getRenderState;
simpleShader = Shader::fromFiles("simple.vert", "simple.frag");
glClearColor(0.25, 0.25, 0.25, 1.0);
resetRenderState();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &ubo_state);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), &uniformState,
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_scene);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformScene), &uniformScene,
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_object);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Object"), ubo_object);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), &uniformObject,
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);
}
}
}
#endif

View File

@@ -74,7 +74,7 @@ matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst)
setTexture(0, m->texture);
setVertexAlpha(inst->vertexAlpha || m->color.alpha != 0xFF);
rw::setRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
flushCache();
glDrawElements(header->primType, inst->numIndex,
@@ -173,15 +173,16 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst)
setTexture(0, env->tex);
setVertexAlpha(1);
glBlendFunc(GL_ONE, GL_ONE);
rw::setRenderState(VERTEXALPHA, 1);
rw::setRenderState(SRCBLEND, BLENDONE);
rw::setRenderState(DESTBLEND, BLENDONE);
flushCache();
glDrawElements(header->primType, inst->numIndex,
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
rw::setRenderState(SRCBLEND, BLENDSRCALPHA);
rw::setRenderState(DESTBLEND, BLENDINVSRCALPHA);
}
void
@@ -197,8 +198,8 @@ matfxRenderCB(Atomic *atomic, InstanceDataHeader *header)
InstanceData *inst = header->inst;
int32 n = header->numMeshes;
setAlphaTestFunc(1);
setAlphaRef(0.2);
rw::setRenderState(ALPHATESTFUNC, 1);
rw::setRenderState(ALPHATESTREF, 50);
int32 fx;
while(n--){
@@ -260,6 +261,11 @@ makeSkinPipeline(void)
return pipe;
}
#else
void initMatFX(void) { }
void initSkin(void) { }
#endif
}

View File

@@ -14,161 +14,13 @@
#include "rwgl3.h"
#include "rwgl3shader.h"
#include "rwgl3impl.h"
namespace rw {
namespace gl3 {
struct UniformState
{
int alphaFunc;
float32 alphaRef;
};
struct UniformScene
{
float32 proj[16];
float32 view[16];
};
struct UniformLight
{
V3d position;
float32 w;
V3d direction;
int32 pad1;
RGBAf color;
float32 radius;
float32 minusCosAngle;
int32 pad2[2];
};
#define MAX_LIGHTS 8
struct UniformObject
{
Matrix world;
RGBAf ambLight;
int32 numLights;
int32 pad[3];
UniformLight lights[MAX_LIGHTS];
};
GLuint vao;
GLuint ubo_state, ubo_scene, ubo_object;
GLuint whitetex;
UniformState uniformState;
UniformScene uniformScene;
UniformObject uniformObject;
Shader *simpleShader;
void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
// View Matrix
Matrix inv;
Matrix::invert(&inv, cam->getFrame()->getLTM());
// Since we're looking into positive Z,
// flip X to ge a left handed view space.
view[0] = -inv.right.x;
view[1] = inv.right.y;
view[2] = inv.right.z;
view[3] = 0.0f;
view[4] = -inv.up.x;
view[5] = inv.up.y;
view[6] = inv.up.z;
view[7] = 0.0f;
view[8] = -inv.at.x;
view[9] = inv.at.y;
view[10] = inv.at.z;
view[11] = 0.0f;
view[12] = -inv.pos.x;
view[13] = inv.pos.y;
view[14] = inv.pos.z;
view[15] = 1.0f;
setViewMatrix(view);
// Projection Matrix
float32 invwx = 1.0f/cam->viewWindow.x;
float32 invwy = 1.0f/cam->viewWindow.y;
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
proj[0] = invwx;
proj[1] = 0.0f;
proj[2] = 0.0f;
proj[3] = 0.0f;
proj[4] = 0.0f;
proj[5] = invwy;
proj[6] = 0.0f;
proj[7] = 0.0f;
if(cam->projection == Camera::PERSPECTIVE){
proj[8] = cam->viewOffset.x*invwx;
proj[9] = cam->viewOffset.y*invwy;
proj[10] = (cam->farPlane+cam->nearPlane)*invz;
proj[11] = 1.0f;
proj[12] = 0.0f;
proj[13] = 0.0f;
proj[14] = -2.0f*cam->nearPlane*cam->farPlane*invz;
proj[15] = 0.0f;
}else{
// TODO
}
setProjectionMatrix(proj);
}
void
initializeRender(void)
{
driver[PLATFORM_GL3]->beginUpdate = beginUpdate;
simpleShader = Shader::fromFiles("simple.vert", "simple.frag");
glClearColor(0.25, 0.25, 0.25, 1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &ubo_state);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), &uniformState,
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_scene);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformScene), &uniformScene,
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_object);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Object"), ubo_object);
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformObject), &uniformObject,
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);
}
void
setAttribPointers(InstanceDataHeader *header)
{
@@ -182,145 +34,6 @@ setAttribPointers(InstanceDataHeader *header)
}
}
static bool32 stateDirty = 1;
static bool32 sceneDirty = 1;
static bool32 objectDirty = 1;
void
setWorldMatrix(Matrix *mat)
{
uniformObject.world = *mat;
objectDirty = 1;
}
void
setAmbientLight(RGBAf *amb)
{
uniformObject.ambLight = *amb;
objectDirty = 1;
}
void
setNumLights(int32 n)
{
uniformObject.numLights = n;
objectDirty = 1;
}
void
setLight(int32 n, Light *light)
{
UniformLight *l;
Frame *f;
Matrix *m;
l = &uniformObject.lights[n];
f = light->getFrame();
if(f){
m = f->getLTM();
l->position = m->pos;
l->direction = m->at;
}
// light has position
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0;
l->color = light->color;
l->radius = light->radius;
l->minusCosAngle = light->minusCosAngle;
objectDirty = 1;
}
void
setProjectionMatrix(float32 *mat)
{
memcpy(&uniformScene.proj, mat, 64);
sceneDirty = 1;
}
void
setViewMatrix(float32 *mat)
{
memcpy(&uniformScene.view, mat, 64);
sceneDirty = 1;
}
static bool32 vertexAlpha;
static bool32 textureAlpha;
void
setTexture(int32 n, Texture *tex)
{
bool32 alpha;
glActiveTexture(GL_TEXTURE0+n);
if(tex == nil){
glBindTexture(GL_TEXTURE_2D, whitetex);
alpha = 0;
}else{
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, tex->raster,
nativeRasterOffset);
glBindTexture(GL_TEXTURE_2D, natras->texid);
alpha = natras->hasAlpha;
}
if(textureAlpha == alpha)
return;
if(alpha)
/*printf("enable\n"),*/ glEnable(GL_BLEND);
else if(!vertexAlpha)
/*printf("disable\n"),*/ glDisable(GL_BLEND);
textureAlpha = alpha;
}
void
setVertexAlpha(bool32 alpha)
{
if(vertexAlpha == alpha)
return;
if(alpha)
/*printf("enable\n"),*/ glEnable(GL_BLEND);
else if(!textureAlpha)
/*printf("disable\n"),*/ glDisable(GL_BLEND);
vertexAlpha = alpha;
}
void
setAlphaTestFunc(int32 f)
{
uniformState.alphaFunc = f;
stateDirty = 1;
}
void
setAlphaRef(float32 f)
{
uniformState.alphaRef = f;
stateDirty = 1;
}
#define U(s) currentShader->uniformLocations[findUniform(s)]
void
flushCache(void)
{
if(objectDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformObject),
&uniformObject);
objectDirty = 0;
}
if(sceneDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformScene),
&uniformScene);
sceneDirty = 0;
}
if(stateDirty){
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformState),
&uniformState);
stateDirty = 0;
}
}
void
lightingCB(void)
{
@@ -346,9 +59,16 @@ lightingCB(void)
setAmbientLight(&ambLight);
}
#define U(s) currentShader->uniformLocations[findUniform(s)]
void
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
{
Material *m;
RGBAf col;
GLfloat surfProps[4];
int id;
setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB();
@@ -356,15 +76,11 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
setAttribPointers(header);
Material *m;
RGBAf col;
GLfloat surfProps[4];
int id;
InstanceData *inst = header->inst;
int32 n = header->numMeshes;
setAlphaTestFunc(1);
setAlphaRef(0.2);
rw::setRenderState(ALPHATESTFUNC, 1);
rw::setRenderState(ALPHATESTREF, 50);
simpleShader->use();
@@ -382,7 +98,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
setTexture(0, m->texture);
setVertexAlpha(inst->vertexAlpha || m->color.alpha != 0xFF);
rw::setRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
flushCache();
glDrawElements(header->primType, inst->numIndex,

View File

@@ -61,8 +61,6 @@ struct InstanceDataHeader : rw::InstanceDataHeader
void setAttribPointers(InstanceDataHeader *header);
// Render state
void setAlphaTestFunc(int32 f);
void setAlphaRef(float32 f);
// per Scene
void setProjectionMatrix(float32*);
@@ -76,7 +74,6 @@ void setLight(int32 n, Light*);
// per Mesh
void setTexture(int32 n, Texture *tex);
void setVertexAlpha(bool32 enable);
void flushCache(void);

View File

@@ -24,7 +24,6 @@ namespace wdgl {
void*
driverOpen(void *o, int32, int32)
{
printf("wdgl open\n");
driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
return o;
}

View File

@@ -23,7 +23,6 @@ namespace ps2 {
void*
driverOpen(void *o, int32, int32)
{
printf("ps2 open\n");
driver[PLATFORM_PS2]->defaultPipeline = makeDefaultPipeline();
driver[PLATFORM_PS2]->rasterNativeOffset = nativeRasterOffset;

View File

@@ -1,5 +1,51 @@
namespace rw {
enum RenderState
{
VERTEXALPHA = 0,
SRCBLEND,
DESTBLEND,
ZTESTENABLE,
ZWRITEENABLE,
// TODO:
// fog enable, color, type, density
// ? cullmode
// ? shademode
// ???? stencil
// platform specific or opaque?
ALPHATESTFUNC,
ALPHATESTREF,
ZTESTFUNC,
};
enum AlphaTestFunc
{
ALPHANEVER = 0,
ALPHALESS,
ALPHAGREATERTHAN
};
enum BlendFunction
{
BLENDZERO = 0,
BLENDONE,
BLENDSRCCOLOR,
BLENDINVSRCCOLOR,
BLENDSRCALPHA,
BLENDINVSRCALPHA,
BLENDDESTALPHA,
BLENDINVDESTALPHA,
BLENDDESTCOLOR,
BLENDINVDESTCOLOR,
BLENDSRCALPHASAT,
// TODO: add more perhaps
};
enum ZTestFunc
{
};
// This is for platform independent things
// TODO: move more stuff into this
struct Engine
@@ -21,6 +67,9 @@ struct Driver
void (*beginUpdate)(Camera*);
void (*endUpdate)(Camera*);
void (*setRenderState)(int32 state, uint32 value);
uint32 (*getRenderState)(int32 state);
void (*rasterCreate)(Raster*);
uint8 *(*rasterLock)(Raster*, int32 level);
void (*rasterUnlock)(Raster*, int32 level);
@@ -39,10 +88,19 @@ struct Driver
extern Driver *driver[NUM_PLATFORMS];
#define DRIVER driver[rw::platform]
inline void setRenderState(int32 state, uint32 value){
DRIVER->setRenderState(state, value); }
inline uint32 getRenderState(int32 state){
return DRIVER->getRenderState(state); }
namespace null {
void beginUpdate(Camera*);
void endUpdate(Camera*);
void setRenderState(int32 state, uint32 value);
uint32 getRenderState(int32 state);
void rasterCreate(Raster*);
uint8 *rasterLock(Raster*, int32 level);
void rasterUnlock(Raster*, int32 level);

View File

@@ -560,7 +560,6 @@ struct Camera : PluginBase<Camera>
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
void updateProjectionMatrix(void);
// fov in degrees
void setFOV(float32 fov, float32 ratio);
};