mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 10:54:26 +02:00
refining the shader pipeline and trying to pass a Status Getter from the model and fails
This commit is contained in:
parent
8bd5e15f73
commit
2f04a9d3da
9 changed files with 159 additions and 31 deletions
|
@ -177,7 +177,22 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p
|
||||||
pendingChanges.resetItem(_myMetaItem, renderPayload);
|
pendingChanges.resetItem(_myMetaItem, renderPayload);
|
||||||
|
|
||||||
if (_model) {
|
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;
|
return true;
|
||||||
|
|
|
@ -191,6 +191,18 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_drawInstanced(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();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -910,6 +910,38 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
|
||||||
return somethingAdded;
|
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) {
|
void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||||
foreach (auto item, _renderItems.keys()) {
|
foreach (auto item, _renderItems.keys()) {
|
||||||
pendingChanges.removeItem(item);
|
pendingChanges.removeItem(item);
|
||||||
|
|
|
@ -118,6 +118,7 @@ public:
|
||||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
||||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoadedWithTextures(); }
|
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);
|
||||||
|
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);
|
void removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||||
|
|
||||||
/// Sets the URL of the model to render.
|
/// Sets the URL of the model to render.
|
||||||
|
|
|
@ -42,6 +42,9 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() {
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
_drawItemBoundPosLoc = program->getUniforms().findLocation("inBoundPos");
|
||||||
|
_drawItemBoundDimLoc = program->getUniforms().findLocation("inBoundDim");
|
||||||
|
|
||||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||||
|
@ -66,6 +69,10 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemStatusPipeline() {
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
gpu::Shader::makeProgram(*program, 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());
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
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);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
RenderArgs* args = renderContext->args;
|
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;
|
gpu::Batch batch;
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
|
@ -97,46 +146,40 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
|
||||||
}
|
}
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
|
/* if (!_drawItemFormat) {
|
||||||
// batch.setModelTransform(Transform());
|
_drawItemFormat.reset(new gpu::Stream::Format());
|
||||||
// bind the unit cube geometry
|
_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
|
// bind the one gpu::Pipeline we need
|
||||||
batch.setPipeline(getDrawItemBoundsPipeline());
|
batch.setPipeline(getDrawItemBoundsPipeline());
|
||||||
|
|
||||||
for (auto& item : inItems) {
|
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
if (!item.bounds.isInvalid()) {
|
glm::vec4* itemStatus = reinterpret_cast<glm::vec4*> (_itemStatus->editData());
|
||||||
Transform model;
|
|
||||||
model.setTranslation(item.bounds.getCorner());
|
|
||||||
if (!item.bounds.isNull()) {
|
|
||||||
model.setScale(item.bounds.getDimensions());
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.setModelTransform(model);
|
for (int i = 0; i < nbItems; i++) {
|
||||||
batch.draw(gpu::LINE_STRIP, 13, 0);
|
|
||||||
}
|
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());
|
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) {
|
batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before rendering the batch make sure we re in sync with gl state
|
// Before rendering the batch make sure we re in sync with gl state
|
||||||
args->_context->syncCache();
|
args->_context->syncCache();
|
||||||
renderContext->args->_context->syncCache();
|
renderContext->args->_context->syncCache();
|
||||||
args->_context->render((batch));
|
args->_context->render((batch));
|
||||||
args->_batch = nullptr;
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,8 +17,17 @@
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
class DrawStatus {
|
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 _drawItemBoundsPipeline;
|
||||||
gpu::PipelinePointer _drawItemStatusPipeline;
|
gpu::PipelinePointer _drawItemStatusPipeline;
|
||||||
|
gpu::BufferPointer _itemBounds;
|
||||||
|
gpu::BufferPointer _itemStatus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -200,13 +200,22 @@ public:
|
||||||
// This is Used for monitoring and dynamically adjust the quality
|
// This is Used for monitoring and dynamically adjust the quality
|
||||||
class Status {
|
class Status {
|
||||||
public:
|
public:
|
||||||
typedef glm::ivec2 Value;
|
typedef unsigned char Value;
|
||||||
typedef std::function<Value()> Getter;
|
typedef std::function<Value()> Getter;
|
||||||
|
|
||||||
int _firstFrame;
|
int _firstFrame;
|
||||||
std::vector<Getter> _values;
|
std::vector<Getter> _values;
|
||||||
|
|
||||||
void addGetter(Getter& getter) { _values.push_back(getter); }
|
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;
|
typedef std::shared_ptr<Status> StatusPointer;
|
||||||
|
|
||||||
|
@ -232,7 +241,7 @@ public:
|
||||||
|
|
||||||
// Status interface is local to the base class
|
// Status interface is local to the base class
|
||||||
const StatusPointer& getStatus() const { return _status; }
|
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:
|
protected:
|
||||||
StatusPointer _status;
|
StatusPointer _status;
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
uniform vec3 inBoundPos;
|
||||||
|
uniform vec3 inBoundDim;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
const vec4 UNIT_BOX[13] = vec4[13](
|
const vec4 UNIT_BOX[13] = vec4[13](
|
||||||
vec4(0.0, 0.0, 0.0, 1.0),
|
vec4(0.0, 0.0, 0.0, 1.0),
|
||||||
|
@ -34,6 +37,8 @@ void main(void) {
|
||||||
);
|
);
|
||||||
vec4 pos = UNIT_BOX[gl_VertexID];
|
vec4 pos = UNIT_BOX[gl_VertexID];
|
||||||
|
|
||||||
|
pos.xyz = inBoundPos + inBoundDim * pos.xyz;
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
|
|
||||||
varying vec4 varColor;
|
varying vec4 varColor;
|
||||||
|
|
||||||
attribute vec4 inStatus;
|
uniform vec3 inBoundPos;
|
||||||
|
uniform vec3 inBoundDim;
|
||||||
|
uniform vec4 inStatus;
|
||||||
|
|
||||||
vec3 paintRainbow(float nv) {
|
vec3 paintRainbow(float nv) {
|
||||||
float v = nv * 5.f;
|
float v = nv * 5.f;
|
||||||
|
@ -51,7 +53,7 @@ void main(void) {
|
||||||
varColor = vec4(paintRainbow(inStatus.x), 1.0);
|
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();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$>
|
<$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$>
|
||||||
|
|
Loading…
Reference in a new issue