FIrst working version of the GLBatching system introduced in the MOdelrendering path

This commit is contained in:
Sam Gateau 2014-10-21 10:50:53 -07:00
parent 0def490db7
commit 00dbe486d9
3 changed files with 659 additions and 414 deletions

View file

@ -12,14 +12,21 @@
#include <QDebug> #include <QDebug>
#define DO_IT_NOW(call, offset) int param = _params.size() - (offset); do##call(param); #define ADD_COMMAND(call) _commands.push_back(COMMAND_##call); _commandCalls.push_back(&gpu::Batch::do_##call); _commandOffsets.push_back(_params.size());
//#define DO_IT_NOW(call, offset) uint32 __param = _params.size() - (offset); do##call(__param);
//#define DO_IT_NOW(call, offset) uint32 __param = _commandOffsets.back(); CommandCall call = _commandCalls.back(); (this->*(call))(__param);
//#define DO_IT_NOW(call, offset) runLastCommand();
//#define DO_IT_NOW(call, offset) uint32 __param = _params.size() - (offset); runCommand(_commands.size() -1);// do##call(__param);
#define DO_IT_NOW(call, offset)
using namespace gpu; using namespace gpu;
Batch::Batch() : Batch::Batch() :
_commands(), _commands(),
_params(), _params(),
_resources(){ _resources(),
_data(){
} }
Batch::~Batch() { Batch::~Batch() {
@ -29,24 +36,99 @@ void Batch::clear() {
_commands.clear(); _commands.clear();
_params.clear(); _params.clear();
_resources.clear(); _resources.clear();
_data.clear();
}
uint32 Batch::cacheResource(Resource* res) {
uint32 offset = _resources.size();
_resources.push_back(ResourceCache(res));
return offset;
}
uint32 Batch::cacheResource(const void* pointer) {
uint32 offset = _resources.size();
_resources.push_back(ResourceCache(pointer));
return offset;
}
uint32 Batch::cacheData(uint32 size, const void* data) {
uint32 offset = _data.size();
uint32 nbBytes = size;
_data.resize(offset + nbBytes);
memcpy(_data.data() + offset, data, size);
return offset;
}
#define CASE_COMMAND(call) case COMMAND_##call: { do_##call(offset); } break;
void Batch::runCommand(Command com, uint32 offset) {
switch (com) {
CASE_COMMAND(draw);
CASE_COMMAND(drawIndexed);
CASE_COMMAND(drawInstanced);
CASE_COMMAND(drawIndexedInstanced);
CASE_COMMAND(glEnable);
CASE_COMMAND(glDisable);
CASE_COMMAND(glEnableClientState);
CASE_COMMAND(glDisableClientState);
CASE_COMMAND(glCullFace);
CASE_COMMAND(glAlphaFunc);
CASE_COMMAND(glDepthFunc);
CASE_COMMAND(glDepthMask);
CASE_COMMAND(glDepthRange);
CASE_COMMAND(glBindBuffer);
CASE_COMMAND(glBindTexture);
CASE_COMMAND(glActiveTexture);
CASE_COMMAND(glDrawBuffers);
CASE_COMMAND(glUseProgram);
CASE_COMMAND(glUniform1f);
CASE_COMMAND(glUniformMatrix4fv);
CASE_COMMAND(glMatrixMode);
CASE_COMMAND(glPushMatrix);
CASE_COMMAND(glPopMatrix);
CASE_COMMAND(glMultMatrixf);
CASE_COMMAND(glLoadMatrixf);
CASE_COMMAND(glLoadIdentity);
CASE_COMMAND(glRotatef);
CASE_COMMAND(glScalef);
CASE_COMMAND(glTranslatef);
CASE_COMMAND(glDrawArrays);
CASE_COMMAND(glDrawRangeElements);
CASE_COMMAND(glColorPointer);
CASE_COMMAND(glNormalPointer);
CASE_COMMAND(glTexCoordPointer);
CASE_COMMAND(glVertexPointer);
CASE_COMMAND(glVertexAttribPointer);
CASE_COMMAND(glEnableVertexAttribArray);
CASE_COMMAND(glDisableVertexAttribArray);
CASE_COMMAND(glColor4f);
CASE_COMMAND(glMaterialf);
CASE_COMMAND(glMaterialfv);
}
} }
void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) {
_commands.push_back(COMMAND_DRAW); ADD_COMMAND(draw);
_params.push_back(startVertex); _params.push_back(startVertex);
_params.push_back(nbVertices); _params.push_back(nbVertices);
_params.push_back(primitiveType); _params.push_back(primitiveType);
} }
void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) { void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) {
_commands.push_back(COMMAND_DRAW_INDEXED); ADD_COMMAND(drawIndexed);
_params.push_back(startIndex); _params.push_back(startIndex);
_params.push_back(nbIndices); _params.push_back(nbIndices);
_params.push_back(primitiveType); _params.push_back(primitiveType);
} }
void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex, int startInstance) { void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex, int startInstance) {
_commands.push_back(COMMAND_DRAW_INSTANCED); ADD_COMMAND(drawInstanced);
_params.push_back(startInstance); _params.push_back(startInstance);
_params.push_back(startVertex); _params.push_back(startVertex);
_params.push_back(nbVertices); _params.push_back(nbVertices);
@ -55,7 +137,8 @@ void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVe
} }
void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex, int startInstance) { void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex, int startInstance) {
_commands.push_back(COMMAND_DRAW_INDEXED_INSTANCED); ADD_COMMAND(drawIndexedInstanced);
_params.push_back(startInstance); _params.push_back(startInstance);
_params.push_back(startIndex); _params.push_back(startIndex);
_params.push_back(nbIndices); _params.push_back(nbIndices);
@ -67,402 +150,474 @@ void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, i
// code, we need to be able to record and batch these calls. THe long // code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API // term strategy is to get rid of any GL calls in favor of the HIFI GPU API
void Batch::_glEnable(GLenum cap) { void Batch::_glEnable(GLenum cap) {
_commands.push_back(COMMAND_glEnable); ADD_COMMAND(glEnable);
_params.push_back(cap);
DO_IT_NOW(_glEnable, 1);
}
void Batch::do_glEnable(int &paramOffset) {
glEnable(_params[paramOffset++]._uint);
}
void Batch::_glDisable(GLenum cap) {
_commands.push_back(COMMAND_glDisable);
_params.push_back(cap);
DO_IT_NOW(_glDisable, 1);
}
void Batch::do_glDisable(int &paramOffset) {
glDisable(_params[paramOffset++]._uint);
}
void Batch::_glEnableClientState(GLenum array) {
_commands.push_back(COMMAND_glEnableClientState);
_params.push_back(array);
DO_IT_NOW(_glEnableClientState, 1 );
}
void Batch::do_glEnableClientState(int &paramOffset) {
glEnableClientState(_params[paramOffset++]._uint);
}
void Batch::_glDisableClientState(GLenum array) { _params.push_back(cap);
_commands.push_back(COMMAND_glDisableClientState);
_params.push_back(array); DO_IT_NOW(_glEnable, 1);
DO_IT_NOW(_glDisableClientState, 1);
} }
void Batch::do_glDisableClientState(int &paramOffset) { void Batch::do_glEnable(uint32& paramOffset) {
glEnable(_params[paramOffset++]._uint);
}
void Batch::_glDisable(GLenum cap) {
ADD_COMMAND(glDisable);
_params.push_back(cap);
DO_IT_NOW(_glDisable, 1);
}
void Batch::do_glDisable(uint32& paramOffset) {
glDisable(_params[paramOffset++]._uint);
}
void Batch::_glEnableClientState(GLenum array) {
ADD_COMMAND(glEnableClientState);
_params.push_back(array);
DO_IT_NOW(_glEnableClientState, 1 );
}
void Batch::do_glEnableClientState(uint32& paramOffset) {
glEnableClientState(_params[paramOffset++]._uint);
}
void Batch::_glDisableClientState(GLenum array) {
ADD_COMMAND(glDisableClientState);
_params.push_back(array);
DO_IT_NOW(_glDisableClientState, 1);
}
void Batch::do_glDisableClientState(uint32& paramOffset) {
glDisableClientState(_params[paramOffset++]._uint); glDisableClientState(_params[paramOffset++]._uint);
} }
void Batch::_glCullFace(GLenum mode) { void Batch::_glCullFace(GLenum mode) {
_commands.push_back(COMMAND_glCullFace); ADD_COMMAND(glCullFace);
_params.push_back(mode);
_params.push_back(mode);
DO_IT_NOW(_glCullFace, 1);
DO_IT_NOW(_glCullFace, 1);
} }
void Batch::do_glCullFace(int &paramOffset) { void Batch::do_glCullFace(uint32& paramOffset) {
glCullFace(_params[paramOffset++]._uint); glCullFace(_params[paramOffset++]._uint);
} }
void Batch::_glAlphaFunc(GLenum func, GLclampf ref) { void Batch::_glAlphaFunc(GLenum func, GLclampf ref) {
_commands.push_back(COMMAND_glAlphaFunc); ADD_COMMAND(glAlphaFunc);
_params.push_back(ref);
_params.push_back(func);
DO_IT_NOW(_glAlphaFunc, 1);
}
void Batch::do_glAlphaFunc(int &paramOffset) {
glAlphaFunc(_params[paramOffset++]._uint, _params[paramOffset++]._float);
}
void Batch::_glDepthFunc(GLenum func) { _params.push_back(ref);
_commands.push_back(COMMAND_glDepthFunc); _params.push_back(func);
_params.push_back(func);
DO_IT_NOW(_glAlphaFunc, 2);
DO_IT_NOW(_glDepthFunc, 1); }
} void Batch::do_glAlphaFunc(uint32& paramOffset) {
void Batch::do_glDepthFunc(int &paramOffset) { glAlphaFunc(_params[paramOffset++]._uint, _params[paramOffset++]._float);
}
void Batch::_glDepthFunc(GLenum func) {
ADD_COMMAND(glDepthFunc);
_params.push_back(func);
DO_IT_NOW(_glDepthFunc, 1);
}
void Batch::do_glDepthFunc(uint32& paramOffset) {
glDepthFunc(_params[paramOffset++]._uint); glDepthFunc(_params[paramOffset++]._uint);
} }
void Batch::_glDepthMask(GLboolean flag) { void Batch::_glDepthMask(GLboolean flag) {
_commands.push_back(COMMAND_glDepthMask); ADD_COMMAND(glDepthMask);
_params.push_back(flag);
_params.push_back(flag);
DO_IT_NOW(_glDepthMask, 1);
} DO_IT_NOW(_glDepthMask, 1);
void Batch::do_glDepthMask(int &paramOffset) { }
void Batch::do_glDepthMask(uint32& paramOffset) {
glDepthMask(_params[paramOffset++]._uint); glDepthMask(_params[paramOffset++]._uint);
} }
void Batch::_glDepthRange(GLclampd zNear, GLclampd zFar) { void Batch::_glDepthRange(GLclampd zNear, GLclampd zFar) {
_commands.push_back(COMMAND_glDepthRange); ADD_COMMAND(glDepthRange);
_params.push_back(zFar);
_params.push_back(zNear); _params.push_back(zFar);
_params.push_back(zNear);
DO_IT_NOW(_glDepthRange, 2);
} DO_IT_NOW(_glDepthRange, 2);
void Batch::do_glDepthRange(int &paramOffset) { }
void Batch::do_glDepthRange(uint32& paramOffset) {
glDepthRange(_params[paramOffset++]._double, _params[paramOffset++]._double); glDepthRange(_params[paramOffset++]._double, _params[paramOffset++]._double);
} }
void Batch::_glBindBuffer(GLenum target, GLuint buffer) { void Batch::_glBindBuffer(GLenum target, GLuint buffer) {
_commands.push_back(COMMAND_glBindBuffer); ADD_COMMAND(glBindBuffer);
_params.push_back(buffer);
_params.push_back(target); _params.push_back(buffer);
_params.push_back(target);
DO_IT_NOW(_glBindBuffer, 2);
} DO_IT_NOW(_glBindBuffer, 2);
void Batch::do_glBindBuffer(int &paramOffset) { }
void Batch::do_glBindBuffer(uint32& paramOffset) {
glBindBuffer(_params[paramOffset++]._uint, _params[paramOffset++]._uint); glBindBuffer(_params[paramOffset++]._uint, _params[paramOffset++]._uint);
} }
void Batch::_glBindTexture(GLenum target, GLuint texture) { void Batch::_glBindTexture(GLenum target, GLuint texture) {
_commands.push_back(COMMAND_glBindTexture); ADD_COMMAND(glBindTexture);
_params.push_back(texture);
_params.push_back(target); _params.push_back(texture);
_params.push_back(target);
DO_IT_NOW(_glBindTexture, 2);
} DO_IT_NOW(_glBindTexture, 2);
void Batch::do_glBindTexture(int &paramOffset) { }
void Batch::do_glBindTexture(uint32& paramOffset) {
glBindTexture(_params[paramOffset++]._uint, _params[paramOffset++]._uint); glBindTexture(_params[paramOffset++]._uint, _params[paramOffset++]._uint);
} }
void Batch::_glActiveTexture(GLenum texture) { void Batch::_glActiveTexture(GLenum texture) {
_commands.push_back(COMMAND_glActiveTexture); ADD_COMMAND(glActiveTexture);
_params.push_back(texture);
_params.push_back(texture);
DO_IT_NOW(_glActiveTexture, 1);
} DO_IT_NOW(_glActiveTexture, 1);
void Batch::do_glActiveTexture(int &paramOffset) { }
void Batch::do_glActiveTexture(uint32& paramOffset) {
glActiveTexture(_params[paramOffset++]._uint); glActiveTexture(_params[paramOffset++]._uint);
} }
void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) { void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) {
_commands.push_back(COMMAND_glDrawBuffers); ADD_COMMAND(glDrawBuffers);
_params.push_back(bufs);
_params.push_back(n); _params.push_back(cacheData(n * sizeof(GLenum), bufs));
_params.push_back(n);
DO_IT_NOW(_glDrawBuffers, 2);
} DO_IT_NOW(_glDrawBuffers, 2);
void Batch::do_glDrawBuffers(int &paramOffset) { }
glDrawBuffers(_params[paramOffset++]._uint, (const GLenum*) _params[paramOffset++]._constPointer); void Batch::do_glDrawBuffers(uint32& paramOffset) {
glDrawBuffers(_params[paramOffset++]._uint, (const GLenum*) editData(_params[paramOffset++]._uint));
} }
void Batch::_glUseProgram(GLuint program) { void Batch::_glUseProgram(GLuint program) {
_commands.push_back(COMMAND_glUseProgram); ADD_COMMAND(glUseProgram);
_params.push_back(program);
_params.push_back(program);
DO_IT_NOW(_glUseProgram, 1);
} DO_IT_NOW(_glUseProgram, 1);
void Batch::do_glUseProgram(int &paramOffset) { }
void Batch::do_glUseProgram(uint32& paramOffset) {
glUseProgram(_params[paramOffset++]._uint); glUseProgram(_params[paramOffset++]._uint);
} }
void Batch::_glUniform1f(GLint location, GLfloat v0) { void Batch::_glUniform1f(GLint location, GLfloat v0) {
_commands.push_back(COMMAND_glUniform1f); ADD_COMMAND(glUniform1f);
_params.push_back(v0);
_params.push_back(location); _params.push_back(v0);
_params.push_back(location);
DO_IT_NOW(_glUniform1f, 1);
} DO_IT_NOW(_glUniform1f, 1);
void Batch::do_glUniform1f(int &paramOffset) { }
glUniform1f(_params[paramOffset++]._float); void Batch::do_glUniform1f(uint32& paramOffset) {
glUniform1f(_params[paramOffset++]._int, _params[paramOffset++]._float);
} }
void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
_commands.push_back(COMMAND_glUniformMatrix4fv); ADD_COMMAND(glUniformMatrix4fv);
_params.push_back(value);
_params.push_back(transpose); const int MATRIX4_SIZE = 16 * sizeof(float);
_params.push_back(count); _params.push_back(cacheData(count * MATRIX4_SIZE, value));
_params.push_back(location); _params.push_back(transpose);
_params.push_back(count);
DO_IT_NOW(_glUniformMatrix4fv, 4); _params.push_back(location);
}
void Batch::do_glUniformMatrix4fv(int &paramOffset) { DO_IT_NOW(_glUniformMatrix4fv, 4);
glUniformMatrix4fv(_params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._constPointer); }
void Batch::do_glUniformMatrix4fv(uint32& paramOffset) {
glUniformMatrix4fv(_params[paramOffset++]._int, _params[paramOffset++]._uint,
_params[paramOffset++]._uint, (const GLfloat*) editData(_params[paramOffset++]._uint));
} }
void Batch::_glMatrixMode(GLenum mode) { void Batch::_glMatrixMode(GLenum mode) {
_commands.push_back(COMMAND_glMatrixMode); ADD_COMMAND(glMatrixMode);
_params.push_back(mode);
_params.push_back(mode);
DO_IT_NOW(_glMatrixMode, 1);
} DO_IT_NOW(_glMatrixMode, 1);
void Batch::do_glMatrixMode(int &paramOffset) { }
void Batch::do_glMatrixMode(uint32& paramOffset) {
glMatrixMode(_params[paramOffset++]._uint); glMatrixMode(_params[paramOffset++]._uint);
} }
void Batch::_glPushMatrix() { void Batch::_glPushMatrix() {
_commands.push_back(COMMAND_glPushMatrix); ADD_COMMAND(glPushMatrix);
DO_IT_NOW(_glPushMatrix, 0); DO_IT_NOW(_glPushMatrix, 0);
} }
void Batch::do_glPushMatrix(int &paramOffset) { void Batch::do_glPushMatrix(uint32& paramOffset) {
glPushMatrix(); glPushMatrix();
} }
void Batch::_glPopMatrix() { void Batch::_glPopMatrix() {
_commands.push_back(COMMAND_glPopMatrix); ADD_COMMAND(glPopMatrix);
DO_IT_NOW(_glPopMatrix, 0); DO_IT_NOW(_glPopMatrix, 0);
} }
void Batch::do_glPopMatrix(int &paramOffset) { void Batch::do_glPopMatrix(uint32& paramOffset) {
glPopMatrix(); glPopMatrix();
} }
void Batch::_glMultMatrixf(const GLfloat *m) { void Batch::_glMultMatrixf(const GLfloat *m) {
_commands.push_back(COMMAND_glMultMatrixf); ADD_COMMAND(glMultMatrixf);
_params.push_back(m);
const int MATRIX4_SIZE = 16 * sizeof(float);
_params.push_back(cacheData(MATRIX4_SIZE, m));
DO_IT_NOW(_glMultMatrixf, 1); DO_IT_NOW(_glMultMatrixf, 1);
} }
void Batch::do_glMultMatrixf(int &paramOffset) { void Batch::do_glMultMatrixf(uint32& paramOffset) {
glMultMatrixf((const GLfloat*) _params[paramOffset++]._constPointer); glMultMatrixf((const GLfloat*) editData(_params[paramOffset++]._uint));
} }
void Batch::_glLoadMatrixf(const GLfloat *m) { void Batch::_glLoadMatrixf(const GLfloat *m) {
_commands.push_back(COMMAND_glLoadMatrixf); ADD_COMMAND(glLoadMatrixf);
_params.push_back(m);
DO_IT_NOW(_glLoadMatrixf, 1); const int MATRIX4_SIZE = 16 * sizeof(float);
} _params.push_back(cacheData(MATRIX4_SIZE, m));
void Batch::do_glLoadMatrixf(int &paramOffset) {
glLoadMatrixf((const GLfloat*)_params[paramOffset++]._constPointer); DO_IT_NOW(_glLoadMatrixf, 1);
} }
void Batch::do_glLoadMatrixf(uint32& paramOffset) {
void Batch::_glLoadIdentity(void) { glLoadMatrixf((const GLfloat*)editData(_params[paramOffset++]._uint));
_commands.push_back(COMMAND_glLoadIdentity); }
DO_IT_NOW(_glLoadIdentity, 0); void Batch::_glLoadIdentity(void) {
} ADD_COMMAND(glLoadIdentity);
void Batch::do_glLoadIdentity(int &paramOffset) {
DO_IT_NOW(_glLoadIdentity, 0);
}
void Batch::do_glLoadIdentity(uint32& paramOffset) {
glLoadIdentity(); glLoadIdentity();
} }
void Batch::_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { void Batch::_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
_commands.push_back(COMMAND_glRotatef); ADD_COMMAND(glRotatef);
_params.push_back(z);
_params.push_back(y); _params.push_back(z);
_params.push_back(x); _params.push_back(y);
_params.push_back(angle); _params.push_back(x);
_params.push_back(angle);
DO_IT_NOW(_glRotatef, 4);
} DO_IT_NOW(_glRotatef, 4);
void Batch::do_glRotatef(int &paramOffset) { }
void Batch::do_glRotatef(uint32& paramOffset) {
glRotatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); glRotatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float);
} }
void Batch::_glScalef(GLfloat x, GLfloat y, GLfloat z) { void Batch::_glScalef(GLfloat x, GLfloat y, GLfloat z) {
_commands.push_back(COMMAND_glScalef); ADD_COMMAND(glScalef);
_params.push_back(z);
_params.push_back(y); _params.push_back(z);
_params.push_back(x); _params.push_back(y);
_params.push_back(x);
DO_IT_NOW(_glScalef, 3);
} DO_IT_NOW(_glScalef, 3);
void Batch::do_glScalef(int &paramOffset) { }
void Batch::do_glScalef(uint32& paramOffset) {
glScalef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); glScalef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float);
} }
void Batch::_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { void Batch::_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
_commands.push_back(COMMAND_glTranslatef); ADD_COMMAND(glTranslatef);
_params.push_back(z);
_params.push_back(y); _params.push_back(z);
_params.push_back(x); _params.push_back(y);
_params.push_back(x);
DO_IT_NOW(_glTranslatef, 3);
} DO_IT_NOW(_glTranslatef, 3);
void Batch::do_glTranslatef(int &paramOffset) { }
void Batch::do_glTranslatef(uint32& paramOffset) {
glTranslatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); glTranslatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float);
} }
void Batch::_glDrawArrays(GLenum mode, GLint first, GLsizei count) { void Batch::_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
_commands.push_back(COMMAND_glDrawArrays); ADD_COMMAND(glDrawArrays);
_params.push_back(count);
_params.push_back(first); _params.push_back(count);
_params.push_back(mode); _params.push_back(first);
_params.push_back(mode);
DO_IT_NOW(_glDrawArrays, 3);
} DO_IT_NOW(_glDrawArrays, 3);
void Batch::do_glDrawArrays(int &paramOffset) { }
void Batch::do_glDrawArrays(uint32& paramOffset) {
glDrawArrays(_params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._int); glDrawArrays(_params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._int);
} }
void Batch::_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) { void Batch::_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {
_commands.push_back(COMMAND_glDrawRangeElements); ADD_COMMAND(glDrawRangeElements);
_params.push_back(indices);
_params.push_back(type); _params.push_back(cacheResource(indices));
_params.push_back(count); _params.push_back(type);
_params.push_back(end); _params.push_back(count);
_params.push_back(start); _params.push_back(end);
_params.push_back(mode); _params.push_back(start);
_params.push_back(mode);
DO_IT_NOW(_glDrawRangeElements, 6);
} //do_glDrawRangeElements(_commandOffsets.back());
void Batch::do_glDrawRangeElements(int &paramOffset) { // runCommand(_commands.size() - 1);
glDrawRangeElements(_params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._constPointer); DO_IT_NOW(_glDrawRangeElements, 6);
} }
void Batch::do_glDrawRangeElements(uint32& paramOffset) {
void Batch::_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { glDrawRangeElements(_params[paramOffset++]._uint, _params[paramOffset++]._uint,
_commands.push_back(COMMAND_glColorPointer); _params[paramOffset++]._uint, _params[paramOffset++]._int,
_params.push_back(pointer); _params[paramOffset++]._uint, editResource(_params[paramOffset++]._uint)->_pointer);
_params.push_back(stride); }
_params.push_back(type);
_params.push_back(size); void Batch::_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
ADD_COMMAND(glColorPointer);
DO_IT_NOW(_glColorPointer, 4);
} _params.push_back(cacheResource(pointer));
void Batch::do_glColorPointer(int &paramOffset) { _params.push_back(stride);
glColorPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._constPointer); _params.push_back(type);
} _params.push_back(size);
void Batch::_glNormalPointer(GLenum type, GLsizei stride, const void *pointer) { DO_IT_NOW(_glColorPointer, 4);
_commands.push_back(COMMAND_glNormalPointer); }
_params.push_back(pointer); void Batch::do_glColorPointer(uint32& paramOffset) {
_params.push_back(stride); glColorPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint,
_params.push_back(type); _params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer);
}
DO_IT_NOW(_glNormalPointer, 4);
} void Batch::_glNormalPointer(GLenum type, GLsizei stride, const void *pointer) {
void Batch::do_glNormalPointer(int &paramOffset) { ADD_COMMAND(glNormalPointer);
glNormalPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._constPointer);
} _params.push_back(cacheResource(pointer));
_params.push_back(stride);
void Batch::_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { _params.push_back(type);
_commands.push_back(COMMAND_glTexCoordPointer);
_params.push_back(pointer); DO_IT_NOW(_glNormalPointer, 3);
_params.push_back(stride); }
_params.push_back(type); void Batch::do_glNormalPointer(uint32& paramOffset) {
_params.push_back(size); glNormalPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int,
} editResource(_params[paramOffset++]._uint)->_pointer);
void Batch::do_glCullFace(int &paramOffset) { }
glCullFace(_params[paramOffset++]._uint);
} void Batch::_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
ADD_COMMAND(glTexCoordPointer);
void Batch::_glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
_commands.push_back(COMMAND_glVertexPointer); _params.push_back(cacheResource(pointer));
_params.push_back(pointer); _params.push_back(stride);
_params.push_back(stride); _params.push_back(type);
_params.push_back(type); _params.push_back(size);
_params.push_back(size);
} DO_IT_NOW(_glTexCoordPointer, 4);
void Batch::do_glCullFace(int &paramOffset) { }
glCullFace(_params[paramOffset++]._uint); void Batch::do_glTexCoordPointer(uint32& paramOffset) {
glTexCoordPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint,
_params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer);
}
void Batch::_glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
ADD_COMMAND(glVertexPointer);
_params.push_back(cacheResource(pointer));
_params.push_back(stride);
_params.push_back(type);
_params.push_back(size);
DO_IT_NOW(_glVertexPointer, 4);
}
void Batch::do_glVertexPointer(uint32& paramOffset) {
glVertexPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint,
_params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer);
} }
void Batch::_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) { void Batch::_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) {
_commands.push_back(COMMAND_glVertexPointer); ADD_COMMAND(glVertexAttribPointer);
_params.push_back(pointer);
_params.push_back(stride);
_params.push_back(normalized);
_params.push_back(type);
_params.push_back(size);
_params.push_back(index);
}
void Batch::do_glCullFace(int &paramOffset) {
glCullFace(_params[paramOffset++]._uint);
}
void Batch::_glEnableVertexArrayAttrib(GLint location) { _params.push_back(cacheResource(pointer));
_commands.push_back(COMMAND_glEnableVertexArrayAttrib); _params.push_back(stride);
_params.push_back(location); _params.push_back(normalized);
} _params.push_back(type);
void Batch::do_glCullFace(int &paramOffset) { _params.push_back(size);
glCullFace(_params[paramOffset++]._uint); _params.push_back(index);
}
void Batch::_glDisableVertexArrayAttrib(GLint location) { DO_IT_NOW(_glVertexAttribPointer, 6);
_commands.push_back(COMMAND_glDisableVertexArrayAttrib);
_params.push_back(location);
}
void Batch::do_glCullFace(int &paramOffset) {
glCullFace(_params[paramOffset++]._uint);
} }
void Batch::do_glVertexAttribPointer(uint32& paramOffset) {
void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { glVertexAttribPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int,
_commands.push_back(COMMAND_glColor4f); _params[paramOffset++]._uint, _params[paramOffset++]._uint,
_params.push_back(alpha); _params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer);
_params.push_back(blue);
_params.push_back(green);
_params.push_back(red);
}
void Batch::do_glCullFace(int &paramOffset) {
glCullFace(_params[paramOffset++]._uint);
}
void Batch::_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
_commands.push_back(COMMAND_glMaterialf);
_params.push_back(param);
_params.push_back(pname);
_params.push_back(face);
}
void Batch::do_glCullFace(int &paramOffset) {
glCullFace(_params[paramOffset++]._uint);
}
void Batch::_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
_commands.push_back(COMMAND_glMaterialfv);
_params.push_back(params);
_params.push_back(pname);
_params.push_back(face);
}
void Batch::do_glCullFace(int &paramOffset) {
glCullFace(_params[paramOffset++]._uint);
} }
void Batch::_glEnableVertexAttribArray(GLint location) {
ADD_COMMAND(glEnableVertexAttribArray);
_params.push_back(location);
DO_IT_NOW(_glEnableVertexAttribArray, 1);
}
void Batch::do_glEnableVertexAttribArray(uint32& paramOffset) {
glEnableVertexAttribArray(_params[paramOffset++]._uint);
}
void Batch::_glDisableVertexAttribArray(GLint location) {
ADD_COMMAND(glDisableVertexAttribArray);
_params.push_back(location);
DO_IT_NOW(_glDisableVertexAttribArray, 1);
}
void Batch::do_glDisableVertexAttribArray(uint32& paramOffset) {
glDisableVertexAttribArray(_params[paramOffset++]._uint);
}
void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
ADD_COMMAND(glColor4f);
_params.push_back(alpha);
_params.push_back(blue);
_params.push_back(green);
_params.push_back(red);
DO_IT_NOW(_glColor4f, 4);
}
void Batch::do_glColor4f(uint32& paramOffset) {
glColor4f(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float);
}
void Batch::_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
ADD_COMMAND(glMaterialf);
_params.push_back(param);
_params.push_back(pname);
_params.push_back(face);
DO_IT_NOW(_glMaterialf, 3);
}
void Batch::do_glMaterialf(uint32& paramOffset) {
glMaterialf(_params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._float);
}
void Batch::_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
ADD_COMMAND(glMaterialfv);
_params.push_back(cacheData(4 * sizeof(float), params));
_params.push_back(pname);
_params.push_back(face);
DO_IT_NOW(_glMaterialfv, 3);
}
void Batch::do_glMaterialfv(uint32& paramOffset) {
glMaterialfv(_params[paramOffset++]._uint, _params[paramOffset++]._uint, (const GLfloat*) editData(_params[paramOffset++]._uint));
}
void backend::renderBatch(Batch& batch) {
for (int i = 0; i < batch._commands.size(); i++) {
batch.runCommand(i);
}
}

