From 00dbe486d9339de11c00a51425081dfea97bae69 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 21 Oct 2014 10:50:53 -0700 Subject: [PATCH] FIrst working version of the GLBatching system introduced in the MOdelrendering path --- interface/src/gpu/Batch.cpp | 843 ++++++++++++++++++------------- interface/src/gpu/Batch.h | 164 ++++-- interface/src/renderer/Model.cpp | 66 ++- 3 files changed, 659 insertions(+), 414 deletions(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 43c6872072..9458dc8a3f 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -12,14 +12,21 @@ #include -#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; Batch::Batch() : _commands(), _params(), - _resources(){ + _resources(), + _data(){ } Batch::~Batch() { @@ -29,24 +36,99 @@ void Batch::clear() { _commands.clear(); _params.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) { - _commands.push_back(COMMAND_DRAW); + ADD_COMMAND(draw); + _params.push_back(startVertex); _params.push_back(nbVertices); _params.push_back(primitiveType); } 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(nbIndices); _params.push_back(primitiveType); } 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(startVertex); _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) { - _commands.push_back(COMMAND_DRAW_INDEXED_INSTANCED); + ADD_COMMAND(drawIndexedInstanced); + _params.push_back(startInstance); _params.push_back(startIndex); _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 // term strategy is to get rid of any GL calls in favor of the HIFI GPU API -void Batch::_glEnable(GLenum cap) { - _commands.push_back(COMMAND_glEnable); - _params.push_back(cap); - - DO_IT_NOW(_glEnable, 1); -} -void Batch::do_glEnable(int ¶mOffset) { - 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 ¶mOffset) { - 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 ¶mOffset) { - glEnableClientState(_params[paramOffset++]._uint); -} +void Batch::_glEnable(GLenum cap) { + ADD_COMMAND(glEnable); -void Batch::_glDisableClientState(GLenum array) { - _commands.push_back(COMMAND_glDisableClientState); - _params.push_back(array); - - DO_IT_NOW(_glDisableClientState, 1); + _params.push_back(cap); + + DO_IT_NOW(_glEnable, 1); } -void Batch::do_glDisableClientState(int ¶mOffset) { +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); } -void Batch::_glCullFace(GLenum mode) { - _commands.push_back(COMMAND_glCullFace); - _params.push_back(mode); - - DO_IT_NOW(_glCullFace, 1); +void Batch::_glCullFace(GLenum mode) { + ADD_COMMAND(glCullFace); + + _params.push_back(mode); + + DO_IT_NOW(_glCullFace, 1); } -void Batch::do_glCullFace(int ¶mOffset) { +void Batch::do_glCullFace(uint32& paramOffset) { glCullFace(_params[paramOffset++]._uint); } -void Batch::_glAlphaFunc(GLenum func, GLclampf ref) { - _commands.push_back(COMMAND_glAlphaFunc); - _params.push_back(ref); - _params.push_back(func); - - DO_IT_NOW(_glAlphaFunc, 1); -} -void Batch::do_glAlphaFunc(int ¶mOffset) { - glAlphaFunc(_params[paramOffset++]._uint, _params[paramOffset++]._float); -} +void Batch::_glAlphaFunc(GLenum func, GLclampf ref) { + ADD_COMMAND(glAlphaFunc); -void Batch::_glDepthFunc(GLenum func) { - _commands.push_back(COMMAND_glDepthFunc); - _params.push_back(func); - - DO_IT_NOW(_glDepthFunc, 1); -} -void Batch::do_glDepthFunc(int ¶mOffset) { + _params.push_back(ref); + _params.push_back(func); + + DO_IT_NOW(_glAlphaFunc, 2); +} +void Batch::do_glAlphaFunc(uint32& 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); -} - -void Batch::_glDepthMask(GLboolean flag) { - _commands.push_back(COMMAND_glDepthMask); - _params.push_back(flag); - - DO_IT_NOW(_glDepthMask, 1); -} -void Batch::do_glDepthMask(int ¶mOffset) { +} + +void Batch::_glDepthMask(GLboolean flag) { + ADD_COMMAND(glDepthMask); + + _params.push_back(flag); + + DO_IT_NOW(_glDepthMask, 1); +} +void Batch::do_glDepthMask(uint32& paramOffset) { glDepthMask(_params[paramOffset++]._uint); -} - -void Batch::_glDepthRange(GLclampd zNear, GLclampd zFar) { - _commands.push_back(COMMAND_glDepthRange); - _params.push_back(zFar); - _params.push_back(zNear); - - DO_IT_NOW(_glDepthRange, 2); -} -void Batch::do_glDepthRange(int ¶mOffset) { +} + +void Batch::_glDepthRange(GLclampd zNear, GLclampd zFar) { + ADD_COMMAND(glDepthRange); + + _params.push_back(zFar); + _params.push_back(zNear); + + DO_IT_NOW(_glDepthRange, 2); +} +void Batch::do_glDepthRange(uint32& paramOffset) { glDepthRange(_params[paramOffset++]._double, _params[paramOffset++]._double); } -void Batch::_glBindBuffer(GLenum target, GLuint buffer) { - _commands.push_back(COMMAND_glBindBuffer); - _params.push_back(buffer); - _params.push_back(target); - - DO_IT_NOW(_glBindBuffer, 2); -} -void Batch::do_glBindBuffer(int ¶mOffset) { +void Batch::_glBindBuffer(GLenum target, GLuint buffer) { + ADD_COMMAND(glBindBuffer); + + _params.push_back(buffer); + _params.push_back(target); + + DO_IT_NOW(_glBindBuffer, 2); +} +void Batch::do_glBindBuffer(uint32& paramOffset) { glBindBuffer(_params[paramOffset++]._uint, _params[paramOffset++]._uint); } -void Batch::_glBindTexture(GLenum target, GLuint texture) { - _commands.push_back(COMMAND_glBindTexture); - _params.push_back(texture); - _params.push_back(target); - - DO_IT_NOW(_glBindTexture, 2); -} -void Batch::do_glBindTexture(int ¶mOffset) { +void Batch::_glBindTexture(GLenum target, GLuint texture) { + ADD_COMMAND(glBindTexture); + + _params.push_back(texture); + _params.push_back(target); + + DO_IT_NOW(_glBindTexture, 2); +} +void Batch::do_glBindTexture(uint32& paramOffset) { glBindTexture(_params[paramOffset++]._uint, _params[paramOffset++]._uint); } -void Batch::_glActiveTexture(GLenum texture) { - _commands.push_back(COMMAND_glActiveTexture); - _params.push_back(texture); - - DO_IT_NOW(_glActiveTexture, 1); -} -void Batch::do_glActiveTexture(int ¶mOffset) { +void Batch::_glActiveTexture(GLenum texture) { + ADD_COMMAND(glActiveTexture); + + _params.push_back(texture); + + DO_IT_NOW(_glActiveTexture, 1); +} +void Batch::do_glActiveTexture(uint32& paramOffset) { glActiveTexture(_params[paramOffset++]._uint); } -void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) { - _commands.push_back(COMMAND_glDrawBuffers); - _params.push_back(bufs); - _params.push_back(n); - - DO_IT_NOW(_glDrawBuffers, 2); -} -void Batch::do_glDrawBuffers(int ¶mOffset) { - glDrawBuffers(_params[paramOffset++]._uint, (const GLenum*) _params[paramOffset++]._constPointer); +void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) { + ADD_COMMAND(glDrawBuffers); + + _params.push_back(cacheData(n * sizeof(GLenum), bufs)); + _params.push_back(n); + + DO_IT_NOW(_glDrawBuffers, 2); +} +void Batch::do_glDrawBuffers(uint32& paramOffset) { + glDrawBuffers(_params[paramOffset++]._uint, (const GLenum*) editData(_params[paramOffset++]._uint)); } -void Batch::_glUseProgram(GLuint program) { - _commands.push_back(COMMAND_glUseProgram); - _params.push_back(program); - - DO_IT_NOW(_glUseProgram, 1); -} -void Batch::do_glUseProgram(int ¶mOffset) { +void Batch::_glUseProgram(GLuint program) { + ADD_COMMAND(glUseProgram); + + _params.push_back(program); + + DO_IT_NOW(_glUseProgram, 1); +} +void Batch::do_glUseProgram(uint32& paramOffset) { glUseProgram(_params[paramOffset++]._uint); } - -void Batch::_glUniform1f(GLint location, GLfloat v0) { - _commands.push_back(COMMAND_glUniform1f); - _params.push_back(v0); - _params.push_back(location); - - DO_IT_NOW(_glUniform1f, 1); -} -void Batch::do_glUniform1f(int ¶mOffset) { - glUniform1f(_params[paramOffset++]._float); + +void Batch::_glUniform1f(GLint location, GLfloat v0) { + ADD_COMMAND(glUniform1f); + + _params.push_back(v0); + _params.push_back(location); + + DO_IT_NOW(_glUniform1f, 1); +} +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) { - _commands.push_back(COMMAND_glUniformMatrix4fv); - _params.push_back(value); - _params.push_back(transpose); - _params.push_back(count); - _params.push_back(location); - - DO_IT_NOW(_glUniformMatrix4fv, 4); -} -void Batch::do_glUniformMatrix4fv(int ¶mOffset) { - glUniformMatrix4fv(_params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._constPointer); +void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + ADD_COMMAND(glUniformMatrix4fv); + + const int MATRIX4_SIZE = 16 * sizeof(float); + _params.push_back(cacheData(count * MATRIX4_SIZE, value)); + _params.push_back(transpose); + _params.push_back(count); + _params.push_back(location); + + DO_IT_NOW(_glUniformMatrix4fv, 4); +} +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) { - _commands.push_back(COMMAND_glMatrixMode); - _params.push_back(mode); - - DO_IT_NOW(_glMatrixMode, 1); -} -void Batch::do_glMatrixMode(int ¶mOffset) { +void Batch::_glMatrixMode(GLenum mode) { + ADD_COMMAND(glMatrixMode); + + _params.push_back(mode); + + DO_IT_NOW(_glMatrixMode, 1); +} +void Batch::do_glMatrixMode(uint32& paramOffset) { glMatrixMode(_params[paramOffset++]._uint); } -void Batch::_glPushMatrix() { - _commands.push_back(COMMAND_glPushMatrix); - - DO_IT_NOW(_glPushMatrix, 0); -} -void Batch::do_glPushMatrix(int ¶mOffset) { +void Batch::_glPushMatrix() { + ADD_COMMAND(glPushMatrix); + + DO_IT_NOW(_glPushMatrix, 0); +} +void Batch::do_glPushMatrix(uint32& paramOffset) { glPushMatrix(); } -void Batch::_glPopMatrix() { - _commands.push_back(COMMAND_glPopMatrix); +void Batch::_glPopMatrix() { + ADD_COMMAND(glPopMatrix); DO_IT_NOW(_glPopMatrix, 0); -} -void Batch::do_glPopMatrix(int ¶mOffset) { +} +void Batch::do_glPopMatrix(uint32& paramOffset) { glPopMatrix(); } -void Batch::_glMultMatrixf(const GLfloat *m) { - _commands.push_back(COMMAND_glMultMatrixf); - _params.push_back(m); - +void Batch::_glMultMatrixf(const GLfloat *m) { + ADD_COMMAND(glMultMatrixf); + + const int MATRIX4_SIZE = 16 * sizeof(float); + _params.push_back(cacheData(MATRIX4_SIZE, m)); + DO_IT_NOW(_glMultMatrixf, 1); -} -void Batch::do_glMultMatrixf(int ¶mOffset) { - glMultMatrixf((const GLfloat*) _params[paramOffset++]._constPointer); +} +void Batch::do_glMultMatrixf(uint32& paramOffset) { + glMultMatrixf((const GLfloat*) editData(_params[paramOffset++]._uint)); } -void Batch::_glLoadMatrixf(const GLfloat *m) { - _commands.push_back(COMMAND_glLoadMatrixf); - _params.push_back(m); +void Batch::_glLoadMatrixf(const GLfloat *m) { + ADD_COMMAND(glLoadMatrixf); - DO_IT_NOW(_glLoadMatrixf, 1); -} -void Batch::do_glLoadMatrixf(int ¶mOffset) { - glLoadMatrixf((const GLfloat*)_params[paramOffset++]._constPointer); -} - -void Batch::_glLoadIdentity(void) { - _commands.push_back(COMMAND_glLoadIdentity); - - DO_IT_NOW(_glLoadIdentity, 0); -} -void Batch::do_glLoadIdentity(int ¶mOffset) { + const int MATRIX4_SIZE = 16 * sizeof(float); + _params.push_back(cacheData(MATRIX4_SIZE, m)); + + DO_IT_NOW(_glLoadMatrixf, 1); +} +void Batch::do_glLoadMatrixf(uint32& paramOffset) { + glLoadMatrixf((const GLfloat*)editData(_params[paramOffset++]._uint)); +} + +void Batch::_glLoadIdentity(void) { + ADD_COMMAND(glLoadIdentity); + + DO_IT_NOW(_glLoadIdentity, 0); +} +void Batch::do_glLoadIdentity(uint32& paramOffset) { glLoadIdentity(); -} - -void Batch::_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - _commands.push_back(COMMAND_glRotatef); - _params.push_back(z); - _params.push_back(y); - _params.push_back(x); - _params.push_back(angle); - - DO_IT_NOW(_glRotatef, 4); -} -void Batch::do_glRotatef(int ¶mOffset) { +} + +void Batch::_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + ADD_COMMAND(glRotatef); + + _params.push_back(z); + _params.push_back(y); + _params.push_back(x); + _params.push_back(angle); + + DO_IT_NOW(_glRotatef, 4); +} +void Batch::do_glRotatef(uint32& paramOffset) { glRotatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); -} - -void Batch::_glScalef(GLfloat x, GLfloat y, GLfloat z) { - _commands.push_back(COMMAND_glScalef); - _params.push_back(z); - _params.push_back(y); - _params.push_back(x); - - DO_IT_NOW(_glScalef, 3); -} -void Batch::do_glScalef(int ¶mOffset) { +} + +void Batch::_glScalef(GLfloat x, GLfloat y, GLfloat z) { + ADD_COMMAND(glScalef); + + _params.push_back(z); + _params.push_back(y); + _params.push_back(x); + + DO_IT_NOW(_glScalef, 3); +} +void Batch::do_glScalef(uint32& paramOffset) { glScalef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); -} - -void Batch::_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { - _commands.push_back(COMMAND_glTranslatef); - _params.push_back(z); - _params.push_back(y); - _params.push_back(x); - - DO_IT_NOW(_glTranslatef, 3); -} -void Batch::do_glTranslatef(int ¶mOffset) { +} + +void Batch::_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { + ADD_COMMAND(glTranslatef); + + _params.push_back(z); + _params.push_back(y); + _params.push_back(x); + + DO_IT_NOW(_glTranslatef, 3); +} +void Batch::do_glTranslatef(uint32& paramOffset) { glTranslatef(_params[paramOffset++]._float, _params[paramOffset++]._float, _params[paramOffset++]._float); -} - -void Batch::_glDrawArrays(GLenum mode, GLint first, GLsizei count) { - _commands.push_back(COMMAND_glDrawArrays); - _params.push_back(count); - _params.push_back(first); - _params.push_back(mode); - - DO_IT_NOW(_glDrawArrays, 3); -} -void Batch::do_glDrawArrays(int ¶mOffset) { +} + +void Batch::_glDrawArrays(GLenum mode, GLint first, GLsizei count) { + ADD_COMMAND(glDrawArrays); + + _params.push_back(count); + _params.push_back(first); + _params.push_back(mode); + + DO_IT_NOW(_glDrawArrays, 3); +} +void Batch::do_glDrawArrays(uint32& paramOffset) { 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) { - _commands.push_back(COMMAND_glDrawRangeElements); - _params.push_back(indices); - _params.push_back(type); - _params.push_back(count); - _params.push_back(end); - _params.push_back(start); - _params.push_back(mode); - - DO_IT_NOW(_glDrawRangeElements, 6); -} -void Batch::do_glDrawRangeElements(int ¶mOffset) { - glDrawRangeElements(_params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._constPointer); -} - -void Batch::_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { - _commands.push_back(COMMAND_glColorPointer); - _params.push_back(pointer); - _params.push_back(stride); - _params.push_back(type); - _params.push_back(size); - - DO_IT_NOW(_glColorPointer, 4); -} -void Batch::do_glColorPointer(int ¶mOffset) { - glColorPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._constPointer); -} - -void Batch::_glNormalPointer(GLenum type, GLsizei stride, const void *pointer) { - _commands.push_back(COMMAND_glNormalPointer); - _params.push_back(pointer); - _params.push_back(stride); - _params.push_back(type); - - DO_IT_NOW(_glNormalPointer, 4); -} -void Batch::do_glNormalPointer(int ¶mOffset) { - glNormalPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int, _params[paramOffset++]._constPointer); -} - -void Batch::_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { - _commands.push_back(COMMAND_glTexCoordPointer); - _params.push_back(pointer); - _params.push_back(stride); - _params.push_back(type); - _params.push_back(size); -} -void Batch::do_glCullFace(int ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); -} - -void Batch::_glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { - _commands.push_back(COMMAND_glVertexPointer); - _params.push_back(pointer); - _params.push_back(stride); - _params.push_back(type); - _params.push_back(size); -} -void Batch::do_glCullFace(int ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); +} + +void Batch::_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) { + ADD_COMMAND(glDrawRangeElements); + + _params.push_back(cacheResource(indices)); + _params.push_back(type); + _params.push_back(count); + _params.push_back(end); + _params.push_back(start); + _params.push_back(mode); + + //do_glDrawRangeElements(_commandOffsets.back()); + // runCommand(_commands.size() - 1); + DO_IT_NOW(_glDrawRangeElements, 6); +} +void Batch::do_glDrawRangeElements(uint32& paramOffset) { + glDrawRangeElements(_params[paramOffset++]._uint, _params[paramOffset++]._uint, + _params[paramOffset++]._uint, _params[paramOffset++]._int, + _params[paramOffset++]._uint, editResource(_params[paramOffset++]._uint)->_pointer); +} + +void Batch::_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { + ADD_COMMAND(glColorPointer); + + _params.push_back(cacheResource(pointer)); + _params.push_back(stride); + _params.push_back(type); + _params.push_back(size); + + DO_IT_NOW(_glColorPointer, 4); +} +void Batch::do_glColorPointer(uint32& paramOffset) { + glColorPointer(_params[paramOffset++]._int, _params[paramOffset++]._uint, + _params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer); +} + +void Batch::_glNormalPointer(GLenum type, GLsizei stride, const void *pointer) { + ADD_COMMAND(glNormalPointer); + + _params.push_back(cacheResource(pointer)); + _params.push_back(stride); + _params.push_back(type); + + DO_IT_NOW(_glNormalPointer, 3); +} +void Batch::do_glNormalPointer(uint32& paramOffset) { + glNormalPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int, + editResource(_params[paramOffset++]._uint)->_pointer); +} + +void Batch::_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { + ADD_COMMAND(glTexCoordPointer); + + _params.push_back(cacheResource(pointer)); + _params.push_back(stride); + _params.push_back(type); + _params.push_back(size); + + DO_IT_NOW(_glTexCoordPointer, 4); +} +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) { - _commands.push_back(COMMAND_glVertexPointer); - _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 ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); -} +void Batch::_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) { + ADD_COMMAND(glVertexAttribPointer); -void Batch::_glEnableVertexArrayAttrib(GLint location) { - _commands.push_back(COMMAND_glEnableVertexArrayAttrib); - _params.push_back(location); -} -void Batch::do_glCullFace(int ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); -} + _params.push_back(cacheResource(pointer)); + _params.push_back(stride); + _params.push_back(normalized); + _params.push_back(type); + _params.push_back(size); + _params.push_back(index); -void Batch::_glDisableVertexArrayAttrib(GLint location) { - _commands.push_back(COMMAND_glDisableVertexArrayAttrib); - _params.push_back(location); -} -void Batch::do_glCullFace(int ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); + DO_IT_NOW(_glVertexAttribPointer, 6); } - -void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - _commands.push_back(COMMAND_glColor4f); - _params.push_back(alpha); - _params.push_back(blue); - _params.push_back(green); - _params.push_back(red); -} -void Batch::do_glCullFace(int ¶mOffset) { - 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 ¶mOffset) { - 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 ¶mOffset) { - glCullFace(_params[paramOffset++]._uint); +void Batch::do_glVertexAttribPointer(uint32& paramOffset) { + glVertexAttribPointer(_params[paramOffset++]._uint, _params[paramOffset++]._int, + _params[paramOffset++]._uint, _params[paramOffset++]._uint, + _params[paramOffset++]._int, editResource(_params[paramOffset++]._uint)->_pointer); } + +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); + } +} \ No newline at end of file diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index a03c4ac1b7..815a7f61f2 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -18,6 +18,13 @@ 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 Resource; typedef int Stamp; @@ -98,21 +105,22 @@ public: 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 _glEnableVertexArrayAttrib(GLint location); - void _glDisableVertexArrayAttrib(GLint location); + void _glEnableVertexAttribArray(GLint location); + void _glDisableVertexAttribArray(GLint location); void _glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void _glMaterialf(GLenum face, GLenum pname, GLfloat param); void _glMaterialfv(GLenum face, GLenum pname, const GLfloat *params); + protected: enum Command { - COMMAND_DRAW = 0, - COMMAND_DRAW_INDEXED, - COMMAND_DRAW_INSTANCED, - COMMAND_DRAW_INDEXED_INSTANCED, + COMMAND_draw = 0, + COMMAND_drawIndexed, + COMMAND_drawInstanced, + COMMAND_drawIndexedInstanced, COMMAND_SET_PIPE_STATE, COMMAND_SET_VIEWPORT, @@ -167,8 +175,8 @@ protected: COMMAND_glVertexPointer, COMMAND_glVertexAttribPointer, - COMMAND_glEnableVertexArrayAttrib, - COMMAND_glDisableVertexArrayAttrib, + COMMAND_glEnableVertexAttribArray, + COMMAND_glDisableVertexAttribArray, COMMAND_glColor4f, @@ -176,6 +184,10 @@ protected: COMMAND_glMaterialfv, }; typedef std::vector Commands; + typedef void (Batch::*CommandCall)(uint32&); + typedef std::vector CommandCalls; + typedef std::vector CommandOffsets; + class Param { public: @@ -184,80 +196,136 @@ protected: uint32 _uint; float _float; char _chars[4]; - const void* _constPointer; double _double; }; Param(int32 val) : _int(val) {} Param(uint32 val) : _uint(val) {} Param(float val) : _float(val) {} - Param(const void* val) : _constPointer(val) {} Param(double val) : _double(val) {} }; typedef std::vector Params; class ResourceCache { public: - Resource* _resource; + union { + Resource* _resource; + const void* _pointer; + }; + ResourceCache(Resource* res) : _resource(res) {} + ResourceCache(const void* pointer) : _pointer(pointer) {} }; typedef std::vector Resources; + typedef unsigned char Byte; + typedef std::vector Bytes; + Commands _commands; + CommandCalls _commandCalls; + CommandOffsets _commandOffsets; Params _params; 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 // 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 - void do_glEnable(int ¶mOffset); - void do_glDisable(int ¶mOffset); + void do_glEnable(uint32& paramOffset); + void do_glDisable(uint32& paramOffset); - void do_glEnableClientState(int ¶mOffset); - void do_glDisableClientState(int ¶mOffset); + void do_glEnableClientState(uint32& paramOffset); + void do_glDisableClientState(uint32& paramOffset); - void do_glCullFace(int ¶mOffset); - void do_glAlphaFunc(int ¶mOffset); + void do_glCullFace(uint32& paramOffset); + void do_glAlphaFunc(uint32& paramOffset); - void do_glDepthFunc(int ¶mOffset); - void do_glDepthMask(int ¶mOffset); - void do_glDepthRange(int ¶mOffset); + void do_glDepthFunc(uint32& paramOffset); + void do_glDepthMask(uint32& paramOffset); + void do_glDepthRange(uint32& paramOffset); - void do_glBindBuffer(int ¶mOffset); + void do_glBindBuffer(uint32& paramOffset); - void do_glBindTexture(int ¶mOffset); - void do_glActiveTexture(int ¶mOffset); + void do_glBindTexture(uint32& paramOffset); + void do_glActiveTexture(uint32& paramOffset); - void do_glDrawBuffers(int ¶mOffset); + void do_glDrawBuffers(uint32& paramOffset); - void do_glUseProgram(int ¶mOffset); - void do_glUniform1f(int ¶mOffset); - void do_glUniformMatrix4fv(int ¶mOffset); + void do_glUseProgram(uint32& paramOffset); + void do_glUniform1f(uint32& paramOffset); + void do_glUniformMatrix4fv(uint32& paramOffset); - void do_glMatrixMode(int ¶mOffset); - void do_glPushMatrix(int ¶mOffset); - void do_glPopMatrix(int ¶mOffset); - void do_glMultMatrixf(int ¶mOffset); - void do_glLoadMatrixf(int ¶mOffset); - void do_glLoadIdentity(int ¶mOffset); - void do_glRotatef(int ¶mOffset); - void do_glScalef(int ¶mOffset); - void do_glTranslatef(int ¶mOffset); + void do_glMatrixMode(uint32& paramOffset); + void do_glPushMatrix(uint32& paramOffset); + void do_glPopMatrix(uint32& paramOffset); + void do_glMultMatrixf(uint32& paramOffset); + void do_glLoadMatrixf(uint32& paramOffset); + void do_glLoadIdentity(uint32& paramOffset); + void do_glRotatef(uint32& paramOffset); + void do_glScalef(uint32& paramOffset); + void do_glTranslatef(uint32& paramOffset); - void do_glDrawArrays(int ¶mOffset); - void do_glDrawRangeElements(int ¶mOffset); + void do_glDrawArrays(uint32& paramOffset); + void do_glDrawRangeElements(uint32& paramOffset); - void do_glColorPointer(int ¶mOffset); - void do_glNormalPointer(int ¶mOffset); - void do_glTexCoordPointer(int ¶mOffset); - void do_glVertexPointer(int ¶mOffset); + void do_glColorPointer(uint32& paramOffset); + void do_glNormalPointer(uint32& paramOffset); + void do_glTexCoordPointer(uint32& paramOffset); + void do_glVertexPointer(uint32& paramOffset); - void do_glVertexAttribPointer(int ¶mOffset); - void do_glEnableVertexArrayAttrib(int ¶mOffset); - void do_glDisableVertexArrayAttrib(int ¶mOffset); + void do_glVertexAttribPointer(uint32& paramOffset); + void do_glEnableVertexAttribArray(uint32& paramOffset); + void do_glDisableVertexAttribArray(uint32& paramOffset); - void do_glColor4f(int ¶mOffset); + void do_glColor4f(uint32& paramOffset); - void do_glMaterialf(int ¶mOffset); - void do_glMaterialfv(int ¶mOffset); + void do_glMaterialf(uint32& paramOffset); + void do_glMaterialfv(uint32& paramOffset); + + friend void backend::renderBatch(Batch& batch); }; }; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 6032ae4d69..765acdf797 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1609,18 +1609,28 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, ProgramObject* activeProgram = program; Locations* activeLocations = locations; - - if (isSkinned) { + + // Try to use the Batch + gpu::Batch batch; + + /*if (isSkinned) { skinProgram->bind(); activeProgram = skinProgram; activeLocations = skinLocations; } else { program->bind(); + }*/ + if (isSkinned) { + activeProgram = skinProgram; + activeLocations = skinLocations; } - activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); - - // Try to use the Batch - gpu::Batch batch; + if (!activeProgram->isLinked()) { + activeProgram->link(); + } + GLBATCH(glUseProgram)(activeProgram->programId()); + // activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); + GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold); + // 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_cast(networkMesh.indexBuffer).bind(); - GLBATCH(glBindBuffer)( GL_INDEX_ARRAY, const_cast(networkMesh.indexBuffer).bufferId() ); + GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, const_cast(networkMesh.indexBuffer).bufferId()); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { @@ -1674,8 +1684,9 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, } } - const_cast(networkMesh.vertexBuffer).bind(); - + //const_cast(networkMesh.vertexBuffer).bind(); + GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, const_cast(networkMesh.vertexBuffer).bufferId()); + GLBATCH(glPushMatrix)(); //Application::getInstance()->loadTranslatedViewMatrix(_translation); 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) + mesh.texCoords.size() * sizeof(glm::vec2) + (mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0); - skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4); - skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT, - offset + vertexCount * sizeof(glm::vec4), 4); - skinProgram->enableAttributeArray(skinLocations->clusterIndices); - skinProgram->enableAttributeArray(skinLocations->clusterWeights); + //skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4); + GLBATCH(glVertexAttribPointer)(skinLocations->clusterIndices, 4, GL_FLOAT, GL_TRUE, 0, (const void*) offset); + //skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT, + // offset + vertexCount * sizeof(glm::vec4), 4); + 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 { GLBATCH(glMultMatrixf)((const GLfloat*)&state.clusterMatrices[0]); } if (mesh.blendshapes.isEmpty()) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { - activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); - activeProgram->enableAttributeArray(activeLocations->tangent); + //activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); + 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) + mesh.tangents.size() * sizeof(glm::vec3))); @@ -1711,12 +1728,15 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, } else { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { - activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, 0, 3); - activeProgram->enableAttributeArray(activeLocations->tangent); + //activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, 0, 3); + 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(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(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); continue; } + // apply material properties if (mode == SHADOW_RENDER_MODE) { GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); @@ -1826,7 +1847,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, GLBATCH(glActiveTexture)(GL_TEXTURE0); // activeProgram->disableAttributeArray(activeLocations->tangent); - GLBATCH(glDisableVertexArrayAttrib)(activeLocations->tangent); + GLBATCH(glDisableVertexAttribArray)(activeLocations->tangent); } if (specularTextureUnit) { @@ -1837,9 +1858,9 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, if (state.clusterMatrices.size() > 1) { // skinProgram->disableAttributeArray(skinLocations->clusterIndices); - GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterIndices); + GLBATCH(glDisableVertexAttribArray)(skinLocations->clusterIndices); // skinProgram->disableAttributeArray(skinLocations->clusterWeights); - GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterWeights); + GLBATCH(glDisableVertexAttribArray)(skinLocations->clusterWeights); } GLBATCH(glPopMatrix)(); @@ -1847,6 +1868,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, //activeProgram->release(); GLBATCH(glUseProgram)(0); + ::gpu::backend::renderBatch(batch); return meshPartsRendered; }