refining the shader pipeline and trying to pass a Status Getter from the model and fails

This commit is contained in:
Sam Gateau 2015-07-01 07:47:46 -07:00
parent 8bd5e15f73
commit 2f04a9d3da
9 changed files with 159 additions and 31 deletions

View file

@ -177,7 +177,22 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p
pendingChanges.resetItem(_myMetaItem, renderPayload);
if (_model) {
return _model->addToScene(scene, pendingChanges);
// return _model->addToScene(scene, pendingChanges);
render::Item::Status::Getter statusGetter = [this] () -> render::Item::Status::Value {
quint64 now = usecTimestampNow();
/* if (now - entity->getLastEditedFromRemote() < 0.1f * USECS_PER_SECOND) {
return glm::vec4 redColor(1.0f, 0.0f, 0.0f, 1.0f);
renderBoundingBox(entity, args, 0.16f, redColor);
}
*/
if (now - this->getLastBroadcast() < 0.2f * USECS_PER_SECOND) {
return 256;
}
return 0;
};
return _model->addToScene(scene, pendingChanges, statusGetter);
}
return true;

View file

@ -191,6 +191,18 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) {
}
void GLBackend::do_drawInstanced(Batch& batch, uint32 paramOffset) {
updateInput();
updateTransform();
updatePipeline();
GLint numInstances = batch._params[paramOffset + 4]._uint;
Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint;
GLenum mode = _primitiveToGLmode[primitiveType];
uint32 numVertices = batch._params[paramOffset + 2]._uint;
uint32 startVertex = batch._params[paramOffset + 1]._uint;
uint32 startInstance = batch._params[paramOffset + 0]._uint;
glDrawArraysInstanced(mode, startVertex, numVertices, numInstances);
(void) CHECK_GL_ERROR();
}

View file

@ -910,6 +910,38 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
return somethingAdded;
}
bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter) {
if (!_meshGroupsKnown && isLoadedWithTextures()) {
segregateMeshGroups();
}
bool somethingAdded = false;
foreach (auto renderItem, _transparentRenderItems) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData));
renderPayload->addStatusGetter(statusGetter);
pendingChanges.resetItem(item, renderPayload);
_renderItems.insert(item, renderPayload);
somethingAdded = true;
}
foreach (auto renderItem, _opaqueRenderItems) {
auto item = scene->allocateID();
auto renderData = MeshPartPayload::Pointer(renderItem);
auto renderPayload = render::PayloadPointer(new MeshPartPayload::Payload(renderData));
renderPayload->addStatusGetter(statusGetter);
pendingChanges.resetItem(item, renderPayload);
_renderItems.insert(item, renderPayload);
somethingAdded = true;
}
_readyWhenAdded = readyToAddToScene();
return somethingAdded;
}
void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
foreach (auto item, _renderItems.keys()) {
pendingChanges.removeItem(item);

View file

@ -118,6 +118,7 @@ public:
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoadedWithTextures(); }
bool addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
bool addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges, render::Item::Status::Getter& statusGetter);
void removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
/// Sets the URL of the model to render.

View file

