From f09133f413624c0ee192a3943ef460d764acb711 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Oct 2014 17:23:31 -0700 Subject: [PATCH 1/7] Adding the Batch class to GPU --- interface/src/gpu/Batch.cpp | 65 +++++++++++++++++++++++++ interface/src/gpu/Batch.h | 94 +++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 interface/src/gpu/Batch.cpp create mode 100644 interface/src/gpu/Batch.h diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp new file mode 100644 index 0000000000..a364a678fc --- /dev/null +++ b/interface/src/gpu/Batch.cpp @@ -0,0 +1,65 @@ +// +// Batch.cpp +// interface/src/gpu +// +// Created by Sam Gateau on 10/14/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "Batch.h" + +#include + +using namespace gpu; + +Batch::Batch() : + _commands(), + _params(), + _resources(){ +} + +Batch::~Batch() { +} + +void Batch::clear() { + _commands.clear(); + _params.clear(); + _resources.clear(); +} + +void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { + _commands.push(COMMAND_DRAW); + _params.push(startVertex); + _params.push(nbVertices); + _params.push(primitiveType); +} + +void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) { + _commands.push(COMMAND_DRAW_INDEXED); + _params.push(startIndex); + _params.push(nbIndices); + _params.push(primitiveType); +} + +void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex, int startInstance) { + _commands.push(COMMAND_DRAW_INSTANCED); + _params.push(startInstance); + _params.push(startVertex); + _params.push(nbVertices); + _params.push(primitiveType); + _params.push(nbInstances); +} + +void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex, int startInstance) { + _commands.push(COMMAND_DRAW_INDEXED_INSTANCED); + _params.push(startInstance); + _params.push(startIndex); + _params.push(nbIndices); + _params.push(primitiveType); + _params.push(nbInstances); +} + + + diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h new file mode 100644 index 0000000000..43888e517b --- /dev/null +++ b/interface/src/gpu/Batch.h @@ -0,0 +1,94 @@ +// +// Batch.h +// interface/src/gpu +// +// Created by Sam Gateau on 10/14/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_gpu_Batch_h +#define hifi_gpu_Batch_h + +#include +#include "InterfaceConfig.h" + +namespace gpu { + +class Buffer; +typedef int Stamp; + +// TODO: move the backend namespace into dedicated files, for now we keep it close to the gpu objects definition for convenience +namespace backend { + +}; + +enum Primitive { + PRIMITIVE_POINTS = 0, + PRIMITIVE_LINES, + PRIMITIVE_LINE_STRIP, + PRIMITIVE_TRIANGLES, + PRIMITIVE_TRIANGLE_STRIP, + PRIMITIVE_QUADS, +}; + +class Batch { +public: + + Batch(); + Batch(const Batch& batch); + ~Batch(); + + void clear(); + + void draw( Primitive primitiveType, int nbVertices, int startVertex = 0); + void drawIndexed( Primitive primitiveType, int nbIndices, int startIndex = 0 ); + void drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); + void drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); + + void glBindBuffer( GLenum +protected: + + enum Command { + COMMAND_DRAW = 0, + COMMAND_DRAW_INDEXED, + COMMAND_DRAW_INSTANCED, + COMMAND_DRAW_INDEXED_INSTANCED, + + COMMAND_SET_PIPE_STATE, + COMMAND_SET_VIEWPORT, + COMMAND_SET_FRAMEBUFFER, + COMMAND_SET_RESOURCE, + COMMAND_SET_VERTEX_STREAM, + COMMAND_SET_INDEX_STREAM, + + COMMAND_GL_SET_UNIFORM, + + }; + typedef std::vector Commands; + + class Param { + public: + union { + uint32 _uint; + char _chars[4]; + }; + Param( uint32 val ): _uint(val) {} + }; + typedef std::vector Params; + + class ResourceCache { + public: + Resource* _resource; + }; + typedef std::vector Resources; + + Commands _commands; + Params _params; + Resources _resources; +}; + +}; + +#endif From a8c3b18e7866902d53577f28b928f20f7625c4d6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Oct 2014 17:29:40 -0700 Subject: [PATCH 2/7] Adding the Batch class to GPU and fixing the compilation issues --- interface/src/gpu/Batch.cpp | 66 ++++++++++++++++++------------------- interface/src/gpu/Batch.h | 6 +++- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index a364a678fc..f21ddb3fbc 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -29,37 +29,37 @@ void Batch::clear() { _resources.clear(); } -void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { - _commands.push(COMMAND_DRAW); - _params.push(startVertex); - _params.push(nbVertices); - _params.push(primitiveType); -} - -void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) { - _commands.push(COMMAND_DRAW_INDEXED); - _params.push(startIndex); - _params.push(nbIndices); - _params.push(primitiveType); -} - -void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex, int startInstance) { - _commands.push(COMMAND_DRAW_INSTANCED); - _params.push(startInstance); - _params.push(startVertex); - _params.push(nbVertices); - _params.push(primitiveType); - _params.push(nbInstances); -} - -void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex, int startInstance) { - _commands.push(COMMAND_DRAW_INDEXED_INSTANCED); - _params.push(startInstance); - _params.push(startIndex); - _params.push(nbIndices); - _params.push(primitiveType); - _params.push(nbInstances); -} - - +void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { + _commands.push_back(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); + _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); + _params.push_back(startInstance); + _params.push_back(startVertex); + _params.push_back(nbVertices); + _params.push_back(primitiveType); + _params.push_back(nbInstances); +} + +void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex, int startInstance) { + _commands.push_back(COMMAND_DRAW_INDEXED_INSTANCED); + _params.push_back(startInstance); + _params.push_back(startIndex); + _params.push_back(nbIndices); + _params.push_back(primitiveType); + _params.push_back(nbInstances); +} + + diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index 43888e517b..51e2ce61b6 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -14,10 +14,15 @@ #include #include "InterfaceConfig.h" +#include + namespace gpu { class Buffer; +class Resource; typedef int Stamp; +typedef unsigned int uint32; +typedef int int32; // TODO: move the backend namespace into dedicated files, for now we keep it close to the gpu objects definition for convenience namespace backend { @@ -47,7 +52,6 @@ public: void drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); void drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); - void glBindBuffer( GLenum protected: enum Command { From 0def490db7937d7b92b0b2d03e3ebd3a20a58a54 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 17 Oct 2014 18:17:44 -0700 Subject: [PATCH 3/7] startign to record all the gl commands in the Batch --- interface/src/gpu/Batch.cpp | 403 +++++++++++++++++++++++++++++++ interface/src/gpu/Batch.h | 195 +++++++++++++-- interface/src/renderer/Model.cpp | 102 ++++---- 3 files changed, 643 insertions(+), 57 deletions(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index f21ddb3fbc..43c6872072 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -12,6 +12,8 @@ #include +#define DO_IT_NOW(call, offset) int param = _params.size() - (offset); do##call(param); + using namespace gpu; Batch::Batch() : @@ -61,5 +63,406 @@ void Batch::drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, i _params.push_back(nbInstances); } +// 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 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::_glDisableClientState(GLenum array) { + _commands.push_back(COMMAND_glDisableClientState); + _params.push_back(array); + + DO_IT_NOW(_glDisableClientState, 1); +} +void Batch::do_glDisableClientState(int ¶mOffset) { + 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::do_glCullFace(int ¶mOffset) { + 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::_glDepthFunc(GLenum func) { + _commands.push_back(COMMAND_glDepthFunc); + _params.push_back(func); + + DO_IT_NOW(_glDepthFunc, 1); +} +void Batch::do_glDepthFunc(int ¶mOffset) { + 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) { + 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) { + 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) { + 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) { + 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) { + 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::_glUseProgram(GLuint program) { + _commands.push_back(COMMAND_glUseProgram); + _params.push_back(program); + + DO_IT_NOW(_glUseProgram, 1); +} +void Batch::do_glUseProgram(int ¶mOffset) { + 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::_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::_glMatrixMode(GLenum mode) { + _commands.push_back(COMMAND_glMatrixMode); + _params.push_back(mode); + + DO_IT_NOW(_glMatrixMode, 1); +} +void Batch::do_glMatrixMode(int ¶mOffset) { + glMatrixMode(_params[paramOffset++]._uint); +} + +void Batch::_glPushMatrix() { + _commands.push_back(COMMAND_glPushMatrix); + + DO_IT_NOW(_glPushMatrix, 0); +} +void Batch::do_glPushMatrix(int ¶mOffset) { + glPushMatrix(); +} + +void Batch::_glPopMatrix() { + _commands.push_back(COMMAND_glPopMatrix); + + DO_IT_NOW(_glPopMatrix, 0); +} +void Batch::do_glPopMatrix(int ¶mOffset) { + glPopMatrix(); +} + +void Batch::_glMultMatrixf(const GLfloat *m) { + _commands.push_back(COMMAND_glMultMatrixf); + _params.push_back(m); + + DO_IT_NOW(_glMultMatrixf, 1); +} +void Batch::do_glMultMatrixf(int ¶mOffset) { + glMultMatrixf((const GLfloat*) _params[paramOffset++]._constPointer); +} + +void Batch::_glLoadMatrixf(const GLfloat *m) { + _commands.push_back(COMMAND_glLoadMatrixf); + _params.push_back(m); + + 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) { + 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) { + 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) { + 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) { + 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) { + 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::_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::_glEnableVertexArrayAttrib(GLint location) { + _commands.push_back(COMMAND_glEnableVertexArrayAttrib); + _params.push_back(location); +} +void Batch::do_glCullFace(int ¶mOffset) { + glCullFace(_params[paramOffset++]._uint); +} + +void Batch::_glDisableVertexArrayAttrib(GLint location) { + _commands.push_back(COMMAND_glDisableVertexArrayAttrib); + _params.push_back(location); +} +void Batch::do_glCullFace(int ¶mOffset) { + glCullFace(_params[paramOffset++]._uint); +} + +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); +} diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index 51e2ce61b6..a03c4ac1b7 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -47,10 +47,64 @@ public: void clear(); - void draw( Primitive primitiveType, int nbVertices, int startVertex = 0); - void drawIndexed( Primitive primitiveType, int nbIndices, int startIndex = 0 ); - void drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); - void drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); + void draw( Primitive primitiveType, int nbVertices, int startVertex = 0); + void drawIndexed( Primitive primitiveType, int nbIndices, int startIndex = 0 ); + void drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); + void drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); + + // 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 _glEnable(GLenum cap); + void _glDisable(GLenum cap); + + void _glEnableClientState(GLenum array); + void _glDisableClientState(GLenum array); + + void _glCullFace(GLenum mode); + void _glAlphaFunc(GLenum func, GLclampf ref); + + void _glDepthFunc(GLenum func); + void _glDepthMask(GLboolean flag); + void _glDepthRange(GLclampd zNear, GLclampd zFar); + + void _glBindBuffer(GLenum target, GLuint buffer); + + void _glBindTexture(GLenum target, GLuint texture); + void _glActiveTexture(GLenum texture); + + void _glDrawBuffers(GLsizei n, const GLenum* bufs); + + void _glUseProgram(GLuint program); + void _glUniform1f(GLint location, GLfloat v0); + void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + + void _glMatrixMode(GLenum mode); + void _glPushMatrix(); + void _glPopMatrix(); + void _glMultMatrixf(const GLfloat *m); + void _glLoadMatrixf(const GLfloat *m); + void _glLoadIdentity(void); + void _glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + void _glScalef(GLfloat x, GLfloat y, GLfloat z); + void _glTranslatef(GLfloat x, GLfloat y, GLfloat z); + + void _glDrawArrays(GLenum mode, GLint first, GLsizei count); + void _glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + + void _glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); + void _glNormalPointer(GLenum type, GLsizei stride, const void *pointer); + void _glTexCoordPointer(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 _glEnableVertexArrayAttrib(GLint location); + void _glDisableVertexArrayAttrib(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: @@ -67,18 +121,77 @@ protected: COMMAND_SET_VERTEX_STREAM, COMMAND_SET_INDEX_STREAM, - COMMAND_GL_SET_UNIFORM, - + // 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 + COMMAND_glEnable, + COMMAND_glDisable, + + COMMAND_glEnableClientState, + COMMAND_glDisableClientState, + + COMMAND_glCullFace, + COMMAND_glAlphaFunc, + + COMMAND_glDepthFunc, + COMMAND_glDepthMask, + COMMAND_glDepthRange, + + COMMAND_glBindBuffer, + + COMMAND_glBindTexture, + COMMAND_glActiveTexture, + + COMMAND_glDrawBuffers, + + COMMAND_glUseProgram, + COMMAND_glUniform1f, + COMMAND_glUniformMatrix4fv, + + COMMAND_glMatrixMode, + COMMAND_glPushMatrix, + COMMAND_glPopMatrix, + COMMAND_glMultMatrixf, + COMMAND_glLoadMatrixf, + COMMAND_glLoadIdentity, + COMMAND_glRotatef, + COMMAND_glScalef, + COMMAND_glTranslatef, + + COMMAND_glDrawArrays, + COMMAND_glDrawRangeElements, + + COMMAND_glColorPointer, + COMMAND_glNormalPointer, + COMMAND_glTexCoordPointer, + COMMAND_glVertexPointer, + + COMMAND_glVertexAttribPointer, + COMMAND_glEnableVertexArrayAttrib, + COMMAND_glDisableVertexArrayAttrib, + + COMMAND_glColor4f, + + COMMAND_glMaterialf, + COMMAND_glMaterialfv, }; typedef std::vector Commands; - - class Param { - public: - union { - uint32 _uint; - char _chars[4]; - }; - Param( uint32 val ): _uint(val) {} + + class Param { + public: + union { + int32 _int; + 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; @@ -91,6 +204,60 @@ protected: Commands _commands; Params _params; Resources _resources; + + // 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_glEnableClientState(int ¶mOffset); + void do_glDisableClientState(int ¶mOffset); + + void do_glCullFace(int ¶mOffset); + void do_glAlphaFunc(int ¶mOffset); + + void do_glDepthFunc(int ¶mOffset); + void do_glDepthMask(int ¶mOffset); + void do_glDepthRange(int ¶mOffset); + + void do_glBindBuffer(int ¶mOffset); + + void do_glBindTexture(int ¶mOffset); + void do_glActiveTexture(int ¶mOffset); + + void do_glDrawBuffers(int ¶mOffset); + + void do_glUseProgram(int ¶mOffset); + void do_glUniform1f(int ¶mOffset); + void do_glUniformMatrix4fv(int ¶mOffset); + + 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_glDrawArrays(int ¶mOffset); + void do_glDrawRangeElements(int ¶mOffset); + + void do_glColorPointer(int ¶mOffset); + void do_glNormalPointer(int ¶mOffset); + void do_glTexCoordPointer(int ¶mOffset); + void do_glVertexPointer(int ¶mOffset); + + void do_glVertexAttribPointer(int ¶mOffset); + void do_glEnableVertexArrayAttrib(int ¶mOffset); + void do_glDisableVertexArrayAttrib(int ¶mOffset); + + void do_glColor4f(int ¶mOffset); + + void do_glMaterialf(int ¶mOffset); + void do_glMaterialfv(int ¶mOffset); }; }; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 3800e78008..6032ae4d69 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -26,6 +26,9 @@ #include "Application.h" #include "Model.h" +#include "gpu/Batch.h" +#define GLBATCH( call ) batch._##call + using namespace std; static int modelPointerTypeId = qRegisterMetaType >(); @@ -1616,6 +1619,10 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, } activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); + // Try to use the Batch + gpu::Batch batch; + + // i is the "index" from the original networkMeshes QVector... foreach (int i, list) { @@ -1631,7 +1638,8 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, const NetworkMesh& networkMesh = networkMeshes.at(i); const FBXMesh& mesh = geometry.meshes.at(i); - const_cast(networkMesh.indexBuffer).bind(); + //const_cast(networkMesh.indexBuffer).bind(); + GLBATCH(glBindBuffer)( GL_INDEX_ARRAY, const_cast(networkMesh.indexBuffer).bufferId() ); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { @@ -1668,12 +1676,16 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, const_cast(networkMesh.vertexBuffer).bind(); - glPushMatrix(); - Application::getInstance()->loadTranslatedViewMatrix(_translation); + GLBATCH(glPushMatrix)(); + //Application::getInstance()->loadTranslatedViewMatrix(_translation); + GLBATCH(glLoadMatrixf)((const GLfloat*)&Application::getInstance()->getUntranslatedViewMatrix()); + glm::vec3 viewMatTranslation = Application::getInstance()->getViewMatrixTranslation(); + GLBATCH(glTranslatef)(_translation.x + viewMatTranslation.x, _translation.y + viewMatTranslation.y, + _translation.z + viewMatTranslation.z); const MeshState& state = _meshStates.at(i); if (state.clusterMatrices.size() > 1) { - glUniformMatrix4fvARB(skinLocations->clusterMatrices, state.clusterMatrices.size(), false, + GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false, (const float*)state.clusterMatrices.constData()); int offset = (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3) + mesh.texCoords.size() * sizeof(glm::vec2) + @@ -1684,7 +1696,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, skinProgram->enableAttributeArray(skinLocations->clusterIndices); skinProgram->enableAttributeArray(skinLocations->clusterWeights); } else { - glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]); + GLBATCH(glMultMatrixf)((const GLfloat*)&state.clusterMatrices[0]); } if (mesh.blendshapes.isEmpty()) { @@ -1692,9 +1704,9 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); activeProgram->enableAttributeArray(activeLocations->tangent); } - 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))); - glTexCoordPointer(2, GL_FLOAT, 0, (void*)(vertexCount * 2 * sizeof(glm::vec3) + + GLBATCH(glTexCoordPointer)(2, GL_FLOAT, 0, (void*)(vertexCount * 2 * sizeof(glm::vec3) + (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3))); } else { @@ -1702,20 +1714,20 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, 0, 3); activeProgram->enableAttributeArray(activeLocations->tangent); } - glColorPointer(3, GL_FLOAT, 0, (void*)(mesh.tangents.size() * sizeof(glm::vec3))); - glTexCoordPointer(2, GL_FLOAT, 0, (void*)((mesh.tangents.size() + mesh.colors.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))); _blendedVertexBuffers[i].bind(); } - glVertexPointer(3, GL_FLOAT, 0, 0); - glNormalPointer(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3))); + GLBATCH(glVertexPointer)(3, GL_FLOAT, 0, 0); + GLBATCH(glNormalPointer)(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3))); if (!mesh.colors.isEmpty()) { - glEnableClientState(GL_COLOR_ARRAY); + GLBATCH(glEnableClientState)(GL_COLOR_ARRAY); } else { - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GLBATCH(glColor4f)(1.0f, 1.0f, 1.0f, 1.0f); } if (!mesh.texCoords.isEmpty()) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + GLBATCH(glEnableClientState)(GL_TEXTURE_COORD_ARRAY); } qint64 offset = 0; @@ -1728,7 +1740,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, } // apply material properties if (mode == SHADOW_RENDER_MODE) { - glBindTexture(GL_TEXTURE_2D, 0); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); } else { if (dontReduceMaterialSwitches || lastMaterialID != part.materialID) { @@ -1741,36 +1753,36 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity); if (!(translucent && alphaThreshold == 0.0f)) { - glAlphaFunc(GL_EQUAL, diffuse.a = Application::getInstance()->getGlowEffect()->getIntensity()); + GLBATCH(glAlphaFunc)(GL_EQUAL, diffuse.a = Application::getInstance()->getGlowEffect()->getIntensity()); } glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); - glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); - glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular); - glMaterialf(GL_FRONT, GL_SHININESS, part.shininess); + GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); + GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, part.shininess); Texture* diffuseMap = networkPart.diffuseTexture.data(); if (mesh.isEye && diffuseMap) { diffuseMap = (_dilatedTextures[i][j] = static_cast(diffuseMap)->getDilatedTexture(_pupilDilation)).data(); } - glBindTexture(GL_TEXTURE_2D, !diffuseMap ? + GLBATCH(glBindTexture)(GL_TEXTURE_2D, !diffuseMap ? Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID()); if (!mesh.tangents.isEmpty()) { - glActiveTexture(GL_TEXTURE1); + GLBATCH(glActiveTexture)(GL_TEXTURE1); Texture* normalMap = networkPart.normalTexture.data(); - glBindTexture(GL_TEXTURE_2D, !normalMap ? + GLBATCH(glBindTexture)(GL_TEXTURE_2D, !normalMap ? Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID()); - glActiveTexture(GL_TEXTURE0); + GLBATCH(glActiveTexture)(GL_TEXTURE0); } if (specularTextureUnit) { - glActiveTexture(specularTextureUnit); + GLBATCH(glActiveTexture)(specularTextureUnit); Texture* specularMap = networkPart.specularTexture.data(); - glBindTexture(GL_TEXTURE_2D, !specularMap ? + GLBATCH(glBindTexture)(GL_TEXTURE_2D, !specularMap ? Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID()); - glActiveTexture(GL_TEXTURE0); + GLBATCH(glActiveTexture)(GL_TEXTURE0); } if (args) { args->_materialSwitches++; @@ -1783,12 +1795,12 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, meshPartsRendered++; if (part.quadIndices.size() > 0) { - glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset); + GLBATCH(glDrawRangeElements)(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset); offset += part.quadIndices.size() * sizeof(int); } if (part.triangleIndices.size() > 0) { - glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, part.triangleIndices.size(), + GLBATCH(glDrawRangeElements)(GL_TRIANGLES, 0, vertexCount - 1, part.triangleIndices.size(), GL_UNSIGNED_INT, (void*)offset); offset += part.triangleIndices.size() * sizeof(int); } @@ -1802,35 +1814,39 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, } if (!mesh.colors.isEmpty()) { - glDisableClientState(GL_COLOR_ARRAY); + GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); } if (!mesh.texCoords.isEmpty()) { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); } if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); + GLBATCH(glActiveTexture)(GL_TEXTURE1); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + GLBATCH(glActiveTexture)(GL_TEXTURE0); - activeProgram->disableAttributeArray(activeLocations->tangent); + // activeProgram->disableAttributeArray(activeLocations->tangent); + GLBATCH(glDisableVertexArrayAttrib)(activeLocations->tangent); } if (specularTextureUnit) { - glActiveTexture(specularTextureUnit); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); + GLBATCH(glActiveTexture)(specularTextureUnit); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + GLBATCH(glActiveTexture)(GL_TEXTURE0); } if (state.clusterMatrices.size() > 1) { - skinProgram->disableAttributeArray(skinLocations->clusterIndices); - skinProgram->disableAttributeArray(skinLocations->clusterWeights); + // skinProgram->disableAttributeArray(skinLocations->clusterIndices); + GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterIndices); + // skinProgram->disableAttributeArray(skinLocations->clusterWeights); + GLBATCH(glDisableVertexArrayAttrib)(skinLocations->clusterWeights); } - glPopMatrix(); + GLBATCH(glPopMatrix)(); } - activeProgram->release(); - + //activeProgram->release(); + GLBATCH(glUseProgram)(0); + return meshPartsRendered; } From 00dbe486d9339de11c00a51425081dfea97bae69 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 21 Oct 2014 10:50:53 -0700 Subject: [PATCH 4/7] 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; } From 821284edfd29b5b2aaaca75c6b50b6840d455739 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 21 Oct 2014 17:46:41 -0700 Subject: [PATCH 5/7] Introduce the gpu::Batch for the full Model::render call --- interface/src/gpu/Batch.cpp | 7 +- interface/src/gpu/Batch.h | 19 +--- interface/src/renderer/Model.cpp | 164 +++++++++++++++++++------------ interface/src/renderer/Model.h | 6 +- 4 files changed, 111 insertions(+), 85 deletions(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 9458dc8a3f..ddc5a9f24f 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -14,16 +14,15 @@ #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(), + _commandCalls(), + _commandOffsets(), _params(), _resources(), _data(){ @@ -34,6 +33,8 @@ Batch::~Batch() { void Batch::clear() { _commands.clear(); + _commandCalls.clear(); + _commandOffsets.clear(); _params.clear(); _resources.clear(); _data.clear(); diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index 815a7f61f2..567740511e 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -31,11 +31,6 @@ typedef int Stamp; typedef unsigned int uint32; typedef int int32; -// TODO: move the backend namespace into dedicated files, for now we keep it close to the gpu objects definition for convenience -namespace backend { - -}; - enum Primitive { PRIMITIVE_POINTS = 0, PRIMITIVE_LINES, @@ -226,7 +221,6 @@ protected: Resources _resources; Bytes _data; - uint32 cacheResource(Resource* res); uint32 cacheResource(const void* pointer); ResourceCache* editResource(uint32 offset) { @@ -246,22 +240,11 @@ protected: 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); + runCommand(index); } void runCommand(Command com, uint32 offset); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 765acdf797..739f5d75b1 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -28,6 +28,7 @@ #include "gpu/Batch.h" #define GLBATCH( call ) batch._##call +//#define GLBATCH( call ) call using namespace std; @@ -433,97 +434,135 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { segregateMeshGroups(); } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - glDisable(GL_COLOR_MATERIAL); + // Let's introduce a gpu::Batch to capture all the calls to the graphics api + gpu::Batch batch; + + GLBATCH(glEnableClientState)(GL_VERTEX_ARRAY); + GLBATCH(glEnableClientState)(GL_NORMAL_ARRAY); + + GLBATCH(glDisable)(GL_COLOR_MATERIAL); if (mode == DIFFUSE_RENDER_MODE || mode == NORMAL_RENDER_MODE) { - glDisable(GL_CULL_FACE); + GLBATCH(glDisable)(GL_CULL_FACE); } else { - glEnable(GL_CULL_FACE); + GLBATCH(glEnable)(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { - glCullFace(GL_FRONT); + GLBATCH(glCullFace)(GL_FRONT); } } // render opaque meshes with alpha testing - - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); + + GLBATCH(glDisable)(GL_BLEND); + GLBATCH(glEnable)(GL_ALPHA_TEST); if (mode == SHADOW_RENDER_MODE) { - glAlphaFunc(GL_EQUAL, 0.0f); + GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); } - - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + + + /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, mode == DEFAULT_RENDER_MODE); - + */ + { + GLenum buffers[3]; + int bufferCount = 0; + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + } + if (mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + } + if (mode == DEFAULT_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + } + GLBATCH(glDrawBuffers)(bufferCount, buffers); + } + const float DEFAULT_ALPHA_THRESHOLD = 0.5f; + //renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, book isSkinned, args); int opaqueMeshPartsRendered = 0; - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); - opaqueMeshPartsRendered += renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); + opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); + // render translucent meshes afterwards - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + { + GLenum buffers[2]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + GLBATCH(glDrawBuffers)(bufferCount, buffers); + } + int translucentMeshPartsRendered = 0; const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - - glDisable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - glDepthMask(false); - glDepthFunc(GL_LEQUAL); - - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); + + GLBATCH(glDisable)(GL_ALPHA_TEST); + GLBATCH(glEnable)(GL_BLEND); + GLBATCH(glDepthMask)(false); + GLBATCH(glDepthFunc)(GL_LEQUAL); + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + { + GLenum buffers[1]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + GLBATCH(glDrawBuffers)(bufferCount, buffers); + } + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); - translucentMeshPartsRendered += renderMeshes(mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); + translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); } - - glDepthMask(true); - glDepthFunc(GL_LESS); - glDisable(GL_CULL_FACE); + + GLBATCH(glDepthMask)(true); + GLBATCH(glDepthFunc)(GL_LESS); + GLBATCH(glDisable)(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { - glCullFace(GL_BACK); + GLBATCH(glCullFace)(GL_BACK); } - + // deactivate vertex arrays after drawing - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); + GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); + GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); // bind with 0 to switch back to normal operation - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - + GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); + GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + + // Render! + ::gpu::backend::renderBatch(batch); + batch.clear(); + // restore all the default material settings Application::getInstance()->setupWorldLight(); @@ -1509,7 +1548,7 @@ void Model::segregateMeshGroups() { _meshGroupsKnown = true; } -int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, +int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); @@ -1611,7 +1650,7 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, Locations* activeLocations = locations; // Try to use the Batch - gpu::Batch batch; + //gpu::Batch batch; /*if (isSkinned) { skinProgram->bind(); @@ -1868,7 +1907,6 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, //activeProgram->release(); GLBATCH(glUseProgram)(0); - ::gpu::backend::renderBatch(batch); return meshPartsRendered; } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 86fa0c2b7a..b6c9987807 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -36,6 +36,10 @@ class ViewFrustum; typedef QSharedPointer AnimationHandlePointer; typedef QWeakPointer WeakAnimationHandlePointer; +namespace gpu { + class Batch; +} + /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject, public PhysicsEntity { Q_OBJECT @@ -252,7 +256,7 @@ private: void applyNextGeometry(); void deleteGeometry(); - int renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL); + int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL); QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); From 86819b934439209cd9b662c8e35f67d7e061ac74 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 21 Oct 2014 18:03:53 -0700 Subject: [PATCH 6/7] fix endline on Batch.cpp --- interface/src/gpu/Batch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index ddc5a9f24f..945ccd4feb 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -621,4 +621,4 @@ void backend::renderBatch(Batch& batch) { for (int i = 0; i < batch._commands.size(); i++) { batch.runCommand(i); } -} \ No newline at end of file +} From 057c17fd2fa0641a1422fb5315f2b2f44647e3a8 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 21 Oct 2014 18:14:26 -0700 Subject: [PATCH 7/7] fix suseless spaces around parameters in functions --- interface/src/gpu/Batch.cpp | 8 ++++---- interface/src/gpu/Batch.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 945ccd4feb..8a094d1024 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -111,7 +111,7 @@ void Batch::runCommand(Command com, uint32 offset) { } } -void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { +void Batch::draw(Primitive primitiveType, int nbVertices, int startVertex) { ADD_COMMAND(draw); _params.push_back(startVertex); @@ -119,7 +119,7 @@ void Batch::draw( Primitive primitiveType, int nbVertices, int startVertex) { _params.push_back(primitiveType); } -void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) { +void Batch::drawIndexed(Primitive primitiveType, int nbIndices, int startIndex) { ADD_COMMAND(drawIndexed); _params.push_back(startIndex); @@ -127,7 +127,7 @@ void Batch::drawIndexed( Primitive primitiveType, int nbIndices, int startIndex) _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) { ADD_COMMAND(drawInstanced); _params.push_back(startInstance); @@ -137,7 +137,7 @@ void Batch::drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVe _params.push_back(nbInstances); } -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) { ADD_COMMAND(drawIndexedInstanced); _params.push_back(startInstance); diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index 567740511e..60c9c2d645 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -49,10 +49,10 @@ public: void clear(); - void draw( Primitive primitiveType, int nbVertices, int startVertex = 0); - void drawIndexed( Primitive primitiveType, int nbIndices, int startIndex = 0 ); - void drawInstanced( uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); - void drawIndexedInstanced( uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); + void draw(Primitive primitiveType, int nbVertices, int startVertex = 0); + void drawIndexed(Primitive primitiveType, int nbIndices, int startIndex = 0); + void drawInstanced(uint32 nbInstances, Primitive primitiveType, int nbVertices, int startVertex = 0, int startInstance = 0); + void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, int nbIndices, int startIndex = 0, int startInstance = 0); // 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