mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 00:34: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);
|
||||
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)$>
|
||||
|
|
Loading…
Reference in a new issue