librw/src/gl/gl3matfx.cpp

222 lines
4.7 KiB
C++
Raw Normal View History

2020-04-30 17:54:38 +02:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
2017-08-29 10:12:56 +02:00
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwrender.h"
#include "../rwengine.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwplugins.h"
2021-01-31 13:48:59 +01:00
2017-08-29 10:12:56 +02:00
#include "rwgl3.h"
#include "rwgl3shader.h"
#include "rwgl3plg.h"
#include "rwgl3impl.h"
namespace rw {
namespace gl3 {
#ifdef RW_OPENGL
static Shader *envShader;
static int32 u_texMatrix;
2020-05-27 10:26:28 +02:00
static int32 u_fxparams;
2020-04-29 21:31:29 +02:00
static int32 u_colorClamp;
2021-02-26 17:20:20 +01:00
static int32 u_envColor;
2017-08-29 10:12:56 +02:00
void
matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst, uint32 flags)
2017-08-29 10:12:56 +02:00
{
Material *m;
m = inst->material;
2020-04-26 19:33:43 +02:00
defaultShader->use();
2017-08-29 10:12:56 +02:00
setMaterial(flags, m->color, m->surfaceProps);
2017-08-29 10:12:56 +02:00
setTexture(0, m->texture);
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
2020-04-28 14:09:26 +02:00
drawInst(header, inst);
2017-08-29 10:12:56 +02:00
}
2020-04-26 19:33:43 +02:00
static Frame *lastEnvFrame;
static RawMatrix normal2texcoord = {
{ 0.5f, 0.0f, 0.0f }, 0.0f,
{ 0.0f, -0.5f, 0.0f }, 0.0f,
{ 0.0f, 0.0f, 1.0f }, 0.0f,
{ 0.5f, 0.5f, 0.0f }, 1.0f
};
2017-08-29 10:12:56 +02:00
void
2020-04-26 19:33:43 +02:00
uploadEnvMatrix(Frame *frame)
2017-08-29 10:12:56 +02:00
{
2020-04-26 19:33:43 +02:00
Matrix invMat;
if(frame == nil)
frame = engine->currentCamera->getFrame();
// cache the matrix across multiple meshes
static RawMatrix envMtx;
// can't do it, frame matrix may change
// if(frame != lastEnvFrame){
// lastEnvFrame = frame;
{
2020-04-26 19:33:43 +02:00
RawMatrix invMtx;
Matrix::invert(&invMat, frame->getLTM());
convMatrix(&invMtx, &invMat);
2020-05-15 13:34:19 +02:00
invMtx.pos.set(0.0f, 0.0f, 0.0f);
2021-02-26 17:20:20 +01:00
float uscale = fabs(normal2texcoord.right.x);
normal2texcoord.right.x = MatFX::envMapFlipU ? -uscale : uscale;
2020-04-26 19:33:43 +02:00
RawMatrix::mult(&envMtx, &invMtx, &normal2texcoord);
2017-08-29 10:12:56 +02:00
}
2021-02-19 23:32:15 +01:00
setUniform(u_texMatrix, &envMtx);
2017-08-29 10:12:56 +02:00
}
void
matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, uint32 flags, MatFX::Env *env)
2017-08-29 10:12:56 +02:00
{
Material *m;
m = inst->material;
2020-04-26 19:33:43 +02:00
if(env->tex == nil || env->coefficient == 0.0f){
matfxDefaultRender(header, inst, flags);
2020-04-26 19:33:43 +02:00
return;
}
2017-08-29 10:12:56 +02:00
envShader->use();
2020-04-26 19:33:43 +02:00
setTexture(0, m->texture);
setTexture(1, env->tex);
uploadEnvMatrix(env->frame);
setMaterial(flags, m->color, m->surfaceProps);
2017-08-29 10:12:56 +02:00
2021-02-19 23:32:15 +01:00
float fxparams[4];
2020-05-27 10:26:28 +02:00
fxparams[0] = env->coefficient;
fxparams[1] = env->fbAlpha ? 0.0f : 1.0f;
2021-02-19 23:32:15 +01:00
fxparams[2] = fxparams[3] = 0.0f;
2020-05-27 10:26:28 +02:00
2021-02-19 23:32:15 +01:00
setUniform(u_fxparams, fxparams);
2020-04-29 21:31:29 +02:00
static float zero[4];
static float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
// This clamps the vertex color below. With it we can achieve both PC and PS2 style matfx
2021-02-26 17:20:20 +01:00
if(MatFX::envMapApplyLight)
2021-02-19 23:32:15 +01:00
setUniform(u_colorClamp, zero);
2020-04-29 21:31:29 +02:00
else
2021-02-19 23:32:15 +01:00
setUniform(u_colorClamp, one);
2021-02-26 17:20:20 +01:00
RGBAf envcol[4];
if(MatFX::envMapUseMatColor)
convColor(envcol, &m->color);
else
convColor(envcol, &MatFX::envMapColor);
setUniform(u_envColor, envcol);
2017-08-29 10:12:56 +02:00
rw::SetRenderState(VERTEXALPHA, 1);
rw::SetRenderState(SRCBLEND, BLENDONE);
2020-04-28 14:09:26 +02:00
drawInst(header, inst);
2017-08-29 10:12:56 +02:00
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
}
void
matfxRenderCB(Atomic *atomic, InstanceDataHeader *header)
{
uint32 flags = atomic->geometry->flags;
2017-08-29 10:12:56 +02:00
setWorldMatrix(atomic->getFrame()->getLTM());
2020-04-26 19:33:43 +02:00
lightingCB(atomic);
2017-08-29 10:12:56 +02:00
2021-02-18 01:57:41 +01:00
setupVertexInput(header);
2017-08-29 10:12:56 +02:00
2020-04-26 19:33:43 +02:00
lastEnvFrame = nil;
2017-08-29 10:12:56 +02:00
InstanceData *inst = header->inst;
int32 n = header->numMeshes;
while(n--){
2020-04-26 19:33:43 +02:00
MatFX *matfx = MatFX::get(inst->material);
if(matfx == nil)
matfxDefaultRender(header, inst, flags);
2020-04-26 19:33:43 +02:00
else switch(matfx->type){
2017-08-29 10:12:56 +02:00
case MatFX::ENVMAP:
matfxEnvRender(header, inst, flags, &matfx->fx[0].env);
2017-08-29 10:12:56 +02:00
break;
default:
matfxDefaultRender(header, inst, flags);
2020-04-26 19:33:43 +02:00
break;
2017-08-29 10:12:56 +02:00
}
inst++;
}
2021-02-18 01:57:41 +01:00
teardownVertexInput(header);
2017-08-29 10:12:56 +02:00
}
ObjPipeline*
makeMatFXPipeline(void)
{
2020-08-14 13:54:44 +02:00
ObjPipeline *pipe = ObjPipeline::create();
2017-08-29 10:12:56 +02:00
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = matfxRenderCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
2020-08-14 13:54:44 +02:00
static void*
matfxOpen(void *o, int32, int32)
{
matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline();
#include "shaders/matfx_gl.inc"
2020-08-14 13:54:44 +02:00
const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, matfx_env_frag_src, nil };
envShader = Shader::create(vs, fs);
assert(envShader);
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_GL3])->destroy();
matFXGlobals.pipelines[PLATFORM_GL3] = nil;
envShader->destroy();
envShader = nil;
return o;
}
void
initMatFX(void)
{
2021-02-19 23:32:15 +01:00
u_texMatrix = registerUniform("u_texMatrix", UNIFORM_MAT4);
u_fxparams = registerUniform("u_fxparams", UNIFORM_VEC4);
u_colorClamp = registerUniform("u_colorClamp", UNIFORM_VEC4);
2021-02-26 17:20:20 +01:00
u_envColor = registerUniform("u_envColor", UNIFORM_VEC4);
2020-08-14 13:54:44 +02:00
Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX,
matfxOpen, matfxClose);
}
2017-08-29 10:12:56 +02:00
#else
void initMatFX(void) { }
#endif
}
}
2017-08-29 14:05:45 +02:00