View file

@ -18,6 +18,13 @@
namespace gpu { namespace gpu {
class Batch;
// TODO: move the backend namespace into dedicated files, for now we keep it close to the gpu objects definition for convenience
namespace backend {
void renderBatch(Batch& batch);
};
class Buffer; class Buffer;
class Resource; class Resource;
typedef int Stamp; typedef int Stamp;
@ -98,21 +105,22 @@ public:
void _glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); void _glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
void _glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); void _glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
void _glEnableVertexArrayAttrib(GLint location); void _glEnableVertexAttribArray(GLint location);
void _glDisableVertexArrayAttrib(GLint location); void _glDisableVertexAttribArray(GLint location);
void _glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void _glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void _glMaterialf(GLenum face, GLenum pname, GLfloat param); void _glMaterialf(GLenum face, GLenum pname, GLfloat param);
void _glMaterialfv(GLenum face, GLenum pname, const GLfloat *params); void _glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
protected: protected:
enum Command { enum Command {
COMMAND_DRAW = 0, COMMAND_draw = 0,
COMMAND_DRAW_INDEXED, COMMAND_drawIndexed,
COMMAND_DRAW_INSTANCED, COMMAND_drawInstanced,
COMMAND_DRAW_INDEXED_INSTANCED, COMMAND_drawIndexedInstanced,
COMMAND_SET_PIPE_STATE, COMMAND_SET_PIPE_STATE,
COMMAND_SET_VIEWPORT, COMMAND_SET_VIEWPORT,
@ -167,8 +175,8 @@ protected:
COMMAND_glVertexPointer, COMMAND_glVertexPointer,
COMMAND_glVertexAttribPointer, COMMAND_glVertexAttribPointer,
COMMAND_glEnableVertexArrayAttrib, COMMAND_glEnableVertexAttribArray,
COMMAND_glDisableVertexArrayAttrib, COMMAND_glDisableVertexAttribArray,
COMMAND_glColor4f, COMMAND_glColor4f,
@ -176,6 +184,10 @@ protected:
COMMAND_glMaterialfv, COMMAND_glMaterialfv,
}; };
typedef std::vector<Command> Commands; typedef std::vector<Command> Commands;
typedef void (Batch::*CommandCall)(uint32&);
typedef std::vector<CommandCall> CommandCalls;
typedef std::vector<uint32> CommandOffsets;
class Param { class Param {
public: public:
@ -184,80 +196,136 @@ protected:
uint32 _uint; uint32 _uint;
float _float; float _float;
char _chars[4]; char _chars[4];
const void* _constPointer;
double _double; double _double;
}; };
Param(int32 val) : _int(val) {} Param(int32 val) : _int(val) {}
Param(uint32 val) : _uint(val) {} Param(uint32 val) : _uint(val) {}
Param(float val) : _float(val) {} Param(float val) : _float(val) {}
Param(const void* val) : _constPointer(val) {}
Param(double val) : _double(val) {} Param(double val) : _double(val) {}
}; };
typedef std::vector<Param> Params; typedef std::vector<Param> Params;
class ResourceCache { class ResourceCache {
public: public:
Resource* _resource; union {
Resource* _resource;
const void* _pointer;
};
ResourceCache(Resource* res) : _resource(res) {}
ResourceCache(const void* pointer) : _pointer(pointer) {}
}; };
typedef std::vector<ResourceCache> Resources; typedef std::vector<ResourceCache> Resources;
typedef unsigned char Byte;
typedef std::vector<Byte> Bytes;
Commands _commands; Commands _commands;
CommandCalls _commandCalls;
CommandOffsets _commandOffsets;
Params _params; Params _params;
Resources _resources; Resources _resources;
Bytes _data;
uint32 cacheResource(Resource* res);
uint32 cacheResource(const void* pointer);
ResourceCache* editResource(uint32 offset) {
if (offset >= _resources.size())
return 0;
return (_resources.data() + offset);
}
uint32 cacheData(uint32 size, const void* data);
Byte* editData(uint32 offset) {
if (offset >= _data.size())
return 0;
return (_data.data() + offset);
}
void runCommand(uint32 index) {
uint32 offset = _commandOffsets[index];
CommandCall call = _commandCalls[index];
(this->*(call))(offset);
uint32 nextOFfset = offset;
GLenum error = glGetError();
if (error) {
error++;
}
}
void runLastCommand() {
uint32 index = _commands.size() - 1;
uint32 offset = _commandOffsets[index];
/* CommandCall call = _commandCalls[index];
(this->*(call))(offset);
uint32 nextOFfset = offset;
*/
runCommand(_commands[index], offset);
}
void runCommand(Command com, uint32 offset);
void do_draw(uint32& paramOffset) {}
void do_drawIndexed(uint32& paramOffset) {}
void do_drawInstanced(uint32& paramOffset) {}
void do_drawIndexedInstanced(uint32& paramOffset) {}
// TODO: As long as we have gl calls explicitely issued from interface // TODO: As long as we have gl calls explicitely issued from interface
// code, we need to be able to record and batch these calls. THe long // code, we need to be able to record and batch these calls. THe long
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API // term strategy is to get rid of any GL calls in favor of the HIFI GPU API
void do_glEnable(int &paramOffset); void do_glEnable(uint32& paramOffset);
void do_glDisable(int &paramOffset); void do_glDisable(uint32& paramOffset);
void do_glEnableClientState(int &paramOffset); void do_glEnableClientState(uint32& paramOffset);
void do_glDisableClientState(int &paramOffset); void do_glDisableClientState(uint32& paramOffset);
void do_glCullFace(int &paramOffset); void do_glCullFace(uint32& paramOffset);
void do_glAlphaFunc(int &paramOffset); void do_glAlphaFunc(uint32& paramOffset);
void do_glDepthFunc(int &paramOffset); void do_glDepthFunc(uint32& paramOffset);
void do_glDepthMask(int &paramOffset); void do_glDepthMask(uint32& paramOffset);
void do_glDepthRange(int &paramOffset); void do_glDepthRange(uint32& paramOffset);
void do_glBindBuffer(int &paramOffset); void do_glBindBuffer(uint32& paramOffset);
void do_glBindTexture(int &paramOffset); void do_glBindTexture(uint32& paramOffset);
void do_glActiveTexture(int &paramOffset); void do_glActiveTexture(uint32& paramOffset);
void do_glDrawBuffers(int &paramOffset); void do_glDrawBuffers(uint32& paramOffset);
void do_glUseProgram(int &paramOffset); void do_glUseProgram(uint32& paramOffset);
void do_glUniform1f(int &paramOffset); void do_glUniform1f(uint32& paramOffset);
void do_glUniformMatrix4fv(int &paramOffset); void do_glUniformMatrix4fv(uint32& paramOffset);
void do_glMatrixMode(int &paramOffset); void do_glMatrixMode(uint32& paramOffset);
void do_glPushMatrix(int &paramOffset); void do_glPushMatrix(uint32& paramOffset);
void do_glPopMatrix(int &paramOffset); void do_glPopMatrix(uint32& paramOffset);
void do_glMultMatrixf(int &paramOffset); void do_glMultMatrixf(uint32& paramOffset);
void do_glLoadMatrixf(int &paramOffset); void do_glLoadMatrixf(uint32& paramOffset);
void do_glLoadIdentity(int &paramOffset); void do_glLoadIdentity(uint32& paramOffset);
void do_glRotatef(int &paramOffset); void do_glRotatef(uint32& paramOffset);
void do_glScalef(int &paramOffset); void do_glScalef(uint32& paramOffset);
void do_glTranslatef(int &paramOffset); void do_glTranslatef(uint32& paramOffset);
void do_glDrawArrays(int &paramOffset); void do_glDrawArrays(uint32& paramOffset);
void do_glDrawRangeElements(int &paramOffset); void do_glDrawRangeElements(uint32& paramOffset);
void do_glColorPointer(int &paramOffset); void do_glColorPointer(uint32& paramOffset);
void do_glNormalPointer(int &paramOffset); void do_glNormalPointer(uint32& paramOffset);
void do_glTexCoordPointer(int &paramOffset); void do_glTexCoordPointer(uint32& paramOffset);
void do_glVertexPointer(int &paramOffset); void do_glVertexPointer(uint32& paramOffset);
void do_glVertexAttribPointer(int &paramOffset); void do_glVertexAttribPointer(uint32& paramOffset);
void do_glEnableVertexArrayAttrib(int &paramOffset); void do_glEnableVertexAttribArray(uint32& paramOffset);
void do_glDisableVertexArrayAttrib(int &paramOffset); void do_glDisableVertexAttribArray(uint32& paramOffset);
void do_glColor4f(int &paramOffset); void do_glColor4f(uint32& paramOffset);
void do_glMaterialf(int &paramOffset); void do_glMaterialf(uint32& paramOffset);
void do_glMaterialfv(int &paramOffset); void do_glMaterialfv(uint32& paramOffset);
friend void backend::renderBatch(Batch& batch);
}; };
}; };

