hacked lighting into im3d

This commit is contained in:
aap 2022-09-22 17:59:20 +02:00
parent d2f54a2471
commit f7e7841e1c
13 changed files with 140 additions and 30 deletions

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -12,4 +12,3 @@ main(void)
DoAlphaTest(color.a);
FRAGCOLOR(color);
}

View File

@ -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

View File

@ -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
};

View File

@ -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;
}
}
}