mirror of https://github.com/aap/librw.git
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
|
||||
IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture;
|
||||
D3DLOCKED_RECT lr;
|
||||
tex->LockRect(level, &lr, 0, 0);
|
||||
tex->LockRect(level, &lr, 0, D3DLOCK_NOSYSLOCK);
|
||||
return (uint8*)lr.pBits;
|
||||
#else
|
||||
RasterLevels *levels = (RasterLevels*)texture;
|
||||
|
|
|
@ -249,6 +249,8 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
|||
return d3d8::destroyNativeData(object, offset, size);
|
||||
if(geometry->instData->platform == PLATFORM_D3D9)
|
||||
return d3d9::destroyNativeData(object, offset, size);
|
||||
if(geometry->instData->platform == PLATFORM_GL3)
|
||||
return gl3::destroyNativeData(object, offset, size);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,32 @@ namespace gl3 {
|
|||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
static void
|
||||
instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
void
|
||||
freeInstanceData(Geometry *geometry)
|
||||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
// TODO: allow for REINSTANCE
|
||||
if(geo->instData)
|
||||
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);
|
||||
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);
|
||||
MeshHeader *meshh = geo->meshHeader;
|
||||
geo->instData = header;
|
||||
|
@ -74,7 +92,36 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||
header->indexBuffer, GL_STATIC_DRAW);
|
||||
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
|
||||
|
@ -88,9 +135,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||
{
|
||||
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
|
||||
Geometry *geo = atomic->geometry;
|
||||
// TODO: allow for REINSTANCE
|
||||
if(geo->instData == nil)
|
||||
pipe->instance(atomic);
|
||||
pipe->instance(atomic);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_GL3);
|
||||
if(pipe->renderCB)
|
||||
|
@ -109,84 +154,100 @@ ObjPipeline::ObjPipeline(uint32 platform)
|
|||
}
|
||||
|
||||
void
|
||||
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||
defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||
{
|
||||
AttribDesc attribs[12], *a;
|
||||
uint32 stride;
|
||||
AttribDesc *attribs, *a;
|
||||
|
||||
//
|
||||
// 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 isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||
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->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);
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
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));
|
||||
attribs = header->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
|
||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].vertices,
|
||||
header->totalNumVertex, a->stride);
|
||||
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){
|
||||
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
|
@ -195,7 +256,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit){
|
||||
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||
;
|
||||
int n = header->numMeshes;
|
||||
|
@ -212,16 +273,17 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
||||
;
|
||||
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||
geo->texCoords[n],
|
||||
header->totalNumVertex, a->stride);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffers(1, &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);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
|
|
@ -213,18 +213,28 @@ rasterLock(Raster *raster, int32 level, int32 lockMode)
|
|||
|
||||
assert(raster->privateFlags == 0);
|
||||
|
||||
px = (uint8*)rwMalloc(raster->stride*raster->height, 0); // TODO: hint
|
||||
assert(raster->pixels == nil);
|
||||
raster->pixels = px;
|
||||
switch(raster->type & 0xF00){
|
||||
case Raster::NORMAL:
|
||||
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)){
|
||||
uint32 prev = bindTexture(natras->texid);
|
||||
glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px);
|
||||
bindTexture(prev);
|
||||
if(lockMode & Raster::LOCKREAD || !(lockMode & Raster::LOCKNOFETCH)){
|
||||
uint32 prev = bindTexture(natras->texid);
|
||||
glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px);
|
||||
bindTexture(prev);
|
||||
}
|
||||
|
||||
raster->privateFlags = lockMode;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0 && "cannot lock this type of raster yet");
|
||||
return nil;
|
||||
}
|
||||
|
||||
raster->privateFlags = lockMode;
|
||||
|
||||
return px;
|
||||
#else
|
||||
return nil;
|
||||
|
|
|
@ -68,28 +68,6 @@ findBlock(const char *name)
|
|||
|
||||
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
|
||||
compileshader(GLenum type, const char **src, GLuint *shader)
|
||||
{
|
||||
|
@ -156,12 +134,17 @@ Shader::create(const char **vsrc, const char **fsrc)
|
|||
return nil;
|
||||
|
||||
fail = compileshader(GL_FRAGMENT_SHADER, fsrc, &fs);
|
||||
if(fail)
|
||||
if(fail){
|
||||
glDeleteShader(vs);
|
||||
return nil;
|
||||
}
|
||||
|
||||
fail = linkprogram(vs, fs, &program);
|
||||
if(fail)
|
||||
if(fail){
|
||||
glDeleteShader(fs);
|
||||
glDeleteShader(vs);
|
||||
return nil;
|
||||
}
|
||||
glDeleteProgram(vs);
|
||||
glDeleteProgram(fs);
|
||||
|
||||
|
@ -195,61 +178,6 @@ Shader::create(const char **vsrc, const char **fsrc)
|
|||
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
|
||||
Shader::use(void)
|
||||
{
|
||||
|
|
|
@ -67,103 +67,119 @@ enum
|
|||
};
|
||||
|
||||
void
|
||||
skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||
skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance)
|
||||
{
|
||||
AttribDesc attribs[14], *a;
|
||||
uint32 stride;
|
||||
AttribDesc *attribs, *a;
|
||||
|
||||
//
|
||||
// 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 isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||
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->type = GL_FLOAT;
|
||||
a->normalized = GL_FALSE;
|
||||
a->offset = stride;
|
||||
stride += 12;
|
||||
a++;
|
||||
}
|
||||
|
||||
// Prelighting
|
||||
bool isPrelit = !!(geo->flags & Geometry::PRELIT);
|
||||
if(isPrelit){
|
||||
a->index = ATTRIB_COLOR;
|
||||
// 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_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;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
uint8 *verts = rwNewT(uint8, header->totalNumVertex*stride, MEMDUR_EVENT | ID_GEOMETRY);
|
||||
header->vertexBuffer = verts;
|
||||
attribs = header->attribDesc;
|
||||
|
||||
//
|
||||
// Fill vertex buffer
|
||||
//
|
||||
|
||||
uint8 *verts = header->vertexBuffer;
|
||||
|
||||
// Positions
|
||||
for(a = attribs; a->index != ATTRIB_POS; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
geo->morphTargets[0].vertices,
|
||||
header->totalNumVertex, a->stride);
|
||||
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){
|
||||
if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){
|
||||
for(a = attribs; a->index != ATTRIB_NORMAL; a++)
|
||||
;
|
||||
instV3d(VERT_FLOAT3, verts + a->offset,
|
||||
|
@ -172,7 +188,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||
}
|
||||
|
||||
// Prelighting
|
||||
if(isPrelit){
|
||||
if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){
|
||||
for(a = attribs; a->index != ATTRIB_COLOR; a++)
|
||||
;
|
||||
instColor(VERT_RGBA, verts + a->offset,
|
||||
|
@ -182,32 +198,37 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|||
|
||||
// Texture coordinates
|
||||
for(int32 n = 0; n < geo->numTexCoordSets; n++){
|
||||
for(a = attribs; a->index != ATTRIB_TEXCOORDS0+n; a++)
|
||||
;
|
||||
instTexCoords(VERT_FLOAT2, verts + a->offset,
|
||||
geo->texCoords[n],
|
||||
header->totalNumVertex, a->stride);
|
||||
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
|
||||
for(a = attribs; a->index != ATTRIB_WEIGHTS; a++)
|
||||
;
|
||||
float *w = skin->weights;
|
||||
instV4d(VERT_FLOAT4, verts + a->offset,
|
||||
(V4d*)w,
|
||||
header->totalNumVertex, a->stride);
|
||||
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
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
glGenBuffers(1, &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);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
|
|
@ -182,18 +182,20 @@ void flushCache(void);
|
|||
class ObjPipeline : public rw::ObjPipeline
|
||||
{
|
||||
public:
|
||||
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header);
|
||||
void (*instanceCB)(Geometry *geo, InstanceDataHeader *header, bool32 reinstance);
|
||||
void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header);
|
||||
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
|
||||
|
||||
ObjPipeline(uint32 platform);
|
||||
};
|
||||
|
||||
void defaultInstanceCB(Geometry *geo, 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 *destroyNativeData(void *object, int32, int32);
|
||||
|
||||
ObjPipeline *makeDefaultPipeline(void);
|
||||
|
||||
// Native Texture and Raster
|
||||
|
|
Loading…
Reference in New Issue