librw/src/pipeline.cpp

190 lines
3.9 KiB
C++
Raw Normal View History

2015-07-12 22:57:05 +02:00
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "rwbase.h"
2016-06-16 14:08:09 +02:00
#include "rwplg.h"
2015-07-12 22:57:05 +02:00
#include "rwpipeline.h"
#include "rwobjects.h"
#define COLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
2015-07-12 22:57:05 +02:00
namespace rw {
2016-02-14 00:52:45 +01:00
static void nothing(ObjPipeline *, Atomic*) {}
2015-07-12 22:57:05 +02:00
Pipeline::Pipeline(uint32 platform)
{
this->pluginID = 0;
this->pluginData = 0;
this->platform = platform;
}
2016-02-14 00:52:45 +01:00
ObjPipeline::ObjPipeline(uint32 platform)
: Pipeline(platform)
2015-08-01 23:03:10 +02:00
{
2016-02-14 00:52:45 +01:00
this->impl.instance = nothing;
this->impl.uninstance = nothing;
this->impl.render = nothing;
2015-08-01 23:03:10 +02:00
}
// helper functions
void
findMinVertAndNumVertices(uint16 *indices, uint32 numIndices, uint32 *minVert, int32 *numVertices)
{
uint32 min = 0xFFFFFFFF;
uint32 max = 0;
while(numIndices--){
if(*indices < min)
min = *indices;
if(*indices > max)
max = *indices;
indices++;
}
2018-07-04 19:21:34 +02:00
uint32 num = max - min + 1;
// if mesh is empty, this can happen
if(min > max){
min = 0;
num = 0;
}
if(minVert)
*minVert = min;
if(numVertices)
2018-07-04 19:21:34 +02:00
*numVertices = num;
}
void
2017-08-05 01:44:37 +02:00
instV4d(int type, uint8 *dst, V4d *src, uint32 numVertices, uint32 stride)
{
if(type == VERT_FLOAT4)
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 16);
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
else
2017-08-05 01:44:37 +02:00
assert(0 && "unsupported instV4d type");
}
void
2017-08-05 01:44:37 +02:00
instV3d(int type, uint8 *dst, V3d *src, uint32 numVertices, uint32 stride)
{
if(type == VERT_FLOAT3)
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 12);
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
else if(type == VERT_COMPNORM)
for(uint32 i = 0; i < numVertices; i++){
2017-08-05 01:44:37 +02:00
uint32 n = ((((uint32)(src->z * 511.0f)) & 0x3ff) << 22) |
((((uint32)(src->y * 1023.0f)) & 0x7ff) << 11) |
((((uint32)(src->x * 1023.0f)) & 0x7ff) << 0);
*(uint32*)dst = n;
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
else
assert(0 && "unsupported instV3d type");
}
2015-09-07 23:00:28 +02:00
void
2017-08-05 01:44:37 +02:00
uninstV3d(int type, V3d *dst, uint8 *src, uint32 numVertices, uint32 stride)
2015-09-07 23:00:28 +02:00
{
if(type == VERT_FLOAT3)
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 12);
src += stride;
2017-08-05 01:44:37 +02:00
dst++;
2015-09-07 23:00:28 +02:00
}
else if(type == VERT_COMPNORM)
for(uint32 i = 0; i < numVertices; i++){
uint32 n = *(uint32*)src;
int32 normal[3];
normal[0] = n & 0x7FF;
normal[1] = (n >> 11) & 0x7FF;
normal[2] = (n >> 22) & 0x3FF;
// sign extend
if(normal[0] & 0x400) normal[0] |= ~0x7FF;
if(normal[1] & 0x400) normal[1] |= ~0x7FF;
if(normal[2] & 0x200) normal[2] |= ~0x3FF;
2017-08-05 01:44:37 +02:00
dst->x = normal[0] / 1023.0f;
dst->y = normal[1] / 1023.0f;
dst->z = normal[2] / 511.0f;
2015-09-07 23:00:28 +02:00
src += stride;
2017-08-05 01:44:37 +02:00
dst++;
2015-09-07 23:00:28 +02:00
}
else
assert(0 && "unsupported uninstV3d type");
}
void
2017-08-05 01:44:37 +02:00
instTexCoords(int type, uint8 *dst, TexCoords *src, uint32 numVertices, uint32 stride)
{
assert(type == VERT_FLOAT2);
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 8);
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
}
2015-09-07 23:00:28 +02:00
void
2017-08-05 01:44:37 +02:00
uninstTexCoords(int type, TexCoords *dst, uint8 *src, uint32 numVertices, uint32 stride)
2015-09-07 23:00:28 +02:00
{
assert(type == VERT_FLOAT2);
for(uint32 i = 0; i < numVertices; i++){
memcpy(dst, src, 8);
src += stride;
2017-08-05 01:44:37 +02:00
dst++;
2015-09-07 23:00:28 +02:00
}
}
bool32
2017-08-05 01:44:37 +02:00
instColor(int type, uint8 *dst, RGBA *src, uint32 numVertices, uint32 stride)
{
2018-01-03 18:02:02 +01:00
uint8 alpha = 0xFF;
if(type == VERT_ARGB){
for(uint32 i = 0; i < numVertices; i++){
2017-08-05 01:44:37 +02:00
dst[0] = src->blue;
dst[1] = src->green;
dst[2] = src->red;
dst[3] = src->alpha;
2018-01-03 18:02:02 +01:00
alpha &= src->alpha;
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
}else if(type == VERT_RGBA){
for(uint32 i = 0; i < numVertices; i++){
2017-08-05 01:44:37 +02:00
dst[0] = src->red;
dst[1] = src->green;
dst[2] = src->blue;
dst[3] = src->alpha;
2018-01-03 18:02:02 +01:00
alpha &= src->alpha;
dst += stride;
2017-08-05 01:44:37 +02:00
src++;
}
}else
assert(0 && "unsupported color type");
2018-01-03 18:02:02 +01:00
return alpha != 0xFF;
}
2015-09-07 23:00:28 +02:00
void
2017-08-05 01:44:37 +02:00
uninstColor(int type, RGBA *dst, uint8 *src, uint32 numVertices, uint32 stride)
2015-09-07 23:00:28 +02:00
{
assert(type == VERT_ARGB);
for(uint32 i = 0; i < numVertices; i++){
2017-08-05 01:44:37 +02:00
dst->red = src[2];
dst->green = src[1];
dst->blue = src[0];
dst->alpha = src[3];
2015-09-07 23:00:28 +02:00
src += stride;
2017-08-05 01:44:37 +02:00
dst++;
2015-09-07 23:00:28 +02:00
}
}
2015-07-12 22:57:05 +02:00
}