mirror of
https://gitlab.com/shinovon/re3-symbian.git
synced 2026-05-23 01:57:21 +03:00
Initial commit
This commit is contained in:
commit
77cdaaf97e
827 changed files with 418745 additions and 0 deletions
56
vendor/librw/src/gl/gl3.cpp
vendored
Normal file
56
vendor/librw/src/gl/gl3.cpp
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
|
||||
#include "rwgl3impl.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
// TODO: make some of these things platform-independent
|
||||
|
||||
static void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
#ifdef RW_OPENGL
|
||||
engine->driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
|
||||
#endif
|
||||
engine->driver[PLATFORM_GL3]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_GL3]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_GL3]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_GL3]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_GL3]->imageFindRasterFormat = imageFindRasterFormat;
|
||||
engine->driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_GL3]->rasterToImage = rasterToImage;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
driverClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
registerPlatformPlugins(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_GL3, 0, PLATFORM_GL3,
|
||||
driverOpen, driverClose);
|
||||
registerNativeRaster();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
2111
vendor/librw/src/gl/gl3device.cpp
vendored
Normal file
2111
vendor/librw/src/gl/gl3device.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
306
vendor/librw/src/gl/gl3immed.cpp
vendored
Normal file
306
vendor/librw/src/gl/gl3immed.cpp
vendored
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3impl.h"
|
||||
#include "rwgl3shader.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
uint32 im2DVbo, im2DIbo;
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
uint32 im2DVao;
|
||||
#endif
|
||||
|
||||
Shader *im2dOverrideShader;
|
||||
|
||||
static int32 u_xform;
|
||||
|
||||
#define STARTINDICES 10000
|
||||
#define STARTVERTICES 10000
|
||||
|
||||
static Shader *im2dShader;
|
||||
static AttribDesc im2dattribDesc[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, u) },
|
||||
};
|
||||
|
||||
static int primTypeMap[] = {
|
||||
GL_POINTS, // invalid
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_POINTS
|
||||
};
|
||||
|
||||
void
|
||||
openIm2D(void)
|
||||
{
|
||||
// must already be registered by device. we just need the value
|
||||
u_xform = registerUniform("u_xform", UNIFORM_VEC4);
|
||||
|
||||
#include "shaders/im2d_gl.inc"
|
||||
#include "shaders/simple_fs_gl.inc"
|
||||
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
|
||||
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
|
||||
im2dShader = Shader::create(vs, fs);
|
||||
assert(im2dShader);
|
||||
|
||||
glGenBuffers(1, &im2DIbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW);
|
||||
|
||||
glGenBuffers(1, &im2DVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im2DVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW);
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glGenVertexArrays(1, &im2DVao);
|
||||
glBindVertexArray(im2DVao);
|
||||
setAttribPointers(im2dattribDesc, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
closeIm2D(void)
|
||||
{
|
||||
glDeleteBuffers(1, &im2DIbo);
|
||||
glDeleteBuffers(1, &im2DVbo);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glDeleteVertexArrays(1, &im2DVao);
|
||||
#endif
|
||||
im2dShader->destroy();
|
||||
im2dShader = nil;
|
||||
}
|
||||
|
||||
static Im2DVertex tmpprimbuf[3];
|
||||
|
||||
void
|
||||
im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2)
|
||||
{
|
||||
Im2DVertex *verts = (Im2DVertex*)vertices;
|
||||
tmpprimbuf[0] = verts[vert1];
|
||||
tmpprimbuf[1] = verts[vert2];
|
||||
im2DRenderPrimitive(PRIMTYPELINELIST, tmpprimbuf, 2);
|
||||
}
|
||||
|
||||
void
|
||||
im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3)
|
||||
{
|
||||
Im2DVertex *verts = (Im2DVertex*)vertices;
|
||||
tmpprimbuf[0] = verts[vert1];
|
||||
tmpprimbuf[1] = verts[vert2];
|
||||
tmpprimbuf[2] = verts[vert3];
|
||||
im2DRenderPrimitive(PRIMTYPETRILIST, tmpprimbuf, 3);
|
||||
}
|
||||
|
||||
void
|
||||
im2DSetXform(void)
|
||||
{
|
||||
GLfloat xform[4];
|
||||
Camera *cam;
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
xform[0] = 2.0f/cam->frameBuffer->width;
|
||||
xform[1] = -2.0f/cam->frameBuffer->height;
|
||||
xform[2] = -1.0f;
|
||||
xform[3] = 1.0f;
|
||||
setUniform(u_xform, xform);
|
||||
// glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||
}
|
||||
|
||||
void
|
||||
im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices)
|
||||
{
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(im2DVao);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im2DVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertex), vertices);
|
||||
|
||||
if(im2dOverrideShader)
|
||||
im2dOverrideShader->use();
|
||||
else
|
||||
im2dShader->use();
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
setAttribPointers(im2dattribDesc, 3);
|
||||
#endif
|
||||
|
||||
im2DSetXform();
|
||||
|
||||
flushCache();
|
||||
glDrawArrays(primTypeMap[primType], 0, numVertices);
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(im2dattribDesc, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices,
|
||||
void *indices, int32 numIndices)
|
||||
{
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(im2DVao);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im2DVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertex), vertices);
|
||||
|
||||
if(im2dOverrideShader)
|
||||
im2dOverrideShader->use();
|
||||
else
|
||||
im2dShader->use();
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
setAttribPointers(im2dattribDesc, 3);
|
||||
#endif
|
||||
|
||||
im2DSetXform();
|
||||
|
||||
flushCache();
|
||||
glDrawElements(primTypeMap[primType], numIndices,
|
||||
GL_UNSIGNED_SHORT, nil);
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(im2dattribDesc, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Im3D
|
||||
|
||||
|
||||
static Shader *im3dShader;
|
||||
static AttribDesc im3dattribDesc[3] = {
|
||||
{ ATTRIB_POS, GL_FLOAT, GL_FALSE, 3,
|
||||
sizeof(Im3DVertex), 0 },
|
||||
{ ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||
sizeof(Im3DVertex), offsetof(Im3DVertex, r) },
|
||||
{ ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||
sizeof(Im3DVertex), offsetof(Im3DVertex, u) },
|
||||
};
|
||||
static uint32 im3DVbo, im3DIbo;
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
static uint32 im3DVao;
|
||||
#endif
|
||||
static int32 num3DVertices; // not actually needed here
|
||||
|
||||
void
|
||||
openIm3D(void)
|
||||
{
|
||||
#include "shaders/im3d_gl.inc"
|
||||
#include "shaders/simple_fs_gl.inc"
|
||||
const char *vs[] = { shaderDecl, header_vert_src, im3d_vert_src, nil };
|
||||
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
|
||||
im3dShader = Shader::create(vs, fs);
|
||||
assert(im3dShader);
|
||||
|
||||
glGenBuffers(1, &im3DIbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW);
|
||||
|
||||
glGenBuffers(1, &im3DVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im3DVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), nil, GL_STREAM_DRAW);
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glGenVertexArrays(1, &im3DVao);
|
||||
glBindVertexArray(im3DVao);
|
||||
setAttribPointers(im3dattribDesc, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
closeIm3D(void)
|
||||
{
|
||||
glDeleteBuffers(1, &im3DIbo);
|
||||
glDeleteBuffers(1, &im3DVbo);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glDeleteVertexArrays(1, &im3DVao);
|
||||
#endif
|
||||
im3dShader->destroy();
|
||||
im3dShader = nil;
|
||||
}
|
||||
|
||||
void
|
||||
im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags)
|
||||
{
|
||||
if(world == nil){
|
||||
static Matrix ident;
|
||||
ident.setIdentity();
|
||||
world = &ident;
|
||||
}
|
||||
setWorldMatrix(world);
|
||||
im3dShader->use();
|
||||
|
||||
if((flags & im3d::VERTEXUV) == 0)
|
||||
SetRenderStatePtr(TEXTURERASTER, nil);
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(im2DVao);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im3DVbo);
|
||||
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);
|
||||
#endif
|
||||
num3DVertices = numVertices;
|
||||
}
|
||||
|
||||
void
|
||||
im3DRenderPrimitive(PrimitiveType primType)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo);
|
||||
|
||||
flushCache();
|
||||
glDrawArrays(primTypeMap[primType], 0, num3DVertices);
|
||||
}
|
||||
|
||||
void
|
||||
im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(primTypeMap[primType], numIndices,
|
||||
GL_UNSIGNED_SHORT, nil);
|
||||
}
|
||||
|
||||
void
|
||||
im3DEnd(void)
|
||||
{
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(im3dattribDesc, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
258
vendor/librw/src/gl/gl3matfx.cpp
vendored
Normal file
258
vendor/librw/src/gl/gl3matfx.cpp
vendored
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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"
|
||||
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
#include "rwgl3plg.h"
|
||||
|
||||
#include "rwgl3impl.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
static Shader *envShader, *envShader_noAT;
|
||||
static Shader *envShader_fullLight, *envShader_fullLight_noAT;
|
||||
static int32 u_texMatrix;
|
||||
static int32 u_fxparams;
|
||||
static int32 u_colorClamp;
|
||||
static int32 u_envColor;
|
||||
|
||||
void
|
||||
matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst, int32 vsBits, uint32 flags)
|
||||
{
|
||||
Material *m;
|
||||
m = inst->material;
|
||||
|
||||
setMaterial(flags, m->color, m->surfaceProps);
|
||||
|
||||
setTexture(0, m->texture);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
if((vsBits & VSLIGHT_MASK) == 0){
|
||||
if(getAlphaTest())
|
||||
defaultShader->use();
|
||||
else
|
||||
defaultShader_noAT->use();
|
||||
}else{
|
||||
if(getAlphaTest())
|
||||
defaultShader_fullLight->use();
|
||||
else
|
||||
defaultShader_fullLight_noAT->use();
|
||||
}
|
||||
|
||||
drawInst(header, inst);
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
void
|
||||
uploadEnvMatrix(Frame *frame)
|
||||
{
|
||||
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;
|
||||
{
|
||||
|
||||
RawMatrix invMtx;
|
||||
Matrix::invert(&invMat, frame->getLTM());
|
||||
convMatrix(&invMtx, &invMat);
|
||||
invMtx.pos.set(0.0f, 0.0f, 0.0f);
|
||||
float uscale = fabs(normal2texcoord.right.x);
|
||||
normal2texcoord.right.x = MatFX::envMapFlipU ? -uscale : uscale;
|
||||
RawMatrix::mult(&envMtx, &invMtx, &normal2texcoord);
|
||||
}
|
||||
setUniform(u_texMatrix, &envMtx);
|
||||
}
|
||||
|
||||
void
|
||||
matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, int32 vsBits, uint32 flags, MatFX::Env *env)
|
||||
{
|
||||
Material *m;
|
||||
m = inst->material;
|
||||
|
||||
if(env->tex == nil || env->coefficient == 0.0f){
|
||||
matfxDefaultRender(header, inst, vsBits, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
setTexture(0, m->texture);
|
||||
setTexture(1, env->tex);
|
||||
uploadEnvMatrix(env->frame);
|
||||
|
||||
setMaterial(flags, m->color, m->surfaceProps);
|
||||
|
||||
float fxparams[4];
|
||||
fxparams[0] = env->coefficient;
|
||||
fxparams[1] = env->fbAlpha ? 0.0f : 1.0f;
|
||||
fxparams[2] = fxparams[3] = 0.0f;
|
||||
|
||||
setUniform(u_fxparams, fxparams);
|
||||
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
|
||||
if(MatFX::envMapApplyLight)
|
||||
setUniform(u_colorClamp, zero);
|
||||
else
|
||||
setUniform(u_colorClamp, one);
|
||||
RGBAf envcol[4];
|
||||
if(MatFX::envMapUseMatColor)
|
||||
convColor(envcol, &m->color);
|
||||
else
|
||||
convColor(envcol, &MatFX::envMapColor);
|
||||
setUniform(u_envColor, envcol);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, 1);
|
||||
rw::SetRenderState(SRCBLEND, BLENDONE);
|
||||
|
||||
if((vsBits & VSLIGHT_MASK) == 0){
|
||||
if(getAlphaTest())
|
||||
envShader->use();
|
||||
else
|
||||
envShader_noAT->use();
|
||||
}else{
|
||||
if(getAlphaTest())
|
||||
envShader_fullLight->use();
|
||||
else
|
||||
envShader_fullLight_noAT->use();
|
||||
}
|
||||
|
||||
drawInst(header, inst);
|
||||
|
||||
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||
}
|
||||
|
||||
void
|
||||
matfxRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
uint32 flags = atomic->geometry->flags;
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
int32 vsBits = lightingCB(atomic);
|
||||
|
||||
setupVertexInput(header);
|
||||
|
||||
lastEnvFrame = nil;
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
int32 n = header->numMeshes;
|
||||
|
||||
while(n--){
|
||||
MatFX *matfx = MatFX::get(inst->material);
|
||||
|
||||
if(matfx == nil)
|
||||
matfxDefaultRender(header, inst, vsBits, flags);
|
||||
else switch(matfx->type){
|
||||
case MatFX::ENVMAP:
|
||||
matfxEnvRender(header, inst, vsBits, flags, &matfx->fx[0].env);
|
||||
break;
|
||||
default:
|
||||
matfxDefaultRender(header, inst, vsBits, flags);
|
||||
break;
|
||||
}
|
||||
inst++;
|
||||
}
|
||||
teardownVertexInput(header);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeMatFXPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->renderCB = matfxRenderCB;
|
||||
pipe->pluginID = ID_MATFX;
|
||||
pipe->pluginData = 0;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
||||
matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline();
|
||||
|
||||
#include "shaders/matfx_gl.inc"
|
||||
const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil };
|
||||
const char *vs_fullLight[] = { shaderDecl, "#define DIRECTIONALS\n#define POINTLIGHTS\n#define SPOTLIGHTS\n", header_vert_src, matfx_env_vert_src, nil };
|
||||
const char *fs[] = { shaderDecl, header_frag_src, matfx_env_frag_src, nil };
|
||||
const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, matfx_env_frag_src, nil };
|
||||
|
||||
envShader = Shader::create(vs, fs);
|
||||
assert(envShader);
|
||||
envShader_noAT = Shader::create(vs, fs_noAT);
|
||||
assert(envShader_noAT);
|
||||
|
||||
envShader_fullLight = Shader::create(vs_fullLight, fs);
|
||||
assert(envShader_fullLight);
|
||||
envShader_fullLight_noAT = Shader::create(vs_fullLight, fs_noAT);
|
||||
assert(envShader_fullLight_noAT);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
matfxClose(void *o, int32, int32)
|
||||
{
|
||||
((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_GL3])->destroy();
|
||||
matFXGlobals.pipelines[PLATFORM_GL3] = nil;
|
||||
|
||||
envShader->destroy();
|
||||
envShader = nil;
|
||||
envShader_noAT->destroy();
|
||||
envShader_noAT = nil;
|
||||
envShader_fullLight->destroy();
|
||||
envShader_fullLight = nil;
|
||||
envShader_fullLight_noAT->destroy();
|
||||
envShader_fullLight_noAT = nil;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initMatFX(void)
|
||||
{
|
||||
u_texMatrix = registerUniform("u_texMatrix", UNIFORM_MAT4);
|
||||
u_fxparams = registerUniform("u_fxparams", UNIFORM_VEC4);
|
||||
u_colorClamp = registerUniform("u_colorClamp", UNIFORM_VEC4);
|
||||
u_envColor = registerUniform("u_envColor", UNIFORM_VEC4);
|
||||
|
||||
Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX,
|
||||
matfxOpen, matfxClose);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void initMatFX(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
333
vendor/librw/src/gl/gl3pipe.cpp
vendored
Normal file
333
vendor/librw/src/gl/gl3pipe.cpp
vendored
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
// TODO: make some of these things platform-independent
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
void
|
||||
freeInstanceData(Geometry *geometry)
|
||||
{
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_GL3)
|
||||
return;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = nil;
|
||||
glDeleteBuffers(1, &header->ibo);
|
||||
glDeleteBuffers(1, &header->vbo);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glDeleteBuffers(1, &header->vao);
|
||||
#endif
|
||||
rwFree(header->indexBuffer);
|
||||
rwFree(header->vertexBuffer);
|
||||
rwFree(header->attribDesc);
|
||||
rwFree(header->inst);
|
||||
rwFree(header);
|
||||
}
|
||||
|
||||
void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
freeInstanceData((Geometry*)object);
|
||||
return object;
|
||||
}
|
||||
|
||||
static InstanceDataHeader*
|
||||
instanceMesh(rw::ObjPipeline *rwpipe, Geometry *geo)
|
||||
{
|
||||
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
MeshHeader *meshh = geo->meshHeader;
|
||||
geo->instData = header;
|
||||
header->platform = PLATFORM_GL3;
|
||||
|
||||
header->serialNumber = meshh->serialNum;
|
||||
header->numMeshes = meshh->numMeshes;
|
||||
header->primType = meshh->flags == 1 ? GL_TRIANGLE_STRIP : GL_TRIANGLES;
|
||||
header->totalNumVertex = geo->numVertices;
|
||||
header->totalNumIndex = meshh->totalIndices;
|
||||
header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
|
||||
header->indexBuffer = rwNewT(uint16, header->totalNumIndex, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
InstanceData *inst = header->inst;
|
||||
Mesh *mesh = meshh->getMeshes();
|
||||
uint32 offset = 0;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||
&inst->minVert, &inst->numVertices);
|
||||
assert(inst->minVert != 0xFFFFFFFF);
|
||||
inst->numIndex = mesh->numIndices;
|
||||
inst->material = mesh->material;
|
||||
inst->vertexAlpha = 0;
|
||||
inst->program = 0;
|
||||
inst->offset = offset;
|
||||
memcpy((uint8*)header->indexBuffer + inst->offset,
|
||||
mesh->indices, inst->numIndex*2);
|
||||
offset += inst->numIndex*2;
|
||||
mesh++;
|
||||
inst++;
|
||||
}
|
||||
|
||||
header->vertexBuffer = nil;
|
||||
header->numAttribs = 0;
|
||||
header->attribDesc = nil;
|
||||
header->ibo = 0;
|
||||
header->vbo = 0;
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glGenVertexArrays(1, &header->vao);
|
||||
glBindVertexArray(header->vao);
|
||||
#endif
|
||||
glGenBuffers(1, &header->ibo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, header->totalNumIndex*2,
|
||||
header->indexBuffer, GL_STATIC_DRAW);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
static void
|
||||
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
// don't try to (re)instance native data
|
||||
if(geo->flags & Geometry::NATIVE)
|
||||
return;
|
||||
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||
if(geo->instData){
|
||||
// Already have instanced data, so check if we have to reinstance
|
||||
assert(header->platform == PLATFORM_GL3);
|
||||
if(header->serialNumber != geo->meshHeader->serialNum){
|
||||
// Mesh changed, so reinstance everything
|
||||
freeInstanceData(geo);
|
||||
}
|
||||
}
|
||||
|
||||
// no instance or complete reinstance
|
||||
if(geo->instData == nil){
|
||||
geo->instData = instanceMesh(rwpipe, geo);
|
||||
pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 0);
|
||||
}else if(geo->lockedSinceInst)
|
||||
pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 1);
|
||||
|
||||
geo->lockedSinceInst = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
{
|
||||
assert(0 && "can't uninstance");
|
||||
}
|
||||
|
||||
static void
|
||||
render(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
pipe->instance(atomic);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_GL3);
|
||||
if(pipe->renderCB)
|
||||
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
|
||||
}
|
||||
|
||||
void
|
||||
ObjPipeline::init(void)
|
||||
{
|
||||
this->rw::ObjPipeline::init(PLATFORM_GL3);
|
||||
this->impl.instance = gl3::instance;
|
||||
this->impl.uninstance = gl3::uninstance;
|
||||
this->impl.render = gl3::render;
|
||||
this->instanceCB = nil;
|
||||
this->uninstanceCB = nil;
|
||||
this->renderCB = nil;
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
ObjPipeline::create(void)
|
||||
{
|
||||
ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL);
|
||||
pipe->init();
|
||||
return pipe;
|
||||
}
|
||||
|
||||
void
|
||||
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||
{
|
||||
AttribDesc *attribs, *a;
|
||||
|
||||
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
||||
|
||||
if(!reinstance){
|
||||
AttribDesc tmpAttribs[12];
|
||||
uint32 stride;
|
||||
|
||||
//
|
||||
// Create attribute descriptions
|
||||
//
|
||||
a = tmpAttribs;
|
||||
stride = 0;
|
||||
|
||||
// Positions
|
||||
a->index = ATTRIB_POS;
|
||||
a->size = 3;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 12;
|
||||
a++;
|
||||
|
||||
// Normals
|
||||
// TODO: compress
|
||||
if(hasNormals){
|
||||
a->index = ATTRIB_NORMAL;
|
||||
a->size = 3;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 12;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit){
|
||||
a->index = ATTRIB_COLOR;
|
||||
a->size = 4;
|
||||
a->type = GL_UNSIGNED_BYTE;
|
||||
a->normalized = GL_TRUE;
|
||||
a->offset = stride;
|
||||
stride += 4;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
a->index = ATTRIB_TEXCOORDS0+n;
|
||||
a->size = 2;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 8;
|
||||
a++;
|
||||
}
|
||||
|
||||
header->numAttribs = a - tmpAttribs;
|
||||
for(a = tmpAttribs; a != &tmpAttribs[header->numAttribs]; a++)
|
||||
a->stride = stride;
|
||||
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
memcpy(header->attribDesc, tmpAttribs,
|
||||
header->numAttribs*sizeof(AttribDesc));
|
||||
|
||||
//
|
||||
// Allocate vertex buffer
|
||||
//
|
||||
header->vertexBuffer = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
assert(header->vbo == 0);
|
||||
glGenBuffers(1, &header->vbo);
|
||||
}
|
||||
|
||||
attribs = header->attribDesc;
|
||||
|
||||
//
|
||||
// Fill vertex buffer
|
||||
//
|
||||
|
||||
uint8 *verts = header->vertexBuffer;
|
||||
|
||||
// Positions
|
||||
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
|
||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].vertices,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Normals
|
||||
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].normals,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||
;
|
||||
int n = header->numMeshes;
|
||||
InstanceData *inst = header->inst;
|
||||
while(n--){
|
||||
assert(inst->minVert != 0xFFFFFFFF);
|
||||
inst->vertexAlpha = instColor(VERT_RGBA,
|
||||
verts + a->offset + a->stride*inst->minVert,
|
||||
geo->colors + inst->minVert,
|
||||
inst->numVertices, a->stride);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){
|
||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
||||
;
|
||||
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||
geo->texCoords[n],
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(header->vao);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||
#endif
|
||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*attribs[0].stride,
|
||||
header->vertexBuffer, GL_STATIC_DRAW);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
setAttribPointers(header->attribDesc, header->numAttribs);
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||
{
|
||||
assert(0 && "can't uninstance");
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeDefaultPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->renderCB = defaultRenderCB;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
#else
|
||||
void *destroyNativeData(void *object, int32, int32) { return object; }
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
1045
vendor/librw/src/gl/gl3raster.cpp
vendored
Normal file
1045
vendor/librw/src/gl/gl3raster.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
184
vendor/librw/src/gl/gl3render.cpp
vendored
Normal file
184
vendor/librw/src/gl/gl3render.cpp
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
|
||||
#include "rwgl3impl.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#define MAX_LIGHTS
|
||||
|
||||
void
|
||||
drawInst_simple(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
}
|
||||
|
||||
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
|
||||
void
|
||||
drawInst_GSemu(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
uint32 hasAlpha;
|
||||
int alphafunc, alpharef, gsalpharef;
|
||||
int zwrite;
|
||||
hasAlpha = getAlphaBlend();
|
||||
if(hasAlpha){
|
||||
zwrite = rw::GetRenderState(rw::ZWRITEENABLE);
|
||||
alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC);
|
||||
if(zwrite){
|
||||
alpharef = rw::GetRenderState(rw::ALPHATESTREF);
|
||||
gsalpharef = rw::GetRenderState(rw::GSALPHATESTREF);
|
||||
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL);
|
||||
SetRenderState(rw::ALPHATESTREF, gsalpharef);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS);
|
||||
SetRenderState(rw::ZWRITEENABLE, 0);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ZWRITEENABLE, 1);
|
||||
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
|
||||
SetRenderState(rw::ALPHATESTREF, alpharef);
|
||||
}else{
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
|
||||
}
|
||||
}else
|
||||
drawInst_simple(header, inst);
|
||||
}
|
||||
|
||||
void
|
||||
drawInst(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
if(rw::GetRenderState(rw::GSALPHATEST))
|
||||
drawInst_GSemu(header, inst);
|
||||
else
|
||||
drawInst_simple(header, inst);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setAttribPointers(AttribDesc *attribDescs, int32 numAttribs)
|
||||
{
|
||||
AttribDesc *a;
|
||||
for(a = attribDescs; a != &attribDescs[numAttribs]; a++){
|
||||
glEnableVertexAttribArray(a->index);
|
||||
glVertexAttribPointer(a->index, a->size, a->type, a->normalized,
|
||||
a->stride, (void*)(uint64)a->offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disableAttribPointers(AttribDesc *attribDescs, int32 numAttribs)
|
||||
{
|
||||
AttribDesc *a;
|
||||
for(a = attribDescs; a != &attribDescs[numAttribs]; a++)
|
||||
glDisableVertexAttribArray(a->index);
|
||||
}
|
||||
|
||||
void
|
||||
setupVertexInput(InstanceDataHeader *header)
|
||||
{
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(header->vao);
|
||||
#else
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||
setAttribPointers(header->attribDesc, header->numAttribs);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
teardownVertexInput(InstanceDataHeader *header)
|
||||
{
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32
|
||||
lightingCB(Atomic *atomic)
|
||||
{
|
||||
WorldLights lightData;
|
||||
Light *directionals[8];
|
||||
Light *locals[8];
|
||||
lightData.directionals = directionals;
|
||||
lightData.numDirectionals = 8;
|
||||
lightData.locals = locals;
|
||||
lightData.numLocals = 8;
|
||||
|
||||
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{
|
||||
memset(&lightData, 0, sizeof(lightData));
|
||||
return setLights(&lightData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
Material *m;
|
||||
|
||||
uint32 flags = atomic->geometry->flags;
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
int32 vsBits = lightingCB(atomic);
|
||||
|
||||
setupVertexInput(header);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
int32 n = header->numMeshes;
|
||||
|
||||
while(n--){
|
||||
m = inst->material;
|
||||
|
||||
setMaterial(flags, m->color, m->surfaceProps);
|
||||
|
||||
setTexture(0, m->texture);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
if((vsBits & VSLIGHT_MASK) == 0){
|
||||
if(getAlphaTest())
|
||||
defaultShader->use();
|
||||
else
|
||||
defaultShader_noAT->use();
|
||||
}else{
|
||||
if(getAlphaTest())
|
||||
defaultShader_fullLight->use();
|
||||
else
|
||||
defaultShader_fullLight_noAT->use();
|
||||
}
|
||||
|
||||
drawInst(header, inst);
|
||||
inst++;
|
||||
}
|
||||
teardownVertexInput(header);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
355
vendor/librw/src/gl/gl3shader.cpp
vendored
Normal file
355
vendor/librw/src/gl/gl3shader.cpp
vendored
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#include "shaders/header_vs.inc"
|
||||
#include "shaders/header_fs.inc"
|
||||
|
||||
UniformRegistry uniformRegistry;
|
||||
static char nameBuffer[(MAX_UNIFORMS + MAX_BLOCKS)*32]; // static because memory system isn't up yet when we register
|
||||
static uint32 nameBufPtr;
|
||||
static float uniformData[512*4]; // seems enough
|
||||
static uint32 dataPtr;
|
||||
|
||||
static int uniformTypesize[] = {
|
||||
0, 4, 4, 16
|
||||
};
|
||||
|
||||
static char*
|
||||
shader_strdup(const char *name)
|
||||
{
|
||||
size_t len = strlen(name)+1;
|
||||
char *s = &nameBuffer[nameBufPtr];
|
||||
nameBufPtr += len;
|
||||
assert(nameBufPtr <= nelem(nameBuffer));
|
||||
memcpy(s, name, len);
|
||||
return s;
|
||||
}
|
||||
|
||||
int32
|
||||
registerUniform(const char *name, UniformType type, int32 num)
|
||||
{
|
||||
int i;
|
||||
i = findUniform(name);
|
||||
if(i >= 0){
|
||||
Uniform *u = &uniformRegistry.uniforms[i];
|
||||
assert(u->type == type);
|
||||
assert(u->num == num);
|
||||
return i;
|
||||
}
|
||||
// TODO: print error
|
||||
if(uniformRegistry.numUniforms+1 >= MAX_UNIFORMS){
|
||||
assert(0 && "no space for uniform");
|
||||
return -1;
|
||||
}
|
||||
Uniform *u = &uniformRegistry.uniforms[uniformRegistry.numUniforms];
|
||||
u->name = shader_strdup(name);
|
||||
u->type = type;
|
||||
u->serialNum = 0;
|
||||
if(type == UNIFORM_NA){
|
||||
u->num = 0;
|
||||
u->data = nil;
|
||||
}else{
|
||||
u->num = num;
|
||||
u->data = &uniformData[dataPtr];
|
||||
dataPtr += uniformTypesize[type]*num;
|
||||
assert(dataPtr <= nelem(uniformData));
|
||||
}
|
||||
|
||||
return uniformRegistry.numUniforms++;
|
||||
}
|
||||
|
||||
int32
|
||||
findUniform(const char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < uniformRegistry.numUniforms; i++)
|
||||
if(strcmp(name, uniformRegistry.uniforms[i].name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32
|
||||
registerBlock(const char *name)
|
||||
{
|
||||
int i;
|
||||
i = findBlock(name);
|
||||
if(i >= 0) return i;
|
||||
// TODO: print error
|
||||
if(uniformRegistry.numBlocks+1 >= MAX_BLOCKS)
|
||||
return -1;
|
||||
uniformRegistry.blockNames[uniformRegistry.numBlocks] = shader_strdup(name);
|
||||
return uniformRegistry.numBlocks++;
|
||||
}
|
||||
|
||||
int32
|
||||
findBlock(const char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < uniformRegistry.numBlocks; i++)
|
||||
if(strcmp(name, uniformRegistry.blockNames[i]) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
setUniform(int32 id, void *data)
|
||||
{
|
||||
Uniform *u = &uniformRegistry.uniforms[id];
|
||||
assert(u->type != UNIFORM_NA);
|
||||
if(memcmp(u->data, data, uniformTypesize[u->type]*u->num * sizeof(float)) != 0){
|
||||
memcpy(u->data, data, uniformTypesize[u->type]*u->num * sizeof(float));
|
||||
//u->dirty = true;
|
||||
u->serialNum++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flushUniforms(void)
|
||||
{
|
||||
for(int i = 0; i < uniformRegistry.numUniforms; i++){
|
||||
// this is bad!
|
||||
if(i >= currentShader->numUniforms){
|
||||
printf("trying to set uniform %d %s that doesn't exist!\n", i, uniformRegistry.uniforms[i].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 loc = currentShader->uniformLocations[i];
|
||||
if(loc == -1)
|
||||
continue;
|
||||
|
||||
Uniform *u = &uniformRegistry.uniforms[i];
|
||||
if(currentShader->serialNums[i] != u->serialNum)
|
||||
switch(u->type){
|
||||
case UNIFORM_NA:
|
||||
break;
|
||||
case UNIFORM_VEC4:
|
||||
glUniform4fv(loc, u->num, (GLfloat*)u->data);
|
||||
break;
|
||||
case UNIFORM_IVEC4:
|
||||
glUniform4iv(loc, u->num, (GLint*)u->data);
|
||||
break;
|
||||
case UNIFORM_MAT4:
|
||||
glUniformMatrix4fv(loc, u->num, GL_FALSE, (GLfloat*)u->data);
|
||||
break;
|
||||
}
|
||||
currentShader->serialNums[i] = u->serialNum;
|
||||
}
|
||||
}
|
||||
|
||||
Shader *currentShader;
|
||||
|
||||
static void
|
||||
printShaderSource(const char **src)
|
||||
{
|
||||
int f;
|
||||
const char *file;
|
||||
bool printline;
|
||||
int line = 1;
|
||||
for(f = 0; src[f]; f++){
|
||||
int fileline = 1;
|
||||
char c;
|
||||
file = src[f];
|
||||
printline = true;
|
||||
while(c = *file++, c != '\0'){
|
||||
if(printline)
|
||||
printf("%.4d/%d:%.4d: ", line++, f, fileline++);
|
||||
putchar(c);
|
||||
printline = c == '\n';
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
compileshader(GLenum type, const char **src, GLuint *shader)
|
||||
{
|
||||
GLint n;
|
||||
GLint shdr, success;
|
||||
GLint len;
|
||||
char *log;
|
||||
|
||||
for(n = 0; src[n]; n++);
|
||||
|
||||
shdr = glCreateShader(type);
|
||||
glShaderSource(shdr, n, src, nil);
|
||||
glCompileShader(shdr);
|
||||
glGetShaderiv(shdr, GL_COMPILE_STATUS, &success);
|
||||
if(!success){
|
||||
printShaderSource(src);
|
||||
fprintf(stderr, "Error in %s shader\n",
|
||||
type == GL_VERTEX_SHADER ? "vertex" : "fragment");
|
||||
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &len);
|
||||
log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
|
||||
glGetShaderInfoLog(shdr, len, nil, log);
|
||||
fprintf(stderr, "%s\n", log);
|
||||
rwFree(log);
|
||||
return 1;
|
||||
}
|
||||
*shader = shdr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
linkprogram(GLint vs, GLint fs, GLuint *program)
|
||||
{
|
||||
GLint prog, success;
|
||||
GLint len;
|
||||
char *log;
|
||||
|
||||
prog = glCreateProgram();
|
||||
|
||||
if(gl3Caps.glversion < 30){
|
||||
// TODO: perhaps just do this always and get rid of the layout stuff?
|
||||
glBindAttribLocation(prog, ATTRIB_POS, "in_pos");
|
||||
glBindAttribLocation(prog, ATTRIB_NORMAL, "in_normal");
|
||||
glBindAttribLocation(prog, ATTRIB_COLOR, "in_color");
|
||||
glBindAttribLocation(prog, ATTRIB_WEIGHTS, "in_weights");
|
||||
glBindAttribLocation(prog, ATTRIB_INDICES, "in_indices");
|
||||
glBindAttribLocation(prog, ATTRIB_TEXCOORDS0, "in_tex0");
|
||||
glBindAttribLocation(prog, ATTRIB_TEXCOORDS1, "in_tex1");
|
||||
}
|
||||
|
||||
glAttachShader(prog, vs);
|
||||
glAttachShader(prog, fs);
|
||||
glLinkProgram(prog);
|
||||
glGetProgramiv(prog, GL_LINK_STATUS, &success);
|
||||
if(!success){
|
||||
fprintf(stderr, "Error in program\n");
|
||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
|
||||
log = (char*)rwMalloc(len, MEMDUR_FUNCTION);
|
||||
glGetProgramInfoLog(prog, len, nil, log);
|
||||
fprintf(stderr, "%s\n", log);
|
||||
rwFree(log);
|
||||
return 1;
|
||||
}
|
||||
*program = prog;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Shader*
|
||||
Shader::create(const char **vsrc, const char **fsrc)
|
||||
{
|
||||
GLuint vs, fs, program;
|
||||
int i;
|
||||
int fail;
|
||||
|
||||
fail = compileshader(GL_VERTEX_SHADER, vsrc, &vs);
|
||||
if(fail)
|
||||
return nil;
|
||||
|
||||
fail = compileshader(GL_FRAGMENT_SHADER, fsrc, &fs);
|
||||
if(fail){
|
||||
glDeleteShader(vs);
|
||||
return nil;
|
||||
}
|
||||
|
||||
fail = linkprogram(vs, fs, &program);
|
||||
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
if(fail){
|
||||
return nil;
|
||||
}
|
||||
|
||||
Shader *sh = rwNewT(Shader, 1, MEMDUR_EVENT | ID_DRIVER); // or global?
|
||||
|
||||
#ifdef xxxRW_GLES2
|
||||
int numUniforms;
|
||||
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||
for(i = 0; i < numUniforms; i++){
|
||||
GLint size;
|
||||
GLenum type;
|
||||
char name[100];
|
||||
glGetActiveUniform(program, i, 100, nil, &size, &type, name);
|
||||
printf("%d %d %s\n", size, type, name);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef xxxRW_GLES2
|
||||
int numAttribs;
|
||||
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttribs);
|
||||
for(i = 0; i < numAttribs; i++){
|
||||
GLint size;
|
||||
GLenum type;
|
||||
char name[100];
|
||||
glGetActiveAttrib(program, i, 100, nil, &size, &type, name);
|
||||
GLint bind = glGetAttribLocation(program, name);
|
||||
printf("%d %d %s. %d\n", size, type, name, bind);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
// set uniform block binding
|
||||
for(i = 0; i < uniformRegistry.numBlocks; i++){
|
||||
int idx = glGetUniformBlockIndex(program,
|
||||
uniformRegistry.blockNames[i]);
|
||||
if(idx >= 0)
|
||||
glUniformBlockBinding(program, idx, i);
|
||||
}
|
||||
|
||||
// query uniform locations
|
||||
sh->program = program;
|
||||
sh->numUniforms = uniformRegistry.numUniforms;
|
||||
sh->uniformLocations = rwNewT(GLint, uniformRegistry.numUniforms, MEMDUR_EVENT | ID_DRIVER);
|
||||
sh->serialNums = rwNewT(uint32, uniformRegistry.numUniforms, MEMDUR_EVENT | ID_DRIVER);
|
||||
for(i = 0; i < uniformRegistry.numUniforms; i++){
|
||||
sh->uniformLocations[i] = glGetUniformLocation(program,
|
||||
uniformRegistry.uniforms[i].name);
|
||||
sh->serialNums[i] = ~0; // let's hope this means dirty
|
||||
}
|
||||
|
||||
// set samplers
|
||||
glUseProgram(program);
|
||||
char name[64];
|
||||
GLint loc;
|
||||
for(i = 0; i < 4; i++){
|
||||
sprintf(name, "tex%d", i);
|
||||
loc = glGetUniformLocation(program, name);
|
||||
glUniform1i(loc, i);
|
||||
}
|
||||
|
||||
// reset program
|
||||
if(currentShader)
|
||||
glUseProgram(currentShader->program);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
void
|
||||
Shader::use(void)
|
||||
{
|
||||
if(currentShader != this){
|
||||
glUseProgram(this->program);
|
||||
currentShader = this;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Shader::destroy(void)
|
||||
{
|
||||
glDeleteProgram(this->program);
|
||||
rwFree(this->uniformLocations);
|
||||
rwFree(this->serialNums);
|
||||
rwFree(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
366
vendor/librw/src/gl/gl3skin.cpp
vendored
Normal file
366
vendor/librw/src/gl/gl3skin.cpp
vendored
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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"
|
||||
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
#include "rwgl3plg.h"
|
||||
|
||||
#include "rwgl3impl.h"
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
static Shader *skinShader, *skinShader_noAT;
|
||||
static Shader *skinShader_fullLight, *skinShader_fullLight_noAT;
|
||||
static int32 u_boneMatrices;
|
||||
|
||||
void
|
||||
skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||
{
|
||||
AttribDesc *attribs, *a;
|
||||
|
||||
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
||||
|
||||
if(!reinstance){
|
||||
AttribDesc tmpAttribs[14];
|
||||
uint32 stride;
|
||||
|
||||
//
|
||||
// Create attribute descriptions
|
||||
//
|
||||
a = tmpAttribs;
|
||||
stride = 0;
|
||||
|
||||
// Positions
|
||||
a->index = ATTRIB_POS;
|
||||
a->size = 3;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 12;
|
||||
a++;
|
||||
|
||||
// Normals
|
||||
// TODO: compress
|
||||
if(hasNormals){
|
||||
a->index = ATTRIB_NORMAL;
|
||||
a->size = 3;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 12;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit){
|
||||
a->index = ATTRIB_COLOR;
|
||||
a->size = 4;
|
||||
a->type = GL_UNSIGNED_BYTE;
|
||||
a->normalized = GL_TRUE;
|
||||
a->offset = stride;
|
||||
stride += 4;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
a->index = ATTRIB_TEXCOORDS0+n;
|
||||
a->size = 2;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 8;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Weights
|
||||
a->index = ATTRIB_WEIGHTS;
|
||||
a->size = 4;
|
||||
a->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 16;
|
||||
a++;
|
||||
|
||||
// Indices
|
||||
a->index = ATTRIB_INDICES;
|
||||
a->size = 4;
|
||||
a->type = GL_UNSIGNED_BYTE;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 4;
|
||||
a++;
|
||||
|
||||
header->numAttribs = a - tmpAttribs;
|
||||
for(a = tmpAttribs; a != &tmpAttribs[header->numAttribs]; a++)
|
||||
a->stride = stride;
|
||||
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
memcpy(header->attribDesc, tmpAttribs,
|
||||
header->numAttribs*sizeof(AttribDesc));
|
||||
|
||||
//
|
||||
// Allocate vertex buffer
|
||||
//
|
||||
header->vertexBuffer = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
assert(header->vbo == 0);
|
||||
glGenBuffers(1, &header->vbo);
|
||||
}
|
||||
|
||||
Skin *skin = Skin::get(geo);
|
||||
attribs = header->attribDesc;
|
||||
|
||||
//
|
||||
// Fill vertex buffer
|
||||
//
|
||||
|
||||
uint8 *verts = header->vertexBuffer;
|
||||
|
||||
// Positions
|
||||
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
|
||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].vertices,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Normals
|
||||
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].normals,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||
;
|
||||
instColor(VERT_RGBA, verts + a->offset,
|
||||
geo->colors,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){
|
||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
||||
;
|
||||
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||
geo->texCoords[n],
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
}
|
||||
|
||||
// Weights
|
||||
if(!reinstance){
|
||||
for(a = attribs; a->index != ATTRIB_WEIGHTS; a++)
|
||||
;
|
||||
float *w = skin->weights;
|
||||
instV4d(VERT_FLOAT4, verts + a->offset,
|
||||
(V4d*)w,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
// Indices
|
||||
if(!reinstance){
|
||||
for(a = attribs; a->index != ATTRIB_INDICES; a++)
|
||||
;
|
||||
// not really colors of course but what the heck
|
||||
instColor(VERT_RGBA, verts + a->offset,
|
||||
(RGBA*)skin->indices,
|
||||
header->totalNumVertex, a->stride);
|
||||
}
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(header->vao);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||
#endif
|
||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*attribs[0].stride,
|
||||
header->vertexBuffer, GL_STATIC_DRAW);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
setAttribPointers(header->attribDesc, header->numAttribs);
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||
{
|
||||
assert(0 && "can't uninstance");
|
||||
}
|
||||
|
||||
static float skinMatrices[64*16];
|
||||
|
||||
void
|
||||
uploadSkinMatrices(Atomic *a)
|
||||
{
|
||||
int i;
|
||||
Skin *skin = Skin::get(a->geometry);
|
||||
Matrix *m = (Matrix*)skinMatrices;
|
||||
HAnimHierarchy *hier = Skin::getHierarchy(a);
|
||||
|
||||
if(hier){
|
||||
Matrix *invMats = (Matrix*)skin->inverseMatrices;
|
||||
Matrix tmp;
|
||||
|
||||
assert(skin->numBones == hier->numNodes);
|
||||
if(hier->flags & HAnimHierarchy::LOCALSPACEMATRICES){
|
||||
for(i = 0; i < hier->numNodes; i++){
|
||||
invMats[i].flags = 0;
|
||||
Matrix::mult(m, &invMats[i], &hier->matrices[i]);
|
||||
m++;
|
||||
}
|
||||
}else{
|
||||
Matrix invAtmMat;
|
||||
Matrix::invert(&invAtmMat, a->getFrame()->getLTM());
|
||||
for(i = 0; i < hier->numNodes; i++){
|
||||
invMats[i].flags = 0;
|
||||
Matrix::mult(&tmp, &hier->matrices[i], &invAtmMat);
|
||||
Matrix::mult(m, &invMats[i], &tmp);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for(i = 0; i < skin->numBones; i++){
|
||||
m->setIdentity();
|
||||
m++;
|
||||
}
|
||||
}
|
||||
setUniform(u_boneMatrices, skinMatrices);
|
||||
}
|
||||
|
||||
void
|
||||
skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
Material *m;
|
||||
|
||||
uint32 flags = atomic->geometry->flags;
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
int32 vsBits = lightingCB(atomic);
|
||||
|
||||
setupVertexInput(header);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
int32 n = header->numMeshes;
|
||||
|
||||
uploadSkinMatrices(atomic);
|
||||
|
||||
while(n--){
|
||||
m = inst->material;
|
||||
|
||||
setMaterial(flags, m->color, m->surfaceProps);
|
||||
|
||||
setTexture(0, m->texture);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
if((vsBits & VSLIGHT_MASK) == 0){
|
||||
if(getAlphaTest())
|
||||
skinShader->use();
|
||||
else
|
||||
skinShader_noAT->use();
|
||||
}else{
|
||||
if(getAlphaTest())
|
||||
skinShader_fullLight->use();
|
||||
else
|
||||
skinShader_fullLight_noAT->use();
|
||||
}
|
||||
|
||||
drawInst(header, inst);
|
||||
inst++;
|
||||
}
|
||||
teardownVertexInput(header);
|
||||
}
|
||||
|
||||
static void*
|
||||
skinOpen(void *o, int32, int32)
|
||||
{
|
||||
skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline();
|
||||
|
||||
#include "shaders/simple_fs_gl.inc"
|
||||
#include "shaders/skin_gl.inc"
|
||||
const char *vs[] = { shaderDecl, header_vert_src, skin_vert_src, nil };
|
||||
const char *vs_fullLight[] = { shaderDecl, "#define DIRECTIONALS\n#define POINTLIGHTS\n#define SPOTLIGHTS\n", header_vert_src, skin_vert_src, nil };
|
||||
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
|
||||
const char *fs_noAT[] = { shaderDecl, "#define NO_ALPHATEST\n", header_frag_src, simple_frag_src, nil };
|
||||
|
||||
skinShader = Shader::create(vs, fs);
|
||||
assert(skinShader);
|
||||
skinShader_noAT = Shader::create(vs, fs_noAT);
|
||||
assert(skinShader_noAT);
|
||||
|
||||
skinShader_fullLight = Shader::create(vs_fullLight, fs);
|
||||
assert(skinShader_fullLight);
|
||||
skinShader_fullLight_noAT = Shader::create(vs_fullLight, fs_noAT);
|
||||
assert(skinShader_fullLight_noAT);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
skinClose(void *o, int32, int32)
|
||||
{
|
||||
((ObjPipeline*)skinGlobals.pipelines[PLATFORM_GL3])->destroy();
|
||||
skinGlobals.pipelines[PLATFORM_GL3] = nil;
|
||||
|
||||
skinShader->destroy();
|
||||
skinShader = nil;
|
||||
skinShader_noAT->destroy();
|
||||
skinShader_noAT = nil;
|
||||
skinShader_fullLight->destroy();
|
||||
skinShader_fullLight = nil;
|
||||
skinShader_fullLight_noAT->destroy();
|
||||
skinShader_fullLight_noAT = nil;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initSkin(void)
|
||||
{
|
||||
u_boneMatrices = registerUniform("u_boneMatrices", UNIFORM_MAT4, 64);
|
||||
|
||||
Driver::registerPlugin(PLATFORM_GL3, 0, ID_SKIN,
|
||||
skinOpen, skinClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeSkinPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
pipe->instanceCB = skinInstanceCB;
|
||||
pipe->uninstanceCB = skinUninstanceCB;
|
||||
pipe->renderCB = skinRenderCB;
|
||||
pipe->pluginID = ID_SKIN;
|
||||
pipe->pluginData = 1;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void initSkin(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
1590
vendor/librw/src/gl/glad/glad.c
vendored
Normal file
1590
vendor/librw/src/gl/glad/glad.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
2808
vendor/librw/src/gl/glad/glad.h
vendored
Normal file
2808
vendor/librw/src/gl/glad/glad.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
290
vendor/librw/src/gl/glad/khrplatform.h
vendored
Normal file
290
vendor/librw/src/gl/glad/khrplatform.h
vendored
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
288
vendor/librw/src/gl/rwgl3.h
vendored
Normal file
288
vendor/librw/src/gl/rwgl3.h
vendored
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
#ifdef RW_GL3
|
||||
#include "glad/glad.h"
|
||||
#ifdef LIBRW_SDL2
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace rw {
|
||||
|
||||
#ifdef RW_GL3
|
||||
struct EngineOpenParams
|
||||
{
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_Window **window;
|
||||
bool32 fullscreen;
|
||||
#else
|
||||
GLFWwindow **window;
|
||||
#endif
|
||||
int width, height;
|
||||
const char *windowtitle;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace gl3 {
|
||||
|
||||
void registerPlatformPlugins(void);
|
||||
|
||||
extern Device renderdevice;
|
||||
|
||||
// arguments to glVertexAttribPointer basically
|
||||
struct AttribDesc
|
||||
{
|
||||
uint32 index;
|
||||
int32 type;
|
||||
bool32 normalized;
|
||||
int32 size;
|
||||
uint32 stride;
|
||||
uint32 offset;
|
||||
};
|
||||
|
||||
enum AttribIndices
|
||||
{
|
||||
ATTRIB_POS = 0,
|
||||
ATTRIB_NORMAL,
|
||||
ATTRIB_COLOR,
|
||||
ATTRIB_WEIGHTS,
|
||||
ATTRIB_INDICES,
|
||||
ATTRIB_TEXCOORDS0,
|
||||
ATTRIB_TEXCOORDS1,
|
||||
ATTRIB_TEXCOORDS2,
|
||||
ATTRIB_TEXCOORDS3,
|
||||
ATTRIB_TEXCOORDS4,
|
||||
ATTRIB_TEXCOORDS5,
|
||||
ATTRIB_TEXCOORDS6,
|
||||
ATTRIB_TEXCOORDS7,
|
||||
};
|
||||
|
||||
// default uniform indices
|
||||
extern int32 u_matColor;
|
||||
extern int32 u_surfProps;
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
uint32 numIndex;
|
||||
uint32 minVert; // not used for rendering
|
||||
int32 numVertices; //
|
||||
Material *material;
|
||||
bool32 vertexAlpha;
|
||||
uint32 program;
|
||||
uint32 offset;
|
||||
};
|
||||
|
||||
struct InstanceDataHeader : rw::InstanceDataHeader
|
||||
{
|
||||
uint32 serialNumber;
|
||||
uint32 numMeshes;
|
||||
uint16 *indexBuffer;
|
||||
uint32 primType;
|
||||
uint8 *vertexBuffer;
|
||||
int32 numAttribs;
|
||||
AttribDesc *attribDesc;
|
||||
uint32 totalNumIndex;
|
||||
uint32 totalNumVertex;
|
||||
|
||||
uint32 ibo;
|
||||
uint32 vbo; // or 2?
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
uint32 vao;
|
||||
#endif
|
||||
|
||||
InstanceData *inst;
|
||||
};
|
||||
|
||||
#ifdef RW_GL3
|
||||
|
||||
struct Shader;
|
||||
|
||||
extern Shader *defaultShader, *defaultShader_noAT;
|
||||
extern Shader *defaultShader_fullLight, *defaultShader_fullLight_noAT;
|
||||
|
||||
struct Im3DVertex
|
||||
{
|
||||
V3d position;
|
||||
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 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; }
|
||||
|
||||
float getX(void) { return this->position.x; }
|
||||
float getY(void) { return this->position.y; }
|
||||
float getZ(void) { return this->position.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; }
|
||||
};
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
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; }
|
||||
// This is a bit unefficient but we have to counteract GL's divide, so multiply
|
||||
void setCameraZ(float32 z) { this->w = z; }
|
||||
void setRecipCameraZ(float32 recipz) { this->w = 1.0f/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, float recipz) { this->u = u; }
|
||||
void setV(float32 v, float recipz) { this->v = v; }
|
||||
|
||||
float getScreenX(void) { return this->x; }
|
||||
float getScreenY(void) { return this->y; }
|
||||
float getScreenZ(void) { return this->z; }
|
||||
float getCameraZ(void) { return this->w; }
|
||||
float getRecipCameraZ(void) { return 1.0f/this->w; }
|
||||
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; }
|
||||
};
|
||||
|
||||
void setAttribPointers(AttribDesc *attribDescs, int32 numAttribs);
|
||||
void disableAttribPointers(AttribDesc *attribDescs, int32 numAttribs);
|
||||
void setupVertexInput(InstanceDataHeader *header);
|
||||
void teardownVertexInput(InstanceDataHeader *header);
|
||||
|
||||
// Render state
|
||||
|
||||
// Vertex shader bits
|
||||
enum
|
||||
{
|
||||
// These should be low so they could be used as indices
|
||||
VSLIGHT_DIRECT = 1,
|
||||
VSLIGHT_POINT = 2,
|
||||
VSLIGHT_SPOT = 4,
|
||||
VSLIGHT_MASK = 7, // all the above
|
||||
// less critical
|
||||
VSLIGHT_AMBIENT = 8,
|
||||
};
|
||||
|
||||
extern const char *shaderDecl; // #version stuff
|
||||
extern const char *header_vert_src;
|
||||
extern const char *header_frag_src;
|
||||
|
||||
extern Shader *im2dOverrideShader;
|
||||
|
||||
// per Scene
|
||||
void setProjectionMatrix(float32*);
|
||||
void setViewMatrix(float32*);
|
||||
|
||||
// per Object
|
||||
void setWorldMatrix(Matrix*);
|
||||
int32 setLights(WorldLights *lightData);
|
||||
|
||||
// per Mesh
|
||||
void setTexture(int32 n, Texture *tex);
|
||||
void setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f);
|
||||
inline void setMaterial(uint32 flags, const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f)
|
||||
{
|
||||
static RGBA white = { 255, 255, 255, 255 };
|
||||
if(flags & Geometry::MODULATE)
|
||||
setMaterial(color, surfaceprops, extraSurfProp);
|
||||
else
|
||||
setMaterial(white, surfaceprops, extraSurfProp);
|
||||
}
|
||||
|
||||
void setAlphaBlend(bool32 enable);
|
||||
bool32 getAlphaBlend(void);
|
||||
|
||||
bool32 getAlphaTest(void);
|
||||
|
||||
void bindFramebuffer(uint32 fbo);
|
||||
uint32 bindTexture(uint32 texid);
|
||||
|
||||
void flushCache(void);
|
||||
|
||||
#endif
|
||||
|
||||
class ObjPipeline : public rw::ObjPipeline
|
||||
{
|
||||
public:
|
||||
void init(void);
|
||||
static ObjPipeline *create(void);
|
||||
|
||||
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
|
||||
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
|
||||
};
|
||||
|
||||
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||
int32 lightingCB(Atomic *atomic);
|
||||
|
||||
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
|
||||
void drawInst_GSemu(InstanceDataHeader *header, InstanceData *inst);
|
||||
// This one switches between the above two depending on render state;
|
||||
void drawInst(InstanceDataHeader *header, InstanceData *inst);
|
||||
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
|
||||
ObjPipeline *makeDefaultPipeline(void);
|
||||
|
||||
// Native Texture and Raster
|
||||
|
||||
struct Gl3Raster
|
||||
{
|
||||
// arguments to glTexImage2D
|
||||
int32 internalFormat;
|
||||
int32 type;
|
||||
int32 format;
|
||||
int32 bpp; // bytes per pixel
|
||||
// texture object
|
||||
uint32 texid;
|
||||
|
||||
bool isCompressed;
|
||||
bool hasAlpha;
|
||||
bool autogenMipmap;
|
||||
int8 numLevels;
|
||||
// cached filtermode and addressing
|
||||
uint8 filterMode;
|
||||
uint8 addressU;
|
||||
uint8 addressV;
|
||||
int32 maxAnisotropy;
|
||||
|
||||
uint32 fbo; // used for camera texture only!
|
||||
Raster *fboMate; // color or zbuffer raster mate of this one
|
||||
RasterLevels *backingStore; // if we can't read back GPU memory but have to
|
||||
};
|
||||
|
||||
struct Gl3Caps
|
||||
{
|
||||
int gles;
|
||||
int glversion;
|
||||
bool dxtSupported;
|
||||
bool astcSupported; // not used yet
|
||||
float maxAnisotropy;
|
||||
};
|
||||
extern Gl3Caps gl3Caps;
|
||||
// GLES can't read back textures very nicely.
|
||||
// In most cases that's not an issue, but when it is,
|
||||
// this has to be set before the texture is filled:
|
||||
extern bool32 needToReadBackTextures;
|
||||
|
||||
void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha);
|
||||
|
||||
Texture *readNativeTexture(Stream *stream);
|
||||
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||
uint32 getSizeNativeTexture(Texture *tex);
|
||||
|
||||
extern int32 nativeRasterOffset;
|
||||
void registerNativeRaster(void);
|
||||
#define GETGL3RASTEREXT(raster) PLUGINOFFSET(Gl3Raster, raster, rw::gl3::nativeRasterOffset)
|
||||
|
||||
}
|
||||
}
|
||||
76
vendor/librw/src/gl/rwgl3impl.h
vendored
Normal file
76
vendor/librw/src/gl/rwgl3impl.h
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
extern uint32 im2DVbo, im2DIbo;
|
||||
void openIm2D(void);
|
||||
void closeIm2D(void);
|
||||
void im2DRenderLine(void *vertices, int32 numVertices,
|
||||
int32 vert1, int32 vert2);
|
||||
void im2DRenderTriangle(void *vertices, int32 numVertices,
|
||||
int32 vert1, int32 vert2, int32 vert3);
|
||||
void im2DRenderPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices);
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||
|
||||
void openIm3D(void);
|
||||
void closeIm3D(void);
|
||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags);
|
||||
void im3DRenderPrimitive(PrimitiveType primType);
|
||||
void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices);
|
||||
void im3DEnd(void);
|
||||
|
||||
struct DisplayMode
|
||||
{
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_DisplayMode mode;
|
||||
#else
|
||||
GLFWvidmode mode;
|
||||
#endif
|
||||
int32 depth;
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
struct GlGlobals
|
||||
{
|
||||
#ifdef LIBRW_SDL2
|
||||
SDL_Window **pWindow;
|
||||
SDL_Window *window;
|
||||
SDL_GLContext glcontext;
|
||||
#else
|
||||
GLFWwindow **pWindow;
|
||||
GLFWwindow *window;
|
||||
|
||||
GLFWmonitor *monitor;
|
||||
int numMonitors;
|
||||
int currentMonitor;
|
||||
#endif
|
||||
|
||||
DisplayMode *modes;
|
||||
int numModes;
|
||||
int currentMode;
|
||||
int presentWidth, presentHeight;
|
||||
int presentOffX, presentOffY;
|
||||
|
||||
// for opening the window
|
||||
int winWidth, winHeight;
|
||||
const char *winTitle;
|
||||
uint32 numSamples;
|
||||
};
|
||||
|
||||
extern GlGlobals glGlobals;
|
||||
#endif
|
||||
|
||||
Raster *rasterCreate(Raster *raster);
|
||||
uint8 *rasterLock(Raster*, int32 level, int32 lockMode);
|
||||
void rasterUnlock(Raster*, int32);
|
||||
int32 rasterNumLevels(Raster*);
|
||||
bool32 imageFindRasterFormat(Image *img, int32 type,
|
||||
int32 *width, int32 *height, int32 *depth, int32 *format);
|
||||
bool32 rasterFromImage(Raster *raster, Image *image);
|
||||
Image *rasterToImage(Raster *raster);
|
||||
|
||||
}
|
||||
}
|
||||
16
vendor/librw/src/gl/rwgl3plg.h
vendored
Normal file
16
vendor/librw/src/gl/rwgl3plg.h
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
void initMatFX(void);
|
||||
ObjPipeline *makeMatFXPipeline(void);
|
||||
void matfxRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||
|
||||
void initSkin(void);
|
||||
ObjPipeline *makeSkinPipeline(void);
|
||||
void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||
void skinRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||
void uploadSkinMatrices(Atomic *atomic);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
69
vendor/librw/src/gl/rwgl3shader.h
vendored
Normal file
69
vendor/librw/src/gl/rwgl3shader.h
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#ifdef RW_OPENGL
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
// TODO: make this dynamic
|
||||
enum {
|
||||
MAX_UNIFORMS = 40,
|
||||
MAX_BLOCKS = 20
|
||||
};
|
||||
|
||||
enum UniformType
|
||||
{
|
||||
UNIFORM_NA, // managed by the user
|
||||
UNIFORM_VEC4,
|
||||
UNIFORM_IVEC4,
|
||||
UNIFORM_MAT4
|
||||
};
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
char *name;
|
||||
UniformType type;
|
||||
//bool dirty;
|
||||
uint32 serialNum;
|
||||
int32 num;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct UniformRegistry
|
||||
{
|
||||
int32 numUniforms;
|
||||
Uniform uniforms[MAX_UNIFORMS];
|
||||
|
||||
int32 numBlocks;
|
||||
char *blockNames[MAX_BLOCKS];
|
||||
};
|
||||
|
||||
int32 registerUniform(const char *name, UniformType type = UNIFORM_NA, int32 num = 1);
|
||||
int32 findUniform(const char *name);
|
||||
int32 registerBlock(const char *name);
|
||||
int32 findBlock(const char *name);
|
||||
|
||||
void setUniform(int32 id, void *data);
|
||||
void flushUniforms(void);
|
||||
|
||||
extern UniformRegistry uniformRegistry;
|
||||
|
||||
struct Shader
|
||||
{
|
||||
GLuint program;
|
||||
// same number of elements as UniformRegistry::numUniforms
|
||||
GLint *uniformLocations;
|
||||
uint32 *serialNums;
|
||||
int32 numUniforms; // just to be sure!
|
||||
|
||||
static Shader *create(const char **vsrc, const char **fsrc);
|
||||
// static Shader *fromFiles(const char *vs, const char *fs);
|
||||
// static Shader *fromStrings(const char *vsrc, const char *fsrc);
|
||||
void use(void);
|
||||
void destroy(void);
|
||||
};
|
||||
|
||||
extern Shader *currentShader;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
88
vendor/librw/src/gl/rwwdgl.h
vendored
Normal file
88
vendor/librw/src/gl/rwwdgl.h
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
namespace rw {
|
||||
namespace wdgl {
|
||||
|
||||
// NOTE: This is not really RW OpenGL! It's specific to WarDrum's GTA ports
|
||||
|
||||
void registerPlatformPlugins(void);
|
||||
|
||||
struct AttribDesc
|
||||
{
|
||||
// arguments to glVertexAttribPointer (should use OpenGL types here)
|
||||
// Vertex = 0, TexCoord, Normal, Color, Weight, Bone Index, Extra Color
|
||||
uint32 index;
|
||||
// float = 0, byte, ubyte, short, ushort
|
||||
int32 type;
|
||||
bool32 normalized;
|
||||
int32 size;
|
||||
uint32 stride;
|
||||
uint32 offset;
|
||||
};
|
||||
|
||||
struct InstanceDataHeader : rw::InstanceDataHeader
|
||||
{
|
||||
int32 numAttribs;
|
||||
AttribDesc *attribs;
|
||||
uint32 dataSize;
|
||||
uint8 *data;
|
||||
|
||||
// needed for rendering
|
||||
uint32 vbo;
|
||||
uint32 ibo;
|
||||
};
|
||||
|
||||
// only RW_OPENGL
|
||||
void uploadGeo(Geometry *geo);
|
||||
void setAttribPointers(InstanceDataHeader *inst);
|
||||
|
||||
void packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale);
|
||||
void unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale);
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
int32 getSizeNativeData(void *object, int32, int32);
|
||||
void registerNativeDataPlugin(void);
|
||||
|
||||
void printPipeinfo(Atomic *a);
|
||||
|
||||
class ObjPipeline : public rw::ObjPipeline
|
||||
{
|
||||
public:
|
||||
void init(void);
|
||||
static ObjPipeline *create(void);
|
||||
|
||||
uint32 numCustomAttribs;
|
||||
uint32 (*instanceCB)(Geometry *g, int32 i, uint32 offset);
|
||||
void (*uninstanceCB)(Geometry *g);
|
||||
};
|
||||
|
||||
ObjPipeline *makeDefaultPipeline(void);
|
||||
|
||||
// Skin plugin
|
||||
|
||||
void initSkin(void);
|
||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||
int32 getSizeNativeSkin(void *object, int32 offset);
|
||||
|
||||
ObjPipeline *makeSkinPipeline(void);
|
||||
|
||||
// MatFX plugin
|
||||
|
||||
void initMatFX(void);
|
||||
ObjPipeline *makeMatFXPipeline(void);
|
||||
|
||||
// Raster
|
||||
|
||||
struct Texture : rw::Texture
|
||||
{
|
||||
void upload(void);
|
||||
void bind(int n);
|
||||
};
|
||||
|
||||
extern int32 nativeRasterOffset;
|
||||
void registerNativeRaster(void);
|
||||
|
||||
}
|
||||
}
|
||||
45
vendor/librw/src/gl/shaders/Makefile
vendored
Normal file
45
vendor/librw/src/gl/shaders/Makefile
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
all: header_vs.inc header_fs.inc im2d_gl.inc im3d_gl.inc default_vs_gl.inc simple_fs_gl.inc matfx_gl.inc skin_gl.inc
|
||||
|
||||
header_vs.inc: header.vert
|
||||
(echo 'const char *header_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' header.vert;\
|
||||
echo ';') >header_vs.inc
|
||||
|
||||
header_fs.inc: header.frag
|
||||
(echo 'const char *header_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' header.frag;\
|
||||
echo ';') >header_fs.inc
|
||||
|
||||
im2d_gl.inc: im2d.vert
|
||||
(echo 'const char *im2d_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' im2d.vert;\
|
||||
echo ';') >im2d_gl.inc
|
||||
|
||||
im3d_gl.inc: im3d.vert
|
||||
(echo 'const char *im3d_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' im3d.vert;\
|
||||
echo ';') >im3d_gl.inc
|
||||
|
||||
default_vs_gl.inc: default.vert
|
||||
(echo 'const char *default_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' default.vert;\
|
||||
echo ';') >default_vs_gl.inc
|
||||
|
||||
simple_fs_gl.inc: simple.frag
|
||||
(echo 'const char *simple_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' simple.frag;\
|
||||
echo ';') >simple_fs_gl.inc
|
||||
|
||||
matfx_gl.inc: matfx_env.frag matfx_env.vert
|
||||
(echo 'const char *matfx_env_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' matfx_env.vert;\
|
||||
echo ';';\
|
||||
echo 'const char *matfx_env_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' matfx_env.frag;\
|
||||
echo ';') >matfx_gl.inc
|
||||
|
||||
skin_gl.inc: skin.vert
|
||||
(echo 'const char *skin_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' skin.vert;\
|
||||
echo ';') >skin_gl.inc
|
||||
|
||||
23
vendor/librw/src/gl/shaders/default.vert
vendored
Normal file
23
vendor/librw/src/gl/shaders/default.vert
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
VSIN(ATTRIB_POS) vec3 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 Vertex = u_world * vec4(in_pos, 1.0);
|
||||
gl_Position = u_proj * u_view * Vertex;
|
||||
vec3 Normal = mat3(u_world) * in_normal;
|
||||
|
||||
v_tex0 = in_tex0;
|
||||
|
||||
v_color = in_color;
|
||||
v_color.rgb += u_ambLight.rgb*surfAmbient;
|
||||
v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
|
||||
v_color = clamp(v_color, 0.0, 1.0);
|
||||
v_color *= u_matColor;
|
||||
|
||||
v_fog = DoFog(gl_Position.w);
|
||||
}
|
||||
25
vendor/librw/src/gl/shaders/default_vs_gl.inc
vendored
Normal file
25
vendor/librw/src/gl/shaders/default_vs_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const char *default_vert_src =
|
||||
"VSIN(ATTRIB_POS) vec3 in_pos;\n"
|
||||
|
||||
"VSOUT vec4 v_color;\n"
|
||||
"VSOUT vec2 v_tex0;\n"
|
||||
"VSOUT float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
|
||||
" gl_Position = u_proj * u_view * Vertex;\n"
|
||||
" vec3 Normal = mat3(u_world) * in_normal;\n"
|
||||
|
||||
" v_tex0 = in_tex0;\n"
|
||||
|
||||
" v_color = in_color;\n"
|
||||
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
|
||||
" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
|
||||
" v_color = clamp(v_color, 0.0, 1.0);\n"
|
||||
" v_color *= u_matColor;\n"
|
||||
|
||||
" v_fog = DoFog(gl_Position.w);\n"
|
||||
"}\n"
|
||||
;
|
||||
30
vendor/librw/src/gl/shaders/header.frag
vendored
Normal file
30
vendor/librw/src/gl/shaders/header.frag
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifdef USE_UBOS
|
||||
layout(std140) uniform State
|
||||
{
|
||||
vec2 u_alphaRef;
|
||||
vec4 u_fogData;
|
||||
vec4 u_fogColor;
|
||||
};
|
||||
#else
|
||||
uniform vec4 u_alphaRef;
|
||||
|
||||
uniform vec4 u_fogData;
|
||||
uniform vec4 u_fogColor;
|
||||
#endif
|
||||
|
||||
#define u_fogStart (u_fogData.x)
|
||||
#define u_fogEnd (u_fogData.y)
|
||||
#define u_fogRange (u_fogData.z)
|
||||
#define u_fogDisable (u_fogData.w)
|
||||
|
||||
#ifndef GL2
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
void DoAlphaTest(float a)
|
||||
{
|
||||
#ifndef NO_ALPHATEST
|
||||
if(a < u_alphaRef.x || a >= u_alphaRef.y)
|
||||
discard;
|
||||
#endif
|
||||
}
|
||||
128
vendor/librw/src/gl/shaders/header.vert
vendored
Normal file
128
vendor/librw/src/gl/shaders/header.vert
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
//#define DIRECTIONALS
|
||||
//#define POINTLIGHTS
|
||||
//#define SPOTLIGHTS
|
||||
|
||||
#define ATTRIB_POS 0
|
||||
#define ATTRIB_NORMAL 1
|
||||
#define ATTRIB_COLOR 2
|
||||
#define ATTRIB_WEIGHTS 3
|
||||
#define ATTRIB_INDICES 4
|
||||
#define ATTRIB_TEXCOORDS0 5
|
||||
#define ATTRIB_TEXCOORDS1 6
|
||||
|
||||
|
||||
VSIN(ATTRIB_NORMAL) vec3 in_normal;
|
||||
VSIN(ATTRIB_COLOR) vec4 in_color;
|
||||
VSIN(ATTRIB_WEIGHTS) vec4 in_weights;
|
||||
VSIN(ATTRIB_INDICES) vec4 in_indices;
|
||||
VSIN(ATTRIB_TEXCOORDS0) vec2 in_tex0;
|
||||
VSIN(ATTRIB_TEXCOORDS1) vec2 in_tex1;
|
||||
|
||||
|
||||
#ifdef USE_UBOS
|
||||
layout(std140) uniform State
|
||||
{
|
||||
vec2 u_alphaRef;
|
||||
vec4 u_fogData;
|
||||
vec4 u_fogColor;
|
||||
};
|
||||
#else
|
||||
uniform vec4 u_alphaRef;
|
||||
uniform vec4 u_fogData;
|
||||
uniform vec4 u_fogColor;
|
||||
#endif
|
||||
|
||||
#define u_fogStart (u_fogData.x)
|
||||
#define u_fogEnd (u_fogData.y)
|
||||
#define u_fogRange (u_fogData.z)
|
||||
#define u_fogDisable (u_fogData.w)
|
||||
|
||||
#ifdef USE_UBOS
|
||||
layout(std140) uniform Scene
|
||||
{
|
||||
mat4 u_proj;
|
||||
mat4 u_view;
|
||||
};
|
||||
#else
|
||||
uniform mat4 u_proj;
|
||||
uniform mat4 u_view;
|
||||
#endif
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
#ifdef USE_UBOS
|
||||
layout(std140) uniform Object
|
||||
{
|
||||
mat4 u_world;
|
||||
vec4 u_ambLight;
|
||||
vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot
|
||||
vec4 u_lightPosition[MAX_LIGHTS];
|
||||
vec4 u_lightDirection[MAX_LIGHTS];
|
||||
vec4 u_lightColor[MAX_LIGHTS];
|
||||
};
|
||||
#else
|
||||
uniform mat4 u_world;
|
||||
uniform vec4 u_ambLight;
|
||||
uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot
|
||||
uniform vec4 u_lightPosition[MAX_LIGHTS];
|
||||
uniform vec4 u_lightDirection[MAX_LIGHTS];
|
||||
uniform vec4 u_lightColor[MAX_LIGHTS];
|
||||
#endif
|
||||
|
||||
uniform vec4 u_matColor;
|
||||
uniform vec4 u_surfProps; // amb, spec, diff, extra
|
||||
|
||||
#define surfAmbient (u_surfProps.x)
|
||||
#define surfSpecular (u_surfProps.y)
|
||||
#define surfDiffuse (u_surfProps.z)
|
||||
|
||||
vec3 DoDynamicLight(vec3 V, vec3 N)
|
||||
{
|
||||
vec3 color = vec3(0.0, 0.0, 0.0);
|
||||
for(int i = 0; i < MAX_LIGHTS; i++){
|
||||
if(u_lightParams[i].x == 0.0)
|
||||
break;
|
||||
#ifdef DIRECTIONALS
|
||||
if(u_lightParams[i].x == 1.0){
|
||||
// direct
|
||||
float l = max(0.0, dot(N, -u_lightDirection[i].xyz));
|
||||
color += l*u_lightColor[i].rgb;
|
||||
}else
|
||||
#endif
|
||||
#ifdef POINTLIGHTS
|
||||
if(u_lightParams[i].x == 2.0){
|
||||
// point
|
||||
vec3 dir = V - u_lightPosition[i].xyz;
|
||||
float dist = length(dir);
|
||||
float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));
|
||||
float l = max(0.0, dot(N, -normalize(dir)));
|
||||
color += l*u_lightColor[i].rgb*atten;
|
||||
}else
|
||||
#endif
|
||||
#ifdef SPOTLIGHTS
|
||||
if(u_lightParams[i].x == 3.0){
|
||||
// spot
|
||||
vec3 dir = V - u_lightPosition[i].xyz;
|
||||
float dist = length(dir);
|
||||
float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));
|
||||
dir /= dist;
|
||||
float l = max(0.0, dot(N, -dir));
|
||||
float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point
|
||||
float ccos = -u_lightParams[i].z;
|
||||
float falloff = (pcos-ccos)/(1.0-ccos);
|
||||
if(falloff < 0.0) // outside of cone
|
||||
l = 0.0;
|
||||
l *= max(falloff, u_lightParams[i].w);
|
||||
return l*u_lightColor[i].rgb*atten;
|
||||
}else
|
||||
#endif
|
||||
;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
float DoFog(float w)
|
||||
{
|
||||
return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);
|
||||
}
|
||||
32
vendor/librw/src/gl/shaders/header_fs.inc
vendored
Normal file
32
vendor/librw/src/gl/shaders/header_fs.inc
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
const char *header_frag_src =
|
||||
"#ifdef USE_UBOS\n"
|
||||
"layout(std140) uniform State\n"
|
||||
"{\n"
|
||||
" vec2 u_alphaRef;\n"
|
||||
" vec4 u_fogData;\n"
|
||||
" vec4 u_fogColor;\n"
|
||||
"};\n"
|
||||
"#else\n"
|
||||
"uniform vec4 u_alphaRef;\n"
|
||||
|
||||
"uniform vec4 u_fogData;\n"
|
||||
"uniform vec4 u_fogColor;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#define u_fogStart (u_fogData.x)\n"
|
||||
"#define u_fogEnd (u_fogData.y)\n"
|
||||
"#define u_fogRange (u_fogData.z)\n"
|
||||
"#define u_fogDisable (u_fogData.w)\n"
|
||||
|
||||
"#ifndef GL2\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"#endif\n"
|
||||
|
||||
"void DoAlphaTest(float a)\n"
|
||||
"{\n"
|
||||
"#ifndef NO_ALPHATEST\n"
|
||||
" if(a < u_alphaRef.x || a >= u_alphaRef.y)\n"
|
||||
" discard;\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
;
|
||||
130
vendor/librw/src/gl/shaders/header_vs.inc
vendored
Normal file
130
vendor/librw/src/gl/shaders/header_vs.inc
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
const char *header_vert_src =
|
||||
|
||||
"//#define DIRECTIONALS\n"
|
||||
"//#define POINTLIGHTS\n"
|
||||
"//#define SPOTLIGHTS\n"
|
||||
|
||||
"#define ATTRIB_POS 0\n"
|
||||
"#define ATTRIB_NORMAL 1\n"
|
||||
"#define ATTRIB_COLOR 2\n"
|
||||
"#define ATTRIB_WEIGHTS 3\n"
|
||||
"#define ATTRIB_INDICES 4\n"
|
||||
"#define ATTRIB_TEXCOORDS0 5\n"
|
||||
"#define ATTRIB_TEXCOORDS1 6\n"
|
||||
|
||||
|
||||
"VSIN(ATTRIB_NORMAL) vec3 in_normal;\n"
|
||||
"VSIN(ATTRIB_COLOR) vec4 in_color;\n"
|
||||
"VSIN(ATTRIB_WEIGHTS) vec4 in_weights;\n"
|
||||
"VSIN(ATTRIB_INDICES) vec4 in_indices;\n"
|
||||
"VSIN(ATTRIB_TEXCOORDS0) vec2 in_tex0;\n"
|
||||
"VSIN(ATTRIB_TEXCOORDS1) vec2 in_tex1;\n"
|
||||
|
||||
|
||||
"#ifdef USE_UBOS\n"
|
||||
"layout(std140) uniform State\n"
|
||||
"{\n"
|
||||
" vec2 u_alphaRef;\n"
|
||||
" vec4 u_fogData;\n"
|
||||
" vec4 u_fogColor;\n"
|
||||
"};\n"
|
||||
"#else\n"
|
||||
"uniform vec4 u_alphaRef;\n"
|
||||
"uniform vec4 u_fogData;\n"
|
||||
"uniform vec4 u_fogColor;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#define u_fogStart (u_fogData.x)\n"
|
||||
"#define u_fogEnd (u_fogData.y)\n"
|
||||
"#define u_fogRange (u_fogData.z)\n"
|
||||
"#define u_fogDisable (u_fogData.w)\n"
|
||||
|
||||
"#ifdef USE_UBOS\n"
|
||||
"layout(std140) uniform Scene\n"
|
||||
"{\n"
|
||||
" mat4 u_proj;\n"
|
||||
" mat4 u_view;\n"
|
||||
"};\n"
|
||||
"#else\n"
|
||||
"uniform mat4 u_proj;\n"
|
||||
"uniform mat4 u_view;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#define MAX_LIGHTS 8\n"
|
||||
|
||||
"#ifdef USE_UBOS\n"
|
||||
"layout(std140) uniform Object\n"
|
||||
"{\n"
|
||||
" mat4 u_world;\n"
|
||||
" vec4 u_ambLight;\n"
|
||||
" vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot\n"
|
||||
" vec4 u_lightPosition[MAX_LIGHTS];\n"
|
||||
" vec4 u_lightDirection[MAX_LIGHTS];\n"
|
||||
" vec4 u_lightColor[MAX_LIGHTS];\n"
|
||||
"};\n"
|
||||
"#else\n"
|
||||
"uniform mat4 u_world;\n"
|
||||
"uniform vec4 u_ambLight;\n"
|
||||
"uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot\n"
|
||||
"uniform vec4 u_lightPosition[MAX_LIGHTS];\n"
|
||||
"uniform vec4 u_lightDirection[MAX_LIGHTS];\n"
|
||||
"uniform vec4 u_lightColor[MAX_LIGHTS];\n"
|
||||
"#endif\n"
|
||||
|
||||
"uniform vec4 u_matColor;\n"
|
||||
"uniform vec4 u_surfProps; // amb, spec, diff, extra\n"
|
||||
|
||||
"#define surfAmbient (u_surfProps.x)\n"
|
||||
"#define surfSpecular (u_surfProps.y)\n"
|
||||
"#define surfDiffuse (u_surfProps.z)\n"
|
||||
|
||||
"vec3 DoDynamicLight(vec3 V, vec3 N)\n"
|
||||
"{\n"
|
||||
" vec3 color = vec3(0.0, 0.0, 0.0);\n"
|
||||
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
|
||||
" if(u_lightParams[i].x == 0.0)\n"
|
||||
" break;\n"
|
||||
"#ifdef DIRECTIONALS\n"
|
||||
" if(u_lightParams[i].x == 1.0){\n"
|
||||
" // direct\n"
|
||||
" float l = max(0.0, dot(N, -u_lightDirection[i].xyz));\n"
|
||||
" color += l*u_lightColor[i].rgb;\n"
|
||||
" }else\n"
|
||||
"#endif\n"
|
||||
"#ifdef POINTLIGHTS\n"
|
||||
" if(u_lightParams[i].x == 2.0){\n"
|
||||
" // point\n"
|
||||
" vec3 dir = V - u_lightPosition[i].xyz;\n"
|
||||
" float dist = length(dir);\n"
|
||||
" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n"
|
||||
" float l = max(0.0, dot(N, -normalize(dir)));\n"
|
||||
" color += l*u_lightColor[i].rgb*atten;\n"
|
||||
" }else\n"
|
||||
"#endif\n"
|
||||
"#ifdef SPOTLIGHTS\n"
|
||||
" if(u_lightParams[i].x == 3.0){\n"
|
||||
" // spot\n"
|
||||
" vec3 dir = V - u_lightPosition[i].xyz;\n"
|
||||
" float dist = length(dir);\n"
|
||||
" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n"
|
||||
" dir /= dist;\n"
|
||||
" float l = max(0.0, dot(N, -dir));\n"
|
||||
" float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point\n"
|
||||
" float ccos = -u_lightParams[i].z;\n"
|
||||
" float falloff = (pcos-ccos)/(1.0-ccos);\n"
|
||||
" if(falloff < 0.0) // outside of cone\n"
|
||||
" l = 0.0;\n"
|
||||
" l *= max(falloff, u_lightParams[i].w);\n"
|
||||
" return l*u_lightColor[i].rgb*atten;\n"
|
||||
" }else\n"
|
||||
"#endif\n"
|
||||
" ;\n"
|
||||
" }\n"
|
||||
" return color;\n"
|
||||
"}\n"
|
||||
|
||||
"float DoFog(float w)\n"
|
||||
"{\n"
|
||||
" return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);\n"
|
||||
"}\n"
|
||||
;
|
||||
18
vendor/librw/src/gl/shaders/im2d.vert
vendored
Normal file
18
vendor/librw/src/gl/shaders/im2d.vert
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
uniform vec4 u_xform;
|
||||
|
||||
VSIN(ATTRIB_POS) vec4 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
gl_Position = in_pos;
|
||||
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
|
||||
v_fog = DoFog(gl_Position.w);
|
||||
gl_Position.xyz *= gl_Position.w;
|
||||
v_color = in_color;
|
||||
v_tex0 = in_tex0;
|
||||
}
|
||||
20
vendor/librw/src/gl/shaders/im2d_gl.inc
vendored
Normal file
20
vendor/librw/src/gl/shaders/im2d_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const char *im2d_vert_src =
|
||||
"uniform vec4 u_xform;\n"
|
||||
|
||||
"VSIN(ATTRIB_POS) vec4 in_pos;\n"
|
||||
|
||||
"VSOUT vec4 v_color;\n"
|
||||
"VSOUT vec2 v_tex0;\n"
|
||||
"VSOUT float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = in_pos;\n"
|
||||
" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
|
||||
" v_fog = DoFog(gl_Position.w);\n"
|
||||
" gl_Position.xyz *= gl_Position.w;\n"
|
||||
" v_color = in_color;\n"
|
||||
" v_tex0 = in_tex0;\n"
|
||||
"}\n"
|
||||
;
|
||||
16
vendor/librw/src/gl/shaders/im3d.vert
vendored
Normal file
16
vendor/librw/src/gl/shaders/im3d.vert
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
VSIN(ATTRIB_POS) vec3 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 Vertex = u_world * vec4(in_pos, 1.0);
|
||||
vec4 CamVertex = u_view * Vertex;
|
||||
gl_Position = u_proj * CamVertex;
|
||||
v_color = in_color;
|
||||
v_tex0 = in_tex0;
|
||||
v_fog = DoFog(gl_Position.w);
|
||||
}
|
||||
18
vendor/librw/src/gl/shaders/im3d_gl.inc
vendored
Normal file
18
vendor/librw/src/gl/shaders/im3d_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const char *im3d_vert_src =
|
||||
"VSIN(ATTRIB_POS) vec3 in_pos;\n"
|
||||
|
||||
"VSOUT vec4 v_color;\n"
|
||||
"VSOUT vec2 v_tex0;\n"
|
||||
"VSOUT float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"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"
|
||||
" v_color = in_color;\n"
|
||||
" v_tex0 = in_tex0;\n"
|
||||
" v_fog = DoFog(gl_Position.w);\n"
|
||||
"}\n"
|
||||
;
|
||||
34
vendor/librw/src/gl/shaders/matfx_env.frag
vendored
Normal file
34
vendor/librw/src/gl/shaders/matfx_env.frag
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
|
||||
uniform vec4 u_fxparams;
|
||||
|
||||
#define shininess (u_fxparams.x)
|
||||
#define disableFBA (u_fxparams.y)
|
||||
|
||||
FSIN vec4 v_color;
|
||||
FSIN vec4 v_envColor;
|
||||
FSIN vec2 v_tex0;
|
||||
FSIN vec2 v_tex1;
|
||||
FSIN float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 pass1 = v_color;
|
||||
pass1 *= texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
|
||||
|
||||
vec4 pass2 = v_envColor*shininess*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
|
||||
|
||||
pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);
|
||||
pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog);
|
||||
|
||||
float fba = max(pass1.a, disableFBA);
|
||||
vec4 color;
|
||||
color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;
|
||||
color.a = pass1.a;
|
||||
|
||||
DoAlphaTest(color.a);
|
||||
|
||||
FRAGCOLOR(color);
|
||||
}
|
||||
31
vendor/librw/src/gl/shaders/matfx_env.vert
vendored
Normal file
31
vendor/librw/src/gl/shaders/matfx_env.vert
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
uniform mat4 u_texMatrix;
|
||||
uniform vec4 u_colorClamp;
|
||||
uniform vec4 u_envColor;
|
||||
|
||||
VSIN(ATTRIB_POS) vec3 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec4 v_envColor;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT vec2 v_tex1;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 Vertex = u_world * vec4(in_pos, 1.0);
|
||||
gl_Position = u_proj * u_view * Vertex;
|
||||
vec3 Normal = mat3(u_world) * in_normal;
|
||||
|
||||
v_tex0 = in_tex0;
|
||||
v_tex1 = (u_texMatrix * vec4(Normal, 1.0)).xy;
|
||||
|
||||
v_color = in_color;
|
||||
v_color.rgb += u_ambLight.rgb*surfAmbient;
|
||||
v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
|
||||
v_color = clamp(v_color, 0.0, 1.0);
|
||||
v_envColor = max(v_color, u_colorClamp) * u_envColor;
|
||||
v_color *= u_matColor;
|
||||
|
||||
v_fog = DoFog(gl_Position.w);
|
||||
}
|
||||
69
vendor/librw/src/gl/shaders/matfx_gl.inc
vendored
Normal file
69
vendor/librw/src/gl/shaders/matfx_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
const char *matfx_env_vert_src =
|
||||
"uniform mat4 u_texMatrix;\n"
|
||||
"uniform vec4 u_colorClamp;\n"
|
||||
"uniform vec4 u_envColor;\n"
|
||||
|
||||
"VSIN(ATTRIB_POS) vec3 in_pos;\n"
|
||||
|
||||
"VSOUT vec4 v_color;\n"
|
||||
"VSOUT vec4 v_envColor;\n"
|
||||
"VSOUT vec2 v_tex0;\n"
|
||||
"VSOUT vec2 v_tex1;\n"
|
||||
"VSOUT float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n"
|
||||
" gl_Position = u_proj * u_view * Vertex;\n"
|
||||
" vec3 Normal = mat3(u_world) * in_normal;\n"
|
||||
|
||||
" v_tex0 = in_tex0;\n"
|
||||
" v_tex1 = (u_texMatrix * vec4(Normal, 1.0)).xy;\n"
|
||||
|
||||
" v_color = in_color;\n"
|
||||
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
|
||||
" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
|
||||
" v_color = clamp(v_color, 0.0, 1.0);\n"
|
||||
" v_envColor = max(v_color, u_colorClamp) * u_envColor;\n"
|
||||
" v_color *= u_matColor;\n"
|
||||
|
||||
" v_fog = DoFog(gl_Position.w);\n"
|
||||
"}\n"
|
||||
;
|
||||
const char *matfx_env_frag_src =
|
||||
"uniform sampler2D tex0;\n"
|
||||
"uniform sampler2D tex1;\n"
|
||||
|
||||
"uniform vec4 u_fxparams;\n"
|
||||
|
||||
"#define shininess (u_fxparams.x)\n"
|
||||
"#define disableFBA (u_fxparams.y)\n"
|
||||
|
||||
"FSIN vec4 v_color;\n"
|
||||
"FSIN vec4 v_envColor;\n"
|
||||
"FSIN vec2 v_tex0;\n"
|
||||
"FSIN vec2 v_tex1;\n"
|
||||
"FSIN float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec4 pass1 = v_color;\n"
|
||||
" pass1 *= texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
|
||||
|
||||
" vec4 pass2 = v_envColor*shininess*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n"
|
||||
|
||||
" pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);\n"
|
||||
" pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog);\n"
|
||||
|
||||
" float fba = max(pass1.a, disableFBA);\n"
|
||||
" vec4 color;\n"
|
||||
" color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;\n"
|
||||
" color.a = pass1.a;\n"
|
||||
|
||||
" DoAlphaTest(color.a);\n"
|
||||
|
||||
" FRAGCOLOR(color);\n"
|
||||
"}\n"
|
||||
;
|
||||
15
vendor/librw/src/gl/shaders/simple.frag
vendored
Normal file
15
vendor/librw/src/gl/shaders/simple.frag
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
uniform sampler2D tex0;
|
||||
|
||||
FSIN vec4 v_color;
|
||||
FSIN vec2 v_tex0;
|
||||
FSIN float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
|
||||
color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
|
||||
DoAlphaTest(color.a);
|
||||
FRAGCOLOR(color);
|
||||
}
|
||||
|
||||
17
vendor/librw/src/gl/shaders/simple_fs_gl.inc
vendored
Normal file
17
vendor/librw/src/gl/shaders/simple_fs_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const char *simple_frag_src =
|
||||
"uniform sampler2D tex0;\n"
|
||||
|
||||
"FSIN vec4 v_color;\n"
|
||||
"FSIN vec2 v_tex0;\n"
|
||||
"FSIN float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec4 color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
|
||||
" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
|
||||
" DoAlphaTest(color.a);\n"
|
||||
" FRAGCOLOR(color);\n"
|
||||
"}\n"
|
||||
|
||||
;
|
||||
32
vendor/librw/src/gl/shaders/skin.vert
vendored
Normal file
32
vendor/librw/src/gl/shaders/skin.vert
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
uniform mat4 u_boneMatrices[64];
|
||||
|
||||
VSIN(ATTRIB_POS) vec3 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec3 SkinVertex = vec3(0.0, 0.0, 0.0);
|
||||
vec3 SkinNormal = vec3(0.0, 0.0, 0.0);
|
||||
for(int i = 0; i < 4; i++){
|
||||
SkinVertex += (u_boneMatrices[int(in_indices[i])] * vec4(in_pos, 1.0)).xyz * in_weights[i];
|
||||
SkinNormal += (mat3(u_boneMatrices[int(in_indices[i])]) * in_normal) * in_weights[i];
|
||||
}
|
||||
|
||||
vec4 Vertex = u_world * vec4(SkinVertex, 1.0);
|
||||
gl_Position = u_proj * u_view * Vertex;
|
||||
vec3 Normal = mat3(u_world) * SkinNormal;
|
||||
|
||||
v_tex0 = in_tex0;
|
||||
|
||||
v_color = in_color;
|
||||
v_color.rgb += u_ambLight.rgb*surfAmbient;
|
||||
v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;
|
||||
v_color = clamp(v_color, 0.0, 1.0);
|
||||
v_color *= u_matColor;
|
||||
|
||||
v_fog = DoFog(gl_Position.z);
|
||||
}
|
||||
34
vendor/librw/src/gl/shaders/skin_gl.inc
vendored
Normal file
34
vendor/librw/src/gl/shaders/skin_gl.inc
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
const char *skin_vert_src =
|
||||
"uniform mat4 u_boneMatrices[64];\n"
|
||||
|
||||
"VSIN(ATTRIB_POS) vec3 in_pos;\n"
|
||||
|
||||
"VSOUT vec4 v_color;\n"
|
||||
"VSOUT vec2 v_tex0;\n"
|
||||
"VSOUT float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" vec3 SkinVertex = vec3(0.0, 0.0, 0.0);\n"
|
||||
" vec3 SkinNormal = vec3(0.0, 0.0, 0.0);\n"
|
||||
" for(int i = 0; i < 4; i++){\n"
|
||||
" SkinVertex += (u_boneMatrices[int(in_indices[i])] * vec4(in_pos, 1.0)).xyz * in_weights[i];\n"
|
||||
" SkinNormal += (mat3(u_boneMatrices[int(in_indices[i])]) * in_normal) * in_weights[i];\n"
|
||||
" }\n"
|
||||
|
||||
" vec4 Vertex = u_world * vec4(SkinVertex, 1.0);\n"
|
||||
" gl_Position = u_proj * u_view * Vertex;\n"
|
||||
" vec3 Normal = mat3(u_world) * SkinNormal;\n"
|
||||
|
||||
" v_tex0 = in_tex0;\n"
|
||||
|
||||
" v_color = in_color;\n"
|
||||
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
|
||||
" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n"
|
||||
" v_color = clamp(v_color, 0.0, 1.0);\n"
|
||||
" v_color *= u_matColor;\n"
|
||||
|
||||
" v_fog = DoFog(gl_Position.z);\n"
|
||||
"}\n"
|
||||
;
|
||||
875
vendor/librw/src/gl/wdgl.cpp
vendored
Normal file
875
vendor/librw/src/gl/wdgl.cpp
vendored
Normal file
|
|
@ -0,0 +1,875 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwplugins.h"
|
||||
#include "rwwdgl.h"
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
#include "glad/glad.h"
|
||||
#endif
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace wdgl {
|
||||
|
||||
static void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
engine->driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
driverClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
registerPlatformPlugins(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_WDGL, 0, PLATFORM_WDGL,
|
||||
driverOpen, driverClose);
|
||||
}
|
||||
|
||||
|
||||
// VC
|
||||
// 8733 0 0 0 3
|
||||
// 45 1 0 0 2
|
||||
// 8657 1 3 0 2
|
||||
// 4610 2 1 1 3
|
||||
// 4185 3 2 1 4
|
||||
// 256 4 2 1 4
|
||||
// 201 4 4 1 4
|
||||
// 457 5 2 0 4
|
||||
|
||||
// SA
|
||||
// 20303 0 0 0 3 vertices: 3 floats
|
||||
// 53 1 0 0 2 texCoords: 2 floats
|
||||
// 20043 1 3 0 2 texCoords: 2 shorts
|
||||
// 6954 2 1 1 3 normal: 3 bytes normalized
|
||||
// 13527 3 2 1 4 color: 4 ubytes normalized
|
||||
// 196 4 2 1 4 weight: 4 ubytes normalized
|
||||
// 225 4 4 1 4 weight: 4 ushorts normalized
|
||||
// 421 5 2 0 4 indices: 4 ubytes
|
||||
// 12887 6 2 1 4 extracolor:4 ubytes normalized
|
||||
|
||||
/*
|
||||
static void
|
||||
printAttribInfo(AttribDesc *attribs, int n)
|
||||
{
|
||||
for(int i = 0; i < n; i++)
|
||||
printf("%x %x %x %x\n",
|
||||
attribs[i].index,
|
||||
attribs[i].type,
|
||||
attribs[i].normalized,
|
||||
attribs[i].size);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
void
|
||||
uploadGeo(Geometry *geo)
|
||||
{
|
||||
InstanceDataHeader *inst = (InstanceDataHeader*)geo->instData;
|
||||
MeshHeader *meshHeader = geo->meshHeader;
|
||||
|
||||
glGenBuffers(1, &inst->vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, inst->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, inst->dataSize,
|
||||
inst->data, GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &inst->ibo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, inst->ibo);
|
||||
glBufferData(GL_ARRAY_BUFFER, meshHeader->totalIndices*2,
|
||||
0, GL_STATIC_DRAW);
|
||||
GLintptr offset = 0;
|
||||
for(uint32 i = 0; i < meshHeader->numMeshes; i++){
|
||||
Mesh *mesh = &meshHeader->getMeshes()[i];
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, mesh->numIndices*2,
|
||||
mesh->indices);
|
||||
offset += mesh->numIndices*2;
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void
|
||||
setAttribPointers(InstanceDataHeader *inst)
|
||||
{
|
||||
static GLenum attribType[] = {
|
||||
GL_FLOAT,
|
||||
GL_BYTE, GL_UNSIGNED_BYTE,
|
||||
GL_SHORT, GL_UNSIGNED_SHORT
|
||||
};
|
||||
for(int32 i = 0; i < inst->numAttribs; i++){
|
||||
AttribDesc *a = &inst->attribs[i];
|
||||
glEnableVertexAttribArray(a->index);
|
||||
glVertexAttribPointer(a->index, a->size, attribType[a->type],
|
||||
a->normalized, a->stride,
|
||||
(void*)(uint64)a->offset);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale=1.0f)
|
||||
{
|
||||
int8 *i8dst;
|
||||
uint16 *u16dst;
|
||||
int16 *i16dst;
|
||||
|
||||
switch(a->type){
|
||||
case 0: // float
|
||||
memcpy(dst, src, a->size*4);
|
||||
break;
|
||||
|
||||
// TODO: maybe have loop inside if?
|
||||
case 1: // byte
|
||||
i8dst = (int8*)dst;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
i8dst[i] = src[i]*scale;
|
||||
else
|
||||
i8dst[i] = src[i]*127.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // ubyte
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
dst[i] = src[i]*scale;
|
||||
else
|
||||
dst[i] = src[i]*255.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // short
|
||||
i16dst = (int16*)dst;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
i16dst[i] = src[i]*scale;
|
||||
else
|
||||
i16dst[i] = src[i]*32767.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // ushort
|
||||
u16dst = (uint16*)dst;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
u16dst[i] = src[i]*scale;
|
||||
else
|
||||
u16dst[i] = src[i]*65535.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale=1.0f)
|
||||
{
|
||||
int8 *i8src;
|
||||
uint16 *u16src;
|
||||
int16 *i16src;
|
||||
|
||||
switch(a->type){
|
||||
case 0: // float
|
||||
memcpy(dst, src, a->size*4);
|
||||
break;
|
||||
|
||||
// TODO: maybe have loop inside if?
|
||||
case 1: // byte
|
||||
i8src = (int8*)src;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
dst[i] = i8src[i]/scale;
|
||||
else
|
||||
dst[i] = i8src[i]/127.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // ubyte
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
dst[i] = src[i]/scale;
|
||||
else
|
||||
dst[i] = src[i]/255.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // short
|
||||
i16src = (int16*)src;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
dst[i] = i16src[i]/scale;
|
||||
else
|
||||
dst[i] = i16src[i]/32767.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // ushort
|
||||
u16src = (uint16*)src;
|
||||
for(int i = 0; i < a->size; i++){
|
||||
if(!a->normalized)
|
||||
dst[i] = u16src[i]/scale;
|
||||
else
|
||||
dst[i] = u16src[i]/65435.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_WDGL)
|
||||
return object;
|
||||
InstanceDataHeader *header =
|
||||
(InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = nil;
|
||||
// TODO: delete ibo and vbo
|
||||
rwFree(header->attribs);
|
||||
rwFree(header->data);
|
||||
rwFree(header);
|
||||
return object;
|
||||
}
|
||||
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
geometry->instData = header;
|
||||
header->platform = PLATFORM_WDGL;
|
||||
header->vbo = 0;
|
||||
header->ibo = 0;
|
||||
header->numAttribs = stream->readU32();
|
||||
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
stream->read32(header->attribs,
|
||||
header->numAttribs*sizeof(AttribDesc));
|
||||
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
||||
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
ASSERTLITTLE;
|
||||
stream->read8(header->data, header->dataSize);
|
||||
return stream;
|
||||
}
|
||||
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_WDGL)
|
||||
return stream;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
stream->writeU32(header->numAttribs);
|
||||
stream->write32(header->attribs, header->numAttribs*sizeof(AttribDesc));
|
||||
ASSERTLITTLE;
|
||||
stream->write8(header->data, header->dataSize);
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
getSizeNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_WDGL)
|
||||
return 0;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
|
||||
}
|
||||
|
||||
void
|
||||
registerNativeDataPlugin(void)
|
||||
{
|
||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||
nil, destroyNativeData, nil);
|
||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
||||
readNativeData,
|
||||
writeNativeData,
|
||||
getSizeNativeData);
|
||||
}
|
||||
|
||||
void
|
||||
printPipeinfo(Atomic *a)
|
||||
{
|
||||
Geometry *g = a->geometry;
|
||||
if(g->instData == nil || g->instData->platform != PLATFORM_WDGL)
|
||||
return;
|
||||
int32 plgid = 0;
|
||||
if(a->pipeline)
|
||||
plgid = a->pipeline->pluginID;
|
||||
printf("%s %x: ", debugFile, plgid);
|
||||
InstanceDataHeader *h = (InstanceDataHeader*)g->instData;
|
||||
for(int i = 0; i < h->numAttribs; i++)
|
||||
printf("%x(%x) ", h->attribs[i].index, h->attribs[i].type);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
// TODO: allow for REINSTANCE (or not, wdgl can't render)
|
||||
if(geo->instData)
|
||||
return;
|
||||
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
geo->instData = header;
|
||||
header->platform = PLATFORM_WDGL;
|
||||
header->vbo = 0;
|
||||
header->ibo = 0;
|
||||
header->numAttribs =
|
||||
pipe->numCustomAttribs + 1 + (geo->numTexCoordSets > 0);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
header->numAttribs++;
|
||||
if(geo->flags & Geometry::NORMALS)
|
||||
header->numAttribs++;
|
||||
int32 offset = 0;
|
||||
header->attribs = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
|
||||
AttribDesc *a = header->attribs;
|
||||
// Vertices
|
||||
a->index = 0;
|
||||
a->type = 0;
|
||||
a->normalized = 0;
|
||||
a->size = 3;
|
||||
a->offset = offset;
|
||||
offset += 12;
|
||||
a++;
|
||||
int32 firstCustom = 1;
|
||||
|
||||
// texCoords, only one set here
|
||||
if(geo->numTexCoordSets){
|
||||
a->index = 1;
|
||||
a->type = 3;
|
||||
a->normalized = 0;
|
||||
a->size = 2;
|
||||
a->offset = offset;
|
||||
offset += 4;
|
||||
a++;
|
||||
firstCustom++;
|
||||
}
|
||||
|
||||
if(geo->flags & Geometry::NORMALS){
|
||||
a->index = 2;
|
||||
a->type = 1;
|
||||
a->normalized = 1;
|
||||
a->size = 3;
|
||||
a->offset = offset;
|
||||
offset += 4;
|
||||
a++;
|
||||
firstCustom++;
|
||||
}
|
||||
|
||||
if(geo->flags & Geometry::PRELIT){
|
||||
a->index = 3;
|
||||
a->type = 2;
|
||||
a->normalized = 1;
|
||||
a->size = 4;
|
||||
a->offset = offset;
|
||||
offset += 4;
|
||||
a++;
|
||||
firstCustom++;
|
||||
}
|
||||
|
||||
if(pipe->instanceCB)
|
||||
offset += pipe->instanceCB(geo, firstCustom, offset);
|
||||
else{
|
||||
header->dataSize = offset*geo->numVertices;
|
||||
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
}
|
||||
|
||||
a = header->attribs;
|
||||
for(int32 i = 0; i < header->numAttribs; i++)
|
||||
a[i].stride = offset;
|
||||
|
||||
uint8 *p = header->data + a->offset;
|
||||
V3d *vert = geo->morphTargets->vertices;
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
packattrib(p, (float32*)vert, a);
|
||||
vert++;
|
||||
p += a->stride;
|
||||
}
|
||||
a++;
|
||||
|
||||
if(geo->numTexCoordSets){
|
||||
p = header->data + a->offset;
|
||||
TexCoords *texcoord = geo->texCoords[0];
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
packattrib(p, (float32*)texcoord, a, 512.0f);
|
||||
texcoord++;
|
||||
p += a->stride;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
if(geo->flags & Geometry::NORMALS){
|
||||
p = header->data + a->offset;
|
||||
V3d *norm = geo->morphTargets->normals;
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
packattrib(p, (float32*)norm, a);
|
||||
norm++;
|
||||
p += a->stride;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
if(geo->flags & Geometry::PRELIT){
|
||||
// TODO: this seems too complicated
|
||||
p = header->data + a->offset;
|
||||
RGBA *color = geo->colors;
|
||||
float32 f[4];
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
f[0] = color->red/255.0f;
|
||||
f[1] = color->green/255.0f;
|
||||
f[2] = color->blue/255.0f;
|
||||
f[3] = color->alpha/255.0f;
|
||||
packattrib(p, (float32*)f, a);
|
||||
color++;
|
||||
p += a->stride;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->flags & Geometry::NATIVE) == 0)
|
||||
return;
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_WDGL);
|
||||
geo->numTriangles = geo->meshHeader->guessNumTriangles();
|
||||
geo->allocateData();
|
||||
|
||||
uint8 *p;
|
||||
TexCoords *texcoord = geo->texCoords[0];
|
||||
RGBA *color = geo->colors;
|
||||
V3d *vert = geo->morphTargets->vertices;
|
||||
V3d *norm = geo->morphTargets->normals;
|
||||
float32 f[4];
|
||||
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||
for(int i = 0; i < header->numAttribs; i++){
|
||||
AttribDesc *a = &header->attribs[i];
|
||||
p = header->data + a->offset;
|
||||
|
||||
switch(a->index){
|
||||
case 0: // Vertices
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
unpackattrib((float32*)vert, p, a);
|
||||
vert++;
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // texCoords
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
unpackattrib((float32*)texcoord, p, a, 512.0f);
|
||||
texcoord++;
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // normals
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
unpackattrib((float32*)norm, p, a);
|
||||
norm++;
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // colors
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
// TODO: this seems too complicated
|
||||
unpackattrib(f, p, a);
|
||||
color->red = f[0]*255.0f;
|
||||
color->green = f[1]*255.0f;
|
||||
color->blue = f[2]*255.0f;
|
||||
color->alpha = f[3]*255.0f;
|
||||
color++;
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pipe->uninstanceCB)
|
||||
pipe->uninstanceCB(geo);
|
||||
|
||||
geo->generateTriangles();
|
||||
|
||||
geo->flags &= ~Geometry::NATIVE;
|
||||
destroyNativeData(geo, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ObjPipeline::init(void)
|
||||
{
|
||||
this->rw::ObjPipeline::init(PLATFORM_GL3);
|
||||
this->numCustomAttribs = 0;
|
||||
this->impl.instance = wdgl::instance;
|
||||
this->impl.uninstance = wdgl::uninstance;
|
||||
this->instanceCB = nil;
|
||||
this->uninstanceCB = nil;
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
ObjPipeline::create(void)
|
||||
{
|
||||
ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL);
|
||||
pipe->init();
|
||||
return pipe;
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeDefaultPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// Skin
|
||||
|
||||
Stream*
|
||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
if(platform != PLATFORM_GL){
|
||||
RWERROR((ERR_PLATFORM, platform));
|
||||
return nil;
|
||||
}
|
||||
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||
|
||||
int32 numBones = stream->readI32();
|
||||
skin->init(numBones, 0, 0);
|
||||
stream->read32(skin->inverseMatrices, skin->numBones*64);
|
||||
return stream;
|
||||
}
|
||||
|
||||
Stream*
|
||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
{
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
stream->writeU32(PLATFORM_GL);
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||
stream->writeI32(skin->numBones);
|
||||
stream->write32(skin->inverseMatrices, skin->numBones*64);
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
getSizeNativeSkin(void *object, int32 offset)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||
if(skin == nil)
|
||||
return -1;
|
||||
int32 size = 12 + 4 + 4 + skin->numBones*64;
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32
|
||||
skinInstanceCB(Geometry *g, int32 i, uint32 offset)
|
||||
{
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)g->instData;
|
||||
AttribDesc *a = &header->attribs[i];
|
||||
// weights
|
||||
a->index = 4;
|
||||
a->type = 2; /* but also short o_O */
|
||||
a->normalized = 1;
|
||||
a->size = 4;
|
||||
a->offset = offset;
|
||||
offset += 4;
|
||||
a++;
|
||||
|
||||
// indices
|
||||
a->index = 5;
|
||||
a->type = 2;
|
||||
a->normalized = 0;
|
||||
a->size = 4;
|
||||
a->offset = offset;
|
||||
offset += 4;
|
||||
|
||||
header->dataSize = offset*g->numVertices;
|
||||
header->data = rwNewT(uint8, header->dataSize, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
|
||||
Skin *skin = Skin::get(g);
|
||||
if(skin == nil)
|
||||
return 8;
|
||||
|
||||
a = &header->attribs[i];
|
||||
uint8 *wgt = header->data + a[0].offset;
|
||||
uint8 *idx = header->data + a[1].offset;
|
||||
uint8 *indices = skin->indices;
|
||||
float32 *weights = skin->weights;
|
||||
for(int32 i = 0; i < g->numVertices; i++){
|
||||
packattrib(wgt, weights, a);
|
||||
weights += 4;
|
||||
wgt += offset;
|
||||
idx[0] = *indices++;
|
||||
idx[1] = *indices++;
|
||||
idx[2] = *indices++;
|
||||
idx[3] = *indices++;
|
||||
idx += offset;
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
void
|
||||
skinUninstanceCB(Geometry *geo)
|
||||
{
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||
|
||||
Skin *skin = Skin::get(geo);
|
||||
if(skin == nil)
|
||||
return;
|
||||
|
||||
uint8 *data = skin->data;
|
||||
float *invMats = skin->inverseMatrices;
|
||||
skin->init(skin->numBones, skin->numBones, geo->numVertices);
|
||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||
rwFree(data);
|
||||
|
||||
uint8 *p;
|
||||
float *weights = skin->weights;
|
||||
uint8 *indices = skin->indices;
|
||||
for(int i = 0; i < header->numAttribs; i++){
|
||||
AttribDesc *a = &header->attribs[i];
|
||||
p = header->data + a->offset;
|
||||
|
||||
switch(a->index){
|
||||
case 4: // weights
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
unpackattrib(weights, p, a);
|
||||
float sum = weights[0] + weights[1] + weights[2] + weights[3];
|
||||
if(sum){
|
||||
weights[0] /= sum;
|
||||
weights[1] /= sum;
|
||||
weights[2] /= sum;
|
||||
weights[3] /= sum;
|
||||
}
|
||||
weights += 4;
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: // indices
|
||||
for(int32 i = 0; i < geo->numVertices; i++){
|
||||
*indices++ = p[0];
|
||||
*indices++ = p[1];
|
||||
*indices++ = p[2];
|
||||
*indices++ = p[3];
|
||||
p += a->stride;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skin->findNumWeights(geo->numVertices);
|
||||
skin->findUsedBones(geo->numVertices);
|
||||
}
|
||||
|
||||
// Skin
|
||||
|
||||
static void*
|
||||
skinOpen(void *o, int32, int32)
|
||||
{
|
||||
skinGlobals.pipelines[PLATFORM_WDGL] = makeSkinPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
skinClose(void *o, int32, int32)
|
||||
{
|
||||
((ObjPipeline*)skinGlobals.pipelines[PLATFORM_WDGL])->destroy();
|
||||
skinGlobals.pipelines[PLATFORM_WDGL] = nil;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initSkin(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_WDGL, 0, ID_SKIN,
|
||||
skinOpen, skinClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeSkinPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
pipe->pluginID = ID_SKIN;
|
||||
pipe->pluginData = 1;
|
||||
pipe->numCustomAttribs = 2;
|
||||
pipe->instanceCB = skinInstanceCB;
|
||||
pipe->uninstanceCB = skinUninstanceCB;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// MatFX
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
||||
matFXGlobals.pipelines[PLATFORM_WDGL] = makeMatFXPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
matfxClose(void *o, int32, int32)
|
||||
{
|
||||
((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_WDGL])->destroy();
|
||||
matFXGlobals.pipelines[PLATFORM_WDGL] = nil;
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initMatFX(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_WDGL, 0, ID_MATFX,
|
||||
matfxOpen, matfxClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeMatFXPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = ObjPipeline::create();
|
||||
pipe->pluginID = ID_MATFX;
|
||||
pipe->pluginData = 0;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// Raster
|
||||
|
||||
int32 nativeRasterOffset;
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
struct GlRaster {
|
||||
GLuint id;
|
||||
};
|
||||
|
||||
static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
GlRaster *raster = PLUGINOFFSET(GlRaster, object, offset);
|
||||
raster->id = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
destroyNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
// TODO:
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
copyNativeRaster(void *dst, void *, int32 offset, int32)
|
||||
{
|
||||
GlRaster *raster = PLUGINOFFSET(GlRaster, dst, offset);
|
||||
raster->id = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
registerNativeRaster(void)
|
||||
{
|
||||
nativeRasterOffset = Raster::registerPlugin(sizeof(GlRaster),
|
||||
ID_RASTERWDGL,
|
||||
createNativeRaster,
|
||||
destroyNativeRaster,
|
||||
copyNativeRaster);
|
||||
}
|
||||
|
||||
void
|
||||
Texture::upload(void)
|
||||
{
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
Raster *r = this->raster;
|
||||
if(r->palette){
|
||||
printf("can't upload paletted raster\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static GLenum filter[] = {
|
||||
0, GL_NEAREST, GL_LINEAR,
|
||||
GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST,
|
||||
GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR
|
||||
};
|
||||
static GLenum filternomip[] = {
|
||||
0, GL_NEAREST, GL_LINEAR,
|
||||
GL_NEAREST, GL_LINEAR,
|
||||
GL_NEAREST, GL_LINEAR
|
||||
};
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
filternomip[this->filterAddressing & 0xFF]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
filternomip[this->filterAddressing & 0xFF]);
|
||||
|
||||
static GLenum wrap[] = {
|
||||
0, GL_REPEAT, GL_MIRRORED_REPEAT,
|
||||
GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
|
||||
};
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||
wrap[(this->filterAddressing >> 8) & 0xF]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
||||
wrap[(this->filterAddressing >> 12) & 0xF]);
|
||||
|
||||
switch(r->format & 0xF00){
|
||||
case Raster::C8888:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, r->width, r->height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, r->pixels);
|
||||
break;
|
||||
default:
|
||||
printf("unsupported raster format: %x\n", r->format);
|
||||
break;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
GlRaster *glr = PLUGINOFFSET(GlRaster, r, nativeRasterOffset);
|
||||
glr->id = id;
|
||||
}
|
||||
|
||||
void
|
||||
Texture::bind(int n)
|
||||
{
|
||||
Raster *r = this->raster;
|
||||
GlRaster *glr = PLUGINOFFSET(GlRaster, r, nativeRasterOffset);
|
||||
glActiveTexture(GL_TEXTURE0+n);
|
||||
if(r){
|
||||
if(glr->id == 0)
|
||||
this->upload();
|
||||
glBindTexture(GL_TEXTURE_2D, glr->id);
|
||||
}else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue