some work on gl3
This commit is contained in:
parent
eb71ca25d0
commit
4f118dcd97
@ -371,7 +371,7 @@ lockTexture(void *texture, int32 level, int32 lockMode)
|
|||||||
#ifdef RW_D3D9
|
#ifdef RW_D3D9
|
||||||
IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture;
|
IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture;
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
tex->LockRect(level, &lr, 0, 0);
|
tex->LockRect(level, &lr, 0, D3DLOCK_NOSYSLOCK);
|
||||||
return (uint8*)lr.pBits;
|
return (uint8*)lr.pBits;
|
||||||
#else
|
#else
|
||||||
RasterLevels *levels = (RasterLevels*)texture;
|
RasterLevels *levels = (RasterLevels*)texture;
|
||||||
|
@ -249,6 +249,8 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
|||||||
return d3d8::destroyNativeData(object, offset, size);
|
return d3d8::destroyNativeData(object, offset, size);
|
||||||
if(geometry->instData->platform == PLATFORM_D3D9)
|
if(geometry->instData->platform == PLATFORM_D3D9)
|
||||||
return d3d9::destroyNativeData(object, offset, size);
|
return d3d9::destroyNativeData(object, offset, size);
|
||||||
|
if(geometry->instData->platform == PLATFORM_GL3)
|
||||||
|
return gl3::destroyNativeData(object, offset, size);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,32 @@ namespace gl3 {
|
|||||||
|
|
||||||
#ifdef RW_OPENGL
|
#ifdef RW_OPENGL
|
||||||
|
|
||||||
static void
|
void
|
||||||
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
freeInstanceData(Geometry *geometry)
|
||||||
{
|
{
|
||||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
if(geometry->instData == nil ||
|
||||||
Geometry *geo = atomic->geometry;
|
geometry->instData->platform != PLATFORM_GL3)
|
||||||
// TODO: allow for REINSTANCE
|
|
||||||
if(geo->instData)
|
|
||||||
return;
|
return;
|
||||||
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
|
geometry->instData = nil;
|
||||||
|
glDeleteBuffers(1, &header->ibo);
|
||||||
|
glDeleteBuffers(1, &header->vbo);
|
||||||
|
rwFree(header->indexBuffer);
|
||||||
|
rwFree(header->vertexBuffer);
|
||||||
|
rwFree(header->attribDesc);
|
||||||
|
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);
|
InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY);
|
||||||
MeshHeader *meshh = geo->meshHeader;
|
MeshHeader *meshh = geo->meshHeader;
|
||||||
geo->instData = header;
|
geo->instData = header;
|
||||||
@ -74,7 +92,36 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||||||
header->indexBuffer, GL_STATIC_DRAW);
|
header->indexBuffer, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
pipe->instanceCB(geo, header);
|
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
|
static void
|
||||||
@ -88,9 +135,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||||||
{
|
{
|
||||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||||
Geometry *geo = atomic->geometry;
|
Geometry *geo = atomic->geometry;
|
||||||
// TODO: allow for REINSTANCE
|
pipe->instance(atomic);
|
||||||
if(geo->instData == nil)
|
|
||||||
pipe->instance(atomic);
|
|
||||||
assert(geo->instData != nil);
|
assert(geo->instData != nil);
|
||||||
assert(geo->instData->platform == PLATFORM_GL3);
|
assert(geo->instData->platform == PLATFORM_GL3);
|
||||||
if(pipe->renderCB)
|
if(pipe->renderCB)
|
||||||
@ -109,84 +154,100 @@ ObjPipeline::ObjPipeline(uint32 platform)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||||
{
|
{
|
||||||
AttribDesc attribs[12], *a;
|
AttribDesc *attribs, *a;
|
||||||
uint32 stride;
|
|
||||||
|
|
||||||
//
|
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||||
// Create attribute descriptions
|
|
||||||
//
|
|
||||||
a = attribs;
|
|
||||||
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
|
|
||||||
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
||||||
if(hasNormals){
|
|
||||||
a->index = ATTRIB_NORMAL;
|
if(!reinstance){
|
||||||
|
AttribDesc tmpAttribs[12];
|
||||||
|
uint32 stride;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create attribute descriptions
|
||||||
|
//
|
||||||
|
a = tmpAttribs;
|
||||||
|
stride = 0;
|
||||||
|
|
||||||
|
// Positions
|
||||||
|
a->index = ATTRIB_POS;
|
||||||
a->size = 3;
|
a->size = 3;
|
||||||
a->type = GL_FLOAT;
|
a->type = GL_FLOAT;
|
||||||
a->normalized = GL_FALSE;
|
a->normalized = GL_FALSE;
|
||||||
a->offset = stride;
|
a->offset = stride;
|
||||||
stride += 12;
|
stride += 12;
|
||||||
a++;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prelighting
|
attribs = header->attribDesc;
|
||||||
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
|
||||||
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 - attribs;
|
|
||||||
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
|
||||||
a->stride = stride;
|
|
||||||
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
|
||||||
memcpy(header->attribDesc, attribs,
|
|
||||||
header->numAttribs*sizeof(AttribDesc));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate and fill vertex buffer
|
// Fill vertex buffer
|
||||||
//
|
//
|
||||||
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
|
||||||
header->vertexBuffer = verts;
|
uint8 *verts = header->vertexBuffer;
|
||||||
|
|
||||||
// Positions
|
// Positions
|
||||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
|
||||||
;
|
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
;
|
||||||
geo->morphTargets[0].vertices,
|
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
geo->morphTargets[0].vertices,
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
if(hasNormals){
|
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||||
;
|
;
|
||||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||||
@ -195,7 +256,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prelighting
|
// Prelighting
|
||||||
if(isPrelit){
|
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||||
;
|
;
|
||||||
int n = header->numMeshes;
|
int n = header->numMeshes;
|
||||||
@ -212,16 +273,17 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||||||
|
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
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],
|
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
geo->texCoords[n],
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenBuffers(1, &header->vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*stride,
|
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*attribs[0].stride,
|
||||||
header->vertexBuffer, GL_STATIC_DRAW);
|
header->vertexBuffer, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
@ -213,18 +213,28 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
|
|||||||
|
|
||||||
assert(raster->privateFlags == 0);
|
assert(raster->privateFlags == 0);
|
||||||
|
|
||||||
px = (uint8*)rwMalloc(raster->stride*raster->height, 0); // TODO: hint
|
switch(raster->type & 0xF00){
|
||||||
assert(raster->pixels == nil);
|
case Raster::NORMAL:
|
||||||
raster->pixels = px;
|
case Raster::TEXTURE:
|
||||||
|
case Raster::CAMERATEXTURE:
|
||||||
|
px = (uint8*)rwMalloc(raster->stride*raster->height, MEMDUR_EVENT | ID_DRIVER);
|
||||||
|
assert(raster->pixels == nil);
|
||||||
|
raster->pixels = px;
|
||||||
|
|
||||||
if(lockMode & Raster::LOCKREAD || !(lockMode & Raster::LOCKNOFETCH)){
|
if(lockMode & Raster::LOCKREAD || !(lockMode & Raster::LOCKNOFETCH)){
|
||||||
uint32 prev = bindTexture(natras->texid);
|
uint32 prev = bindTexture(natras->texid);
|
||||||
glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px);
|
glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px);
|
||||||
bindTexture(prev);
|
bindTexture(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
raster->privateFlags = lockMode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0 && "cannot lock this type of raster yet");
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
raster->privateFlags = lockMode;
|
|
||||||
|
|
||||||
return px;
|
return px;
|
||||||
#else
|
#else
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -68,28 +68,6 @@ findBlock(const char *name)
|
|||||||
|
|
||||||
Shader *currentShader;
|
Shader *currentShader;
|
||||||
|
|
||||||
// TODO: maybe make this public somewhere?
|
|
||||||
static char*
|
|
||||||
loadfile(const char *path)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
char *buf;
|
|
||||||
long len;
|
|
||||||
|
|
||||||
if(f = fopen(path, "rb"), f == nil){
|
|
||||||
fprintf(stderr, "Couldn't open file %s\n", path);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
len = ftell(f);
|
|
||||||
buf = (char*)rwMalloc(len+1, MEMDUR_EVENT);
|
|
||||||
rewind(f);
|
|
||||||
fread(buf, 1, len, f);
|
|
||||||
buf[len] = '\0';
|
|
||||||
fclose(f);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compileshader(GLenum type, const char **src, GLuint *shader)
|
compileshader(GLenum type, const char **src, GLuint *shader)
|
||||||
{
|
{
|
||||||
@ -156,12 +134,17 @@ Shader::create(const char **vsrc, const char **fsrc)
|
|||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
fail = compileshader(GL_FRAGMENT_SHADER, fsrc, &fs);
|
fail = compileshader(GL_FRAGMENT_SHADER, fsrc, &fs);
|
||||||
if(fail)
|
if(fail){
|
||||||
|
glDeleteShader(vs);
|
||||||
return nil;
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
fail = linkprogram(vs, fs, &program);
|
fail = linkprogram(vs, fs, &program);
|
||||||
if(fail)
|
if(fail){
|
||||||
|
glDeleteShader(fs);
|
||||||
|
glDeleteShader(vs);
|
||||||
return nil;
|
return nil;
|
||||||
|
}
|
||||||
glDeleteProgram(vs);
|
glDeleteProgram(vs);
|
||||||
glDeleteProgram(fs);
|
glDeleteProgram(fs);
|
||||||
|
|
||||||
@ -195,61 +178,6 @@ Shader::create(const char **vsrc, const char **fsrc)
|
|||||||
return sh;
|
return sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
Shader*
|
|
||||||
Shader::fromStrings(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)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
fail = linkprogram(vs, fs, &program);
|
|
||||||
if(fail)
|
|
||||||
return nil;
|
|
||||||
glDeleteProgram(vs);
|
|
||||||
glDeleteProgram(fs);
|
|
||||||
|
|
||||||
Shader *sh = rwNewT(Shader, 1, MEMDUR_EVENT | ID_DRIVER); // or global?
|
|
||||||
|
|
||||||
// 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->uniformLocations = rwNewT(GLint, uniformRegistry.numUniforms, MEMDUR_EVENT | ID_DRIVER);
|
|
||||||
for(i = 0; i < uniformRegistry.numUniforms; i++)
|
|
||||||
sh->uniformLocations[i] = glGetUniformLocation(program,
|
|
||||||
uniformRegistry.uniformNames[i]);
|
|
||||||
|
|
||||||
return sh;
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader*
|
|
||||||
Shader::fromFiles(const char *vspath, const char *fspath)
|
|
||||||
{
|
|
||||||
char *vsrc, *fsrc;
|
|
||||||
vsrc = loadfile(vspath);
|
|
||||||
fsrc = loadfile(fspath);
|
|
||||||
Shader *s = fromStrings(vsrc, fsrc);
|
|
||||||
rwFree(vsrc);
|
|
||||||
rwFree(fsrc);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Shader::use(void)
|
Shader::use(void)
|
||||||
{
|
{
|
||||||
|
@ -67,103 +67,119 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||||
{
|
{
|
||||||
AttribDesc attribs[14], *a;
|
AttribDesc *attribs, *a;
|
||||||
uint32 stride;
|
|
||||||
|
|
||||||
//
|
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||||
// Create attribute descriptions
|
|
||||||
//
|
|
||||||
a = attribs;
|
|
||||||
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
|
|
||||||
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
bool hasNormals = !!(geo->flags & Geometry::NORMALS);
|
||||||
if(hasNormals){
|
|
||||||
a->index = ATTRIB_NORMAL;
|
if(!reinstance){
|
||||||
|
AttribDesc tmpAttribs[14];
|
||||||
|
uint32 stride;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create attribute descriptions
|
||||||
|
//
|
||||||
|
a = tmpAttribs;
|
||||||
|
stride = 0;
|
||||||
|
|
||||||
|
// Positions
|
||||||
|
a->index = ATTRIB_POS;
|
||||||
a->size = 3;
|
a->size = 3;
|
||||||
a->type = GL_FLOAT;
|
a->type = GL_FLOAT;
|
||||||
a->normalized = GL_FALSE;
|
a->normalized = GL_FALSE;
|
||||||
a->offset = stride;
|
a->offset = stride;
|
||||||
stride += 12;
|
stride += 12;
|
||||||
a++;
|
a++;
|
||||||
}
|
|
||||||
|
|
||||||
// Prelighting
|
// Normals
|
||||||
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
// TODO: compress
|
||||||
if(isPrelit){
|
if(hasNormals){
|
||||||
a->index = ATTRIB_COLOR;
|
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->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->type = GL_FLOAT;
|
||||||
a->normalized = GL_FALSE;
|
a->normalized = GL_FALSE;
|
||||||
a->offset = stride;
|
a->offset = stride;
|
||||||
stride += 8;
|
stride += 16;
|
||||||
a++;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 - attribs;
|
|
||||||
for(a = attribs; a != &attribs[header->numAttribs]; a++)
|
|
||||||
a->stride = stride;
|
|
||||||
header->attribDesc = rwNewT(AttribDesc, header->numAttribs, MEMDUR_EVENT | ID_GEOMETRY);
|
|
||||||
memcpy(header->attribDesc, attribs,
|
|
||||||
header->numAttribs*sizeof(AttribDesc));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate and fill vertex buffer
|
|
||||||
//
|
|
||||||
Skin *skin = Skin::get(geo);
|
Skin *skin = Skin::get(geo);
|
||||||
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
attribs = header->attribDesc;
|
||||||
header->vertexBuffer = verts;
|
|
||||||
|
//
|
||||||
|
// Fill vertex buffer
|
||||||
|
//
|
||||||
|
|
||||||
|
uint8 *verts = header->vertexBuffer;
|
||||||
|
|
||||||
// Positions
|
// Positions
|
||||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){
|
||||||
;
|
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
;
|
||||||
geo->morphTargets[0].vertices,
|
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
geo->morphTargets[0].vertices,
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
if(hasNormals){
|
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||||
;
|
;
|
||||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||||
@ -172,7 +188,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prelighting
|
// Prelighting
|
||||||
if(isPrelit){
|
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||||
;
|
;
|
||||||
instColor(VERT_RGBA, verts + a->offset,
|
instColor(VERT_RGBA, verts + a->offset,
|
||||||
@ -182,32 +198,37 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||||||
|
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
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],
|
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
geo->texCoords[n],
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weights
|
// Weights
|
||||||
for(a = attribs; a->index != ATTRIB_WEIGHTS; a++)
|
if(!reinstance){
|
||||||
;
|
for(a = attribs; a->index != ATTRIB_WEIGHTS; a++)
|
||||||
float *w = skin->weights;
|
;
|
||||||
instV4d(VERT_FLOAT4, verts + a->offset,
|
float *w = skin->weights;
|
||||||
(V4d*)w,
|
instV4d(VERT_FLOAT4, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
(V4d*)w,
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
|
|
||||||
// Indices
|
// Indices
|
||||||
for(a = attribs; a->index != ATTRIB_INDICES; a++)
|
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,
|
// not really colors of course but what the heck
|
||||||
(RGBA*)skin->indices,
|
instColor(VERT_RGBA, verts + a->offset,
|
||||||
header->totalNumVertex, a->stride);
|
(RGBA*)skin->indices,
|
||||||
|
header->totalNumVertex, a->stride);
|
||||||
|
}
|
||||||
|
|
||||||
glGenBuffers(1, &header->vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*stride,
|
glBufferData(GL_ARRAY_BUFFER, header->totalNumVertex*attribs[0].stride,
|
||||||
header->vertexBuffer, GL_STATIC_DRAW);
|
header->vertexBuffer, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
@ -182,18 +182,20 @@ void flushCache(void);
|
|||||||
class ObjPipeline : public rw::ObjPipeline
|
class ObjPipeline : public rw::ObjPipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header);
|
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||||
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
|
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
|
||||||
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
|
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
|
||||||
|
|
||||||
ObjPipeline(uint32 platform);
|
ObjPipeline(uint32 platform);
|
||||||
};
|
};
|
||||||
|
|
||||||
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
|
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||||
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
int32 lightingCB(Atomic *atomic);
|
int32 lightingCB(Atomic *atomic);
|
||||||
|
|
||||||
|
void *destroyNativeData(void *object, int32, int32);
|
||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
Loading…
x
Reference in New Issue
Block a user