View file

@ -1609,18 +1609,28 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
ProgramObject* activeProgram = program; ProgramObject* activeProgram = program;
Locations* activeLocations = locations; Locations* activeLocations = locations;
if (isSkinned) { // Try to use the Batch
gpu::Batch batch;
/*if (isSkinned) {
skinProgram->bind(); skinProgram->bind();
activeProgram = skinProgram; activeProgram = skinProgram;
activeLocations = skinLocations; activeLocations = skinLocations;
} else { } else {
program->bind(); program->bind();
}*/
if (isSkinned) {
activeProgram = skinProgram;
activeLocations = skinLocations;
} }
activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); if (!activeProgram->isLinked()) {
activeProgram->link();
// Try to use the Batch }
gpu::Batch batch; GLBATCH(glUseProgram)(activeProgram->programId());
// activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold);
GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold);
// i is the "index" from the original networkMeshes QVector... // i is the "index" from the original networkMeshes QVector...
@ -1639,7 +1649,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
const FBXMesh& mesh = geometry.meshes.at(i); const FBXMesh& mesh = geometry.meshes.at(i);
//const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bind(); //const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bind();
GLBATCH(glBindBuffer)( GL_INDEX_ARRAY, const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bufferId() ); GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bufferId());
int vertexCount = mesh.vertices.size(); int vertexCount = mesh.vertices.size();
if (vertexCount == 0) { if (vertexCount == 0) {
@ -1674,8 +1684,9 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
} }
} }
const_cast<QOpenGLBuffer&>(networkMesh.vertexBuffer).bind(); //const_cast<QOpenGLBuffer&>(networkMesh.vertexBuffer).bind();
GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, const_cast<QOpenGLBuffer&>(networkMesh.vertexBuffer).bufferId());
GLBATCH(glPushMatrix)(); GLBATCH(glPushMatrix)();
//Application::getInstance()->loadTranslatedViewMatrix(_translation); //Application::getInstance()->loadTranslatedViewMatrix(_translation);
GLBATCH(glLoadMatrixf)((const GLfloat*)&Application::getInstance()->getUntranslatedViewMatrix()); GLBATCH(glLoadMatrixf)((const GLfloat*)&Application::getInstance()->getUntranslatedViewMatrix());
@ -1690,19 +1701,25 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
int offset = (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3) + int offset = (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3) +
mesh.texCoords.size() * sizeof(glm::vec2) + mesh.texCoords.size() * sizeof(glm::vec2) +
(mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0); (mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0);
skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4); //skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4);
skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT, GLBATCH(glVertexAttribPointer)(skinLocations->clusterIndices, 4, GL_FLOAT, GL_TRUE, 0, (const void*) offset);
offset + vertexCount * sizeof(glm::vec4), 4); //skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT,
skinProgram->enableAttributeArray(skinLocations->clusterIndices); // offset + vertexCount * sizeof(glm::vec4), 4);
skinProgram->enableAttributeArray(skinLocations->clusterWeights); GLBATCH(glVertexAttribPointer)(skinLocations->clusterWeights, 4, GL_FLOAT, GL_TRUE, 0, (const void*) (offset + vertexCount * sizeof(glm::vec4)));
//skinProgram->enableAttributeArray(skinLocations->clusterIndices);
GLBATCH(glEnableVertexAttribArray)(skinLocations->clusterIndices);
//skinProgram->enableAttributeArray(skinLocations->clusterWeights);
GLBATCH(glEnableVertexAttribArray)(skinLocations->clusterWeights);
} else { } else {
GLBATCH(glMultMatrixf)((const GLfloat*)&state.clusterMatrices[0]); GLBATCH(glMultMatrixf)((const GLfloat*)&state.clusterMatrices[0]);
} }
if (mesh.blendshapes.isEmpty()) { if (mesh.blendshapes.isEmpty()) {
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); //activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
activeProgram->enableAttributeArray(activeLocations->tangent); GLBATCH(glVertexAttribPointer)(activeLocations->tangent, 3, GL_FLOAT, GL_TRUE, 0, (const void*)(vertexCount * 2 * sizeof(glm::vec3)));
//activeProgram->enableAttributeArray(activeLocations->tangent);
GLBATCH(glEnableVertexAttribArray)(activeLocations->tangent);
} }
GLBATCH(glColorPointer)(3, GL_FLOAT, 0, (void*)(vertexCount * 2 * sizeof(glm::vec3) + GLBATCH(glColorPointer)(3, GL_FLOAT, 0, (void*)(vertexCount * 2 * sizeof(glm::vec3) +
mesh.tangents.size() * sizeof(glm::vec3))); mesh.tangents.size() * sizeof(glm::vec3)));
@ -1711,12 +1728,15 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
} else { } else {
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, 0, 3); //activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, 0, 3);
activeProgram->enableAttributeArray(activeLocations->tangent); GLBATCH(glVertexAttribPointer)(activeLocations->tangent, 3, GL_FLOAT, GL_TRUE, 0, 0);
//activeProgram->enableAttributeArray(activeLocations->tangent);
GLBATCH(glEnableVertexAttribArray)(activeLocations->tangent);
} }
GLBATCH(glColorPointer)(3, GL_FLOAT, 0, (void*)(mesh.tangents.size() * sizeof(glm::vec3))); GLBATCH(glColorPointer)(3, GL_FLOAT, 0, (void*)(mesh.tangents.size() * sizeof(glm::vec3)));
GLBATCH(glTexCoordPointer)(2, GL_FLOAT, 0, (void*)((mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3))); GLBATCH(glTexCoordPointer)(2, GL_FLOAT, 0, (void*)((mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3)));
_blendedVertexBuffers[i].bind(); // _blendedVertexBuffers[i].bind();
GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, _blendedVertexBuffers[i].bufferId());
} }
GLBATCH(glVertexPointer)(3, GL_FLOAT, 0, 0); GLBATCH(glVertexPointer)(3, GL_FLOAT, 0, 0);
GLBATCH(glNormalPointer)(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3))); GLBATCH(glNormalPointer)(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3)));
@ -1738,6 +1758,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int);
continue; continue;
} }
// apply material properties // apply material properties
if (mode == SHADOW_RENDER_MODE) { if (mode == SHADOW_RENDER_MODE) {
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
@ -1826,7 +1847,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
GLBATCH(glActiveTexture)(GL_TEXTURE0); GLBATCH(glActiveTexture)(GL_TEXTURE0);
// activeProgram->disableAttributeArray(activeLocations->tangent); // activeProgram->disableAttributeArray(activeLocations->tangent);
GLBATCH(glDisableVertexArrayAttrib)(activeLocations->tangent); GLBATCH(glDisableVertexAttribArray)(activeLocations->tangent);
} }
if (specularTextureUnit) { if (specularTextureUnit) {
@ -1837,9 +1858,9 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
if (state.clusterMatrices.size() > 1) { if (state.clusterMatrices.size() > 1) {
// skinProgram->disableAttributeArray(skinLocations->clusterIndices); // skinProgram->disableAttributeArray(skinLocations->clusterIndices);
GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterIndices); GLBATCH(glDisableVertexAttribArray)(skinLocations->clusterIndices);
// skinProgram->disableAttributeArray(skinLocations->clusterWeights); // skinProgram->disableAttributeArray(skinLocations->clusterWeights);
GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterWeights); GLBATCH(glDisableVertexAttribArray)(skinLocations->clusterWeights);
} }
GLBATCH(glPopMatrix)(); GLBATCH(glPopMatrix)();
@ -1847,6 +1868,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
//activeProgram->release(); //activeProgram->release();
GLBATCH(glUseProgram)(0); GLBATCH(glUseProgram)(0);
::gpu::backend::renderBatch(batch);
return meshPartsRendered; return meshPartsRendered;
} }