@ -42,6 +42,9 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() {
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(true, false, gpu::LESS_EQUAL);
@ -66,6 +69,10 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemStatusPipeline() {
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
_drawItemStatusPosLoc = program->getUniforms().findLocation("inBoundPos");
_drawItemStatusDimLoc = program->getUniforms().findLocation("inBoundDim");
_drawItemStatusValueLoc = program->getUniforms().findLocation("inStatus");
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(false, false, gpu::LESS_EQUAL);
@ -85,7 +92,49 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
auto& scene = sceneContext->_scene;
// FIrst thing, we collect the bound and the status for all the items we want to render
int nbItems = 0;
{
if (!_itemBounds) {
_itemBounds.reset(new gpu::Buffer());
}
if (!_itemStatus) {
_itemStatus.reset(new gpu::Buffer());
}
_itemBounds->resize((inItems.size() * sizeof(AABox)));
_itemStatus->resize((inItems.size() * sizeof(glm::vec4)));
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
glm::vec4* itemStatus = reinterpret_cast<glm::vec4*> (_itemStatus->editData());
for (auto& item : inItems) {
if (!item.bounds.isInvalid()) {
if (!item.bounds.isNull()) {
(*itemAABox) = item.bounds;
} else {
(*itemAABox).setBox(item.bounds.getCorner(), 0.1f);
}
auto& itemScene = scene->getItem(item.id);
auto& status = itemScene.getStatus();
if (status) {
status->getValue((*itemStatus));
} else {
(*itemStatus) = glm::vec4(-1.0f);
}
nbItems++;
itemAABox++;
itemStatus++;
}
}
}
if (nbItems == 0) {
return;
}
// Allright, something to render let's do it
gpu::Batch batch;
glm::mat4 projMat;
@ -97,46 +146,40 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// batch.setModelTransform(Transform());
// bind the unit cube geometry
/* if (!_drawItemFormat) {
_drawItemFormat.reset(new gpu::Stream::Format());
_drawItemFormat->setAttribute(0, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0, gpu::Stream::PER_INSTANCE);
_drawItemFormat->setAttribute(1, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), sizeof(glm::vec3), gpu::Stream::PER_INSTANCE);
}
*/
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawItemBoundsPipeline());
for (auto& item : inItems) {
if (!item.bounds.isInvalid()) {
Transform model;
model.setTranslation(item.bounds.getCorner());
if (!item.bounds.isNull()) {
model.setScale(item.bounds.getDimensions());
}
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
glm::vec4* itemStatus = reinterpret_cast<glm::vec4*> (_itemStatus->editData());
batch.setModelTransform(model);
batch.draw(gpu::LINE_STRIP, 13, 0);
}
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const GLfloat*) (itemAABox + i));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3);
batch.draw(gpu::LINE_STRIP, 13, 0);
}
batch.setPipeline(getDrawItemStatusPipeline());
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const GLfloat*) (itemAABox + i));
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const GLfloat*) (itemAABox + i)) + 3);
batch._glUniform4fv(_drawItemStatusValueLoc, 1, (const GLfloat*) (itemStatus + i));
for (auto& item : inItems) {
if (!item.bounds.isInvalid()) {
Transform model;
model.setTranslation(item.bounds.getCorner());
if (!item.bounds.isNull()) {
model.setScale(item.bounds.getDimensions());
}
batch.setModelTransform(model);
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
}
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
}
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
renderContext->args->_context->syncCache();
args->_context->render((batch));
args->_batch = nullptr;
}

View file

@ -17,8 +17,17 @@
namespace render {
class DrawStatus {
int _drawItemBoundPosLoc = -1;
int _drawItemBoundDimLoc = -1;
int _drawItemStatusPosLoc = -1;
int _drawItemStatusDimLoc = -1;
int _drawItemStatusValueLoc = -1;
gpu::Stream::FormatPointer _drawItemFormat;
gpu::PipelinePointer _drawItemBoundsPipeline;
gpu::PipelinePointer _drawItemStatusPipeline;
gpu::BufferPointer _itemBounds;
gpu::BufferPointer _itemStatus;
public:

View file

@ -200,13 +200,22 @@ public:
// This is Used for monitoring and dynamically adjust the quality
class Status {
public:
typedef glm::ivec2 Value;
typedef unsigned char Value;
typedef std::function<Value()> Getter;
int _firstFrame;
std::vector<Getter> _values;
void addGetter(Getter& getter) { _values.push_back(getter); }
void getValue(glm::vec4& value) {
for (unsigned int i = 0; i < value.length(); i++) {
if (i < _values.size()) {
value[i] = _values[i]() / 256;
} else {
value[i] = 0.0f;
}
}
}
};
typedef std::shared_ptr<Status> StatusPointer;
@ -232,7 +241,7 @@ public:
// Status interface is local to the base class
const StatusPointer& getStatus() const { return _status; }
void addStatusGetter(Status::Getter& getter) { _status->addGetter(getter); }
void addStatusGetter(Status::Getter& getter) { if (!_status) { _status.reset(new Status());} _status->addGetter(getter); }
protected:
StatusPointer _status;

View file

@ -16,6 +16,9 @@
<$declareStandardTransform()$>
uniform vec3 inBoundPos;
uniform vec3 inBoundDim;
void main(void) {
const vec4 UNIT_BOX[13] = vec4[13](
vec4(0.0, 0.0, 0.0, 1.0),
@ -34,6 +37,8 @@ void main(void) {
);
vec4 pos = UNIT_BOX[gl_VertexID];
pos.xyz = inBoundPos + inBoundDim * pos.xyz;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();

View file

@ -18,7 +18,9 @@
varying vec4 varColor;
attribute vec4 inStatus;
uniform vec3 inBoundPos;
uniform vec3 inBoundDim;
uniform vec4 inStatus;
vec3 paintRainbow(float nv) {
float v = nv * 5.f;
@ -51,7 +53,7 @@ void main(void) {
varColor = vec4(paintRainbow(inStatus.x), 1.0);
vec4 anchorPoint = vec4(0.5, 0.5, 0.5, 1.0);
vec4 anchorPoint = vec4(inBoundPos, 1.0) + vec4(inBoundDim, 0.0) * vec4(0.5, 0.5, 0.5, 0.0);
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$>