2014-12-23 11:29:37 +01:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include "rwbase.h"
|
|
|
|
#include "rwplugin.h"
|
2014-12-23 15:59:14 +01:00
|
|
|
#include "rwobjects.h"
|
2014-12-23 11:29:37 +01:00
|
|
|
#include "rwogl.h"
|
|
|
|
|
2014-12-24 11:38:25 +01:00
|
|
|
#include <GL/glew.h>
|
|
|
|
|
2014-12-23 11:29:37 +01:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace Rw {
|
2014-12-24 11:38:25 +01:00
|
|
|
namespace Gl {
|
2014-12-23 11:29:37 +01:00
|
|
|
|
2014-12-24 14:04:46 +01:00
|
|
|
static void
|
|
|
|
printAttribInfo(AttribDesc *attribs, int n)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < n; i++)
|
|
|
|
printf("%x %x %x %x %x %x\n",
|
|
|
|
attribs[i].index,
|
|
|
|
attribs[i].type,
|
|
|
|
attribs[i].normalized,
|
|
|
|
attribs[i].size);
|
|
|
|
}
|
|
|
|
|
2014-12-23 11:29:37 +01:00
|
|
|
void*
|
2014-12-24 11:38:25 +01:00
|
|
|
DestroyNativeData(void *object, int32, int32)
|
2014-12-23 11:29:37 +01:00
|
|
|
{
|
|
|
|
Geometry *geometry = (Geometry*)object;
|
|
|
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
2014-12-24 11:38:25 +01:00
|
|
|
InstanceDataHeader *header =
|
|
|
|
(InstanceDataHeader*)geometry->instData;
|
2014-12-23 11:29:37 +01:00
|
|
|
delete[] header->attribs;
|
|
|
|
delete[] header->data;
|
|
|
|
delete header;
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-12-24 11:38:25 +01:00
|
|
|
ReadNativeData(istream &stream, int32, void *object, int32, int32)
|
2014-12-23 11:29:37 +01:00
|
|
|
{
|
|
|
|
Geometry *geometry = (Geometry*)object;
|
2014-12-24 11:38:25 +01:00
|
|
|
InstanceDataHeader *header = new InstanceDataHeader;
|
2014-12-23 11:29:37 +01:00
|
|
|
geometry->instData = header;
|
|
|
|
header->platform = PLATFORM_OGL;
|
2014-12-24 11:38:25 +01:00
|
|
|
header->vbo = 0;
|
|
|
|
header->ibo = 0;
|
2014-12-23 11:29:37 +01:00
|
|
|
header->numAttribs = readUInt32(stream);
|
2014-12-24 11:38:25 +01:00
|
|
|
header->attribs = new AttribDesc[header->numAttribs];
|
2014-12-23 11:29:37 +01:00
|
|
|
stream.read((char*)header->attribs,
|
2014-12-24 11:38:25 +01:00
|
|
|
header->numAttribs*sizeof(AttribDesc));
|
2014-12-23 11:29:37 +01:00
|
|
|
// Any better way to find out the size? (header length can be wrong)
|
|
|
|
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
|
|
|
header->data = new uint8[header->dataSize];
|
|
|
|
stream.read((char*)header->data, header->dataSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-12-24 11:38:25 +01:00
|
|
|
WriteNativeData(ostream &stream, int32 len, void *object, int32, int32)
|
2014-12-23 11:29:37 +01:00
|
|
|
{
|
|
|
|
Geometry *geometry = (Geometry*)object;
|
|
|
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
2014-12-24 11:38:25 +01:00
|
|
|
InstanceDataHeader *header =
|
|
|
|
(InstanceDataHeader*)geometry->instData;
|
2014-12-23 11:29:37 +01:00
|
|
|
writeUInt32(header->numAttribs, stream);
|
|
|
|
stream.write((char*)header->attribs,
|
2014-12-24 11:38:25 +01:00
|
|
|
header->numAttribs*sizeof(AttribDesc));
|
2014-12-23 11:29:37 +01:00
|
|
|
stream.write((char*)header->data, header->dataSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32
|
2014-12-24 11:38:25 +01:00
|
|
|
GetSizeNativeData(void *object, int32, int32)
|
2014-12-23 11:29:37 +01:00
|
|
|
{
|
|
|
|
Geometry *geometry = (Geometry*)object;
|
|
|
|
assert(geometry->instData->platform == PLATFORM_OGL);
|
2014-12-24 11:38:25 +01:00
|
|
|
InstanceDataHeader *header =
|
|
|
|
(InstanceDataHeader*)geometry->instData;
|
|
|
|
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
|
2014-12-23 11:29:37 +01:00
|
|
|
}
|
|
|
|
|
2014-12-24 11:38:25 +01:00
|
|
|
|
2014-12-24 14:04:46 +01:00
|
|
|
#ifdef RW_OPENGL
|
2014-12-24 11:38:25 +01:00
|
|
|
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->mesh[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);
|
|
|
|
}
|
|
|
|
}
|
2014-12-24 14:04:46 +01:00
|
|
|
#endif
|
2014-12-24 11:38:25 +01:00
|
|
|
|
|
|
|
}
|
2014-12-23 11:29:37 +01:00
|
|
|
}
|