mirror of https://github.com/aap/librw.git
hacked lighting into im3d
This commit is contained in:
parent
d2f54a2471
commit
f7e7841e1c
|
@ -236,8 +236,9 @@ static int32 num3DVertices;
|
|||
void
|
||||
openIm3D(void)
|
||||
{
|
||||
D3DVERTEXELEMENT9 elements[4] = {
|
||||
D3DVERTEXELEMENT9 elements[5] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, offsetof(Im3DVertex, normal), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
|
||||
{ 0, offsetof(Im3DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
|
||||
{ 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
D3DDECL_END()
|
||||
|
@ -273,6 +274,10 @@ closeIm3D(void)
|
|||
im3dindbuf = nil;
|
||||
}
|
||||
|
||||
// settable by user - TOOD: make this less shit
|
||||
RGBA im3dMaterialColor = { 255, 255, 255, 255 };
|
||||
SurfaceProperties im3dSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
void
|
||||
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
||||
{
|
||||
|
@ -284,9 +289,22 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
|||
if((flags & im3d::VERTEXUV) == 0)
|
||||
SetRenderStatePtr(TEXTURERASTER, nil);
|
||||
|
||||
void *shader = default_amb_VS;
|
||||
if(flags & im3d::LIGHTING){
|
||||
setMaterial(im3dMaterialColor, im3dSurfaceProps);
|
||||
int32 vsBits = lightingCB_Shader();
|
||||
// Pick a shader
|
||||
if((vsBits & VSLIGHT_MASK) == 0)
|
||||
shader = default_amb_VS;
|
||||
else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT)
|
||||
shader = default_amb_dir_VS;
|
||||
else
|
||||
shader = default_all_VS;
|
||||
}else{
|
||||
static RGBA white = { 255, 255, 255, 255 };
|
||||
static SurfaceProperties surfprops = { 0.0f, 0.0f, 0.0f };
|
||||
setMaterial(white, surfprops);
|
||||
}
|
||||
|
||||
uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_DISCARD);
|
||||
memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex));
|
||||
|
@ -295,7 +313,7 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
|||
setStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex));
|
||||
setVertexDeclaration(im3ddecl);
|
||||
|
||||
setVertexShader(default_amb_VS);
|
||||
setVertexShader(shader);
|
||||
|
||||
num3DVertices = numVertices;
|
||||
}
|
||||
|
|
|
@ -357,11 +357,6 @@ lightingCB_Shader(Atomic *atomic)
|
|||
if(atomic->geometry->flags & rw::Geometry::LIGHT){
|
||||
((World*)engine->currentWorld)->enumerateLights(atomic, &lightData);
|
||||
setAmbient(lightData.ambient);
|
||||
if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){
|
||||
// Get rid of lights that need normals when we don't have any
|
||||
lightData.numDirectionals = 0;
|
||||
lightData.numLocals = 0;
|
||||
}
|
||||
return uploadLights(&lightData);
|
||||
}else{
|
||||
static const RGBAf black = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
@ -371,6 +366,22 @@ lightingCB_Shader(Atomic *atomic)
|
|||
}
|
||||
}
|
||||
|
||||
int32
|
||||
lightingCB_Shader(void)
|
||||
{
|
||||
WorldLights lightData;
|
||||
Light *directionals[8];
|
||||
Light *locals[8];
|
||||
lightData.directionals = directionals;
|
||||
lightData.numDirectionals = 8;
|
||||
lightData.locals = locals;
|
||||
lightData.numLocals = 8;
|
||||
|
||||
((World*)engine->currentWorld)->enumerateLights(&lightData);
|
||||
setAmbient(lightData.ambient);
|
||||
return uploadLights(&lightData);
|
||||
}
|
||||
|
||||
static RawMatrix identityXform = {
|
||||
{ 1.0f, 0.0f, 0.0f }, 0.0f,
|
||||
{ 0.0f, 1.0f, 0.0f }, 0.0f,
|
||||
|
|
|
@ -42,12 +42,16 @@ void setD3dMaterial(D3DMATERIAL9 *mat9);
|
|||
struct Im3DVertex
|
||||
{
|
||||
V3d position;
|
||||
V3d normal; // librw extension
|
||||
uint32 color;
|
||||
float32 u, v;
|
||||
|
||||
void setX(float32 x) { this->position.x = x; }
|
||||
void setY(float32 y) { this->position.y = y; }
|
||||
void setZ(float32 z) { this->position.z = z; }
|
||||
void setNormalX(float32 x) { this->normal.x = x; }
|
||||
void setNormalY(float32 y) { this->normal.y = y; }
|
||||
void setNormalZ(float32 z) { this->normal.z = z; }
|
||||
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); }
|
||||
void setU(float32 u) { this->u = u; }
|
||||
void setV(float32 v) { this->v = v; }
|
||||
|
@ -55,11 +59,16 @@ struct Im3DVertex
|
|||
float getX(void) { return this->position.x; }
|
||||
float getY(void) { return this->position.y; }
|
||||
float getZ(void) { return this->position.z; }
|
||||
float getNormalX(void) { return this->normal.x; }
|
||||
float getNormalY(void) { return this->normal.y; }
|
||||
float getNormalZ(void) { return this->normal.z; }
|
||||
RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF,
|
||||
this->color & 0xFF, this->color>>24 & 0xFF); }
|
||||
float getU(void) { return this->u; }
|
||||
float getV(void) { return this->v; }
|
||||
};
|
||||
extern RGBA im3dMaterialColor;
|
||||
extern SurfaceProperties im3dSurfaceProps;
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
|
@ -386,6 +395,7 @@ enum
|
|||
|
||||
void lightingCB_Fix(Atomic *atomic);
|
||||
int32 lightingCB_Shader(Atomic *atomic);
|
||||
int32 lightingCB_Shader(void);
|
||||
// for VS
|
||||
void uploadMatrices(void); // no world transform
|
||||
void uploadMatrices(Matrix *worldMat);
|
||||
|
|
|
@ -193,9 +193,11 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||
|
||||
|
||||
static Shader *im3dShader;
|
||||
static AttribDesc im3dattribDesc[3] = {
|
||||
static AttribDesc im3dattribDesc[4] = {
|
||||
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 3,
|
||||
sizeof(Im3DVertex), 0 },
|
||||
{ ATTRIB_NORMAL, GL_FLOAT, GL_FALSE, 3,
|
||||
sizeof(Im3DVertex), offsetof(Im3DVertex, normal) },
|
||||
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||
sizeof(Im3DVertex), offsetof(Im3DVertex, r) },
|
||||
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||
|
@ -228,7 +230,7 @@ openIm3D(void)
|
|||
#ifdef RW_GL_USE_VAOS
|
||||
glGenVertexArrays(1, &im3DVao);
|
||||
glBindVertexArray(im3DVao);
|
||||
setAttribPointers(im3dattribDesc, 3);
|
||||
setAttribPointers(im3dattribDesc, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -244,6 +246,10 @@ closeIm3D(void)
|
|||
im3dShader = nil;
|
||||
}
|
||||
|
||||
// settable by user - TOOD: make this less shit
|
||||
RGBA im3dMaterialColor = { 255, 255, 255, 255 };
|
||||
SurfaceProperties im3dSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
void
|
||||
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
||||
{
|
||||
|
@ -253,6 +259,11 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
|||
world = &ident;
|
||||
}
|
||||
setWorldMatrix(world);
|
||||
if(flags & im3d::LIGHTING){
|
||||
setMaterial(im3dMaterialColor, im3dSurfaceProps);
|
||||
int32 vsBits = lightingCB();
|
||||
defaultShader_fullLight->use();
|
||||
}else
|
||||
im3dShader->use();
|
||||
|
||||
if((flags & im3d::VERTEXUV) == 0)
|
||||
|
@ -266,7 +277,7 @@ im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
|||
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im3DVertex), vertices);
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
setAttribPointers(im3dattribDesc, 3);
|
||||
setAttribPointers(im3dattribDesc, 4);
|
||||
#endif
|
||||
num3DVertices = numVertices;
|
||||
}
|
||||
|
@ -296,7 +307,7 @@ void
|
|||
im3DEnd(void)
|
||||
{
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(im3dattribDesc, 3);
|
||||
disableAttribPointers(im3dattribDesc, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -121,20 +121,29 @@ lightingCB(Atomic *atomic)
|
|||
lightData.locals = locals;
|
||||
lightData.numLocals = 8;
|
||||
|
||||
if(atomic->geometry->flags & rw::Geometry::LIGHT){
|
||||
if(atomic->geometry->flags & rw::Geometry::LIGHT)
|
||||
((World*)engine->currentWorld)->enumerateLights(atomic, &lightData);
|
||||
if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){
|
||||
// Get rid of lights that need normals when we don't have any
|
||||
lightData.numDirectionals = 0;
|
||||
lightData.numLocals = 0;
|
||||
}
|
||||
return setLights(&lightData);
|
||||
}else{
|
||||
else
|
||||
memset(&lightData, 0, sizeof(lightData));
|
||||
return setLights(&lightData);
|
||||
}
|
||||
|
||||
int32
|
||||
lightingCB(void)
|
||||
{
|
||||
WorldLights lightData;
|
||||
Light *directionals[8];
|
||||
Light *locals[8];
|
||||
lightData.directionals = directionals;
|
||||
lightData.numDirectionals = 8;
|
||||
lightData.locals = locals;
|
||||
lightData.numLocals = 8;
|
||||
|
||||
((World*)engine->currentWorld)->enumerateLights(&lightData);
|
||||
return setLights(&lightData);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ registerUniform(const char *name, UniformType type, int32 num)
|
|||
{
|
||||
int i;
|
||||
i = findUniform(name);
|
||||
if(type == UNIFORM_NA)
|
||||
num = 0;
|
||||
if(i >= 0){
|
||||
Uniform *u = &uniformRegistry.uniforms[i];
|
||||
assert(u->type == type);
|
||||
|
|
|
@ -103,12 +103,16 @@ extern Shader *defaultShader_fullLight, *defaultShader_fullLight_noAT;
|
|||
struct Im3DVertex
|
||||
{
|
||||
V3d position;
|
||||
V3d normal; // librw extension
|
||||
uint8 r, g, b, a;
|
||||
float32 u, v;
|
||||
|
||||
void setX(float32 x) { this->position.x = x; }
|
||||
void setY(float32 y) { this->position.y = y; }
|
||||
void setZ(float32 z) { this->position.z = z; }
|
||||
void setNormalX(float32 x) { this->normal.x = x; }
|
||||
void setNormalY(float32 y) { this->normal.y = y; }
|
||||
void setNormalZ(float32 z) { this->normal.z = z; }
|
||||
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; }
|
||||
|
@ -117,10 +121,15 @@ struct Im3DVertex
|
|||
float getX(void) { return this->position.x; }
|
||||
float getY(void) { return this->position.y; }
|
||||
float getZ(void) { return this->position.z; }
|
||||
float getNormalX(void) { return this->normal.x; }
|
||||
float getNormalY(void) { return this->normal.y; }
|
||||
float getNormalZ(void) { return this->normal.z; }
|
||||
RGBA getColor(void) { return makeRGBA(this->r, this->g, this->b, this->a); }
|
||||
float getU(void) { return this->u; }
|
||||
float getV(void) { return this->v; }
|
||||
};
|
||||
extern RGBA im3dMaterialColor;
|
||||
extern SurfaceProperties im3dSurfaceProps;
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
|
@ -221,6 +230,7 @@ void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinsta
|
|||
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||
int32 lightingCB(Atomic *atomic);
|
||||
int32 lightingCB(void);
|
||||
|
||||
void drawInst_simple(InstanceDataHeader *header, InstanceData *inst);
|
||||
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
|
||||
|
|
|
@ -8,8 +8,7 @@ void
|
|||
main(void)
|
||||
{
|
||||
vec4 Vertex = u_world * vec4(in_pos, 1.0);
|
||||
vec4 CamVertex = u_view * Vertex;
|
||||
gl_Position = u_proj * CamVertex;
|
||||
gl_Position = u_proj * u_view * Vertex;
|
||||
v_color = in_color;
|
||||
v_tex0 = in_tex0;
|
||||
v_fog = DoFog(gl_Position.w);
|
||||
|
|
|
@ -9,8 +9,7 @@ const char *im3d_vert_src =
|
|||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
|
||||
" vec4 CamVertex = u_view * Vertex;\n"
|
||||
" gl_Position = u_proj * CamVertex;\n"
|
||||
" gl_Position = u_proj * u_view * Vertex;\n"
|
||||
" v_color = in_color;\n"
|
||||
" v_tex0 = in_tex0;\n"
|
||||
" v_fog = DoFog(gl_Position.w);\n"
|
||||
|
|
|
@ -12,4 +12,3 @@ main(void)
|
|||
DoAlphaTest(color.a);
|
||||
FRAGCOLOR(color);
|
||||
}
|
||||
|
||||
|
|
|
@ -872,6 +872,7 @@ struct World
|
|||
void removeClump(Clump *clump);
|
||||
void render(void);
|
||||
void enumerateLights(Atomic *atomic, WorldLights *lightData);
|
||||
void enumerateLights(WorldLights *lightData);
|
||||
};
|
||||
|
||||
struct TexDictionary
|
||||
|
|
|
@ -123,6 +123,7 @@ enum TransformFlags
|
|||
NOCLIP = 4, // don't frustum clip
|
||||
VERTEXXYZ = 8, // has position
|
||||
VERTEXRGBA = 16, // has color
|
||||
LIGHTING = 32, // do lighting, assumes normals (librw extension)
|
||||
EVERYTHING = VERTEXUV|VERTEXXYZ|VERTEXRGBA
|
||||
};
|
||||
|
||||
|
|
|
@ -195,4 +195,44 @@ World::enumerateLights(Atomic *atomic, WorldLights *lightData)
|
|||
}
|
||||
}
|
||||
|
||||
// Find all lights, for im3d lighting extension
|
||||
// missing flags and bounding spheres so more primitive than above
|
||||
void
|
||||
World::enumerateLights(WorldLights *lightData)
|
||||
{
|
||||
int32 maxDirectionals, maxLocals;
|
||||
|
||||
maxDirectionals = lightData->numDirectionals;
|
||||
maxLocals = lightData->numLocals;
|
||||
|
||||
lightData->numDirectionals = 0;
|
||||
lightData->numLocals = 0;
|
||||
lightData->numAmbients = 0;
|
||||
lightData->ambient.red = 0.0f;
|
||||
lightData->ambient.green = 0.0f;
|
||||
lightData->ambient.blue = 0.0f;
|
||||
lightData->ambient.alpha = 1.0f;
|
||||
|
||||
FORLIST(lnk, this->globalLights){
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
if(l->getType() == Light::AMBIENT){
|
||||
lightData->ambient.red += l->color.red;
|
||||
lightData->ambient.green += l->color.green;
|
||||
lightData->ambient.blue += l->color.blue;
|
||||
lightData->numAmbients++;
|
||||
}else if(l->getType() == Light::DIRECTIONAL){
|
||||
if(lightData->numDirectionals < maxDirectionals)
|
||||
lightData->directionals[lightData->numDirectionals++] = l;
|
||||
}
|
||||
}
|
||||
|
||||
FORLIST(lnk, this->localLights){
|
||||
if(lightData->numLocals >= maxLocals)
|
||||
return;
|
||||
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
lightData->locals[lightData->numLocals++] = l;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue