mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
Exposing the viewport to the shader and have a first draft of the draw status pipeline
This commit is contained in:
parent
20cb519c14
commit
8bd5e15f73
13 changed files with 198 additions and 5 deletions
|
@ -159,6 +159,12 @@ void Batch::setProjectionTransform(const Mat4& proj) {
|
|||
_params.push_back(cacheData(sizeof(Mat4), &proj));
|
||||
}
|
||||
|
||||
void Batch::setViewportTransform(const Vec4i& viewport) {
|
||||
ADD_COMMAND(setViewportTransform);
|
||||
|
||||
_params.push_back(cacheData(sizeof(Vec4i), &viewport));
|
||||
}
|
||||
|
||||
void Batch::setPipeline(const PipelinePointer& pipeline) {
|
||||
ADD_COMMAND(setPipeline);
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
void setModelTransform(const Transform& model);
|
||||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Mat4& proj);
|
||||
void setViewportTransform(const Vec4i& viewport); // Viewport is xy = low left corner in the framebuffer, zw = width height of the viewport
|
||||
|
||||
// Pipeline Stage
|
||||
void setPipeline(const PipelinePointer& pipeline);
|
||||
|
@ -177,6 +178,7 @@ public:
|
|||
COMMAND_setModelTransform,
|
||||
COMMAND_setViewTransform,
|
||||
COMMAND_setProjectionTransform,
|
||||
COMMAND_setViewportTransform,
|
||||
|
||||
COMMAND_setPipeline,
|
||||
COMMAND_setStateBlendFactor,
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef uint32 Offset;
|
|||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat3 Mat3;
|
||||
typedef glm::vec4 Vec4;
|
||||
typedef glm::ivec4 Vec4i;
|
||||
typedef glm::vec3 Vec3;
|
||||
typedef glm::vec2 Vec2;
|
||||
typedef glm::ivec2 Vec2i;
|
||||
|
|
|
@ -29,6 +29,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_setModelTransform),
|
||||
(&::gpu::GLBackend::do_setViewTransform),
|
||||
(&::gpu::GLBackend::do_setProjectionTransform),
|
||||
(&::gpu::GLBackend::do_setViewportTransform),
|
||||
|
||||
(&::gpu::GLBackend::do_setPipeline),
|
||||
(&::gpu::GLBackend::do_setStateBlendFactor),
|
||||
|
|
|
@ -96,7 +96,9 @@ public:
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
GLuint _transformObject_model = -1;
|
||||
GLuint _transformCamera_viewInverse = -1;
|
||||
GLuint _transformCamera_viewport = -1;
|
||||
#endif
|
||||
|
||||
GLShader();
|
||||
|
@ -267,7 +269,8 @@ protected:
|
|||
void do_setModelTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_setViewportTransform(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void initTransform();
|
||||
void killTransform();
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
|
@ -281,9 +284,11 @@ protected:
|
|||
Transform _model;
|
||||
Transform _view;
|
||||
Mat4 _projection;
|
||||
Vec4i _viewport;
|
||||
bool _invalidModel;
|
||||
bool _invalidView;
|
||||
bool _invalidProj;
|
||||
bool _invalidViewport;
|
||||
|
||||
GLenum _lastMode;
|
||||
|
||||
|
@ -296,6 +301,7 @@ protected:
|
|||
_invalidModel(true),
|
||||
_invalidView(true),
|
||||
_invalidProj(false),
|
||||
_invalidViewport(false),
|
||||
_lastMode(GL_TEXTURE) {}
|
||||
} _transform;
|
||||
|
||||
|
@ -329,7 +335,9 @@ protected:
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
GLint _program_transformObject_model = -1;
|
||||
GLint _program_transformCamera_viewInverse = -1;
|
||||
GLint _program_transformCamera_viewport = -1;
|
||||
#endif
|
||||
|
||||
State::Data _stateCache;
|
||||
|
|
|
@ -73,7 +73,9 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
_pipeline._program_transformObject_model = -1;
|
||||
_pipeline._program_transformCamera_viewInverse = -1;
|
||||
_pipeline._program_transformCamera_viewport = -1;
|
||||
#endif
|
||||
|
||||
_pipeline._state = nullptr;
|
||||
|
@ -91,7 +93,9 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
_pipeline._program_transformObject_model = pipelineObject->_program->_transformObject_model;
|
||||
_pipeline._program_transformCamera_viewInverse = pipelineObject->_program->_transformCamera_viewInverse;
|
||||
_pipeline._program_transformCamera_viewport = pipelineObject->_program->_transformCamera_viewport;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -143,10 +147,20 @@ void GLBackend::updatePipeline() {
|
|||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
#else
|
||||
// If shader program needs the model we need to provide it
|
||||
if (_pipeline._program_transformObject_model >= 0) {
|
||||
glUniformMatrix4fv(_pipeline._program_transformObject_model, 1, false, (const GLfloat*) &_transform._transformObject._model);
|
||||
}
|
||||
|
||||
// If shader program needs the inverseView we need to provide it
|
||||
if (_pipeline._program_transformCamera_viewInverse >= 0) {
|
||||
glUniformMatrix4fv(_pipeline._program_transformCamera_viewInverse, 1, false, (const GLfloat*) &_transform._transformCamera._viewInverse);
|
||||
}
|
||||
|
||||
// If shader program needs the viewport we need to provide it
|
||||
if (_pipeline._program_transformCamera_viewport >= 0) {
|
||||
glUniform4fv(_pipeline._program_transformCamera_viewport, 1, (const GLfloat*) &_transform._transformCamera._viewport);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -111,10 +111,20 @@ void makeBindings(GLBackend::GLShader* shader) {
|
|||
shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
||||
}
|
||||
#else
|
||||
loc = glGetUniformLocation(glprogram, "transformObject_model");
|
||||
if (loc >= 0) {
|
||||
shader->_transformObject_model = loc;
|
||||
}
|
||||
|
||||
loc = glGetUniformLocation(glprogram, "transformCamera_viewInverse");
|
||||
if (loc >= 0) {
|
||||
shader->_transformCamera_viewInverse = loc;
|
||||
}
|
||||
|
||||
loc = glGetUniformLocation(glprogram, "transformCamera_viewport");
|
||||
if (loc >= 0) {
|
||||
shader->_transformCamera_viewport = loc;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,12 @@ void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
|||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
void GLBackend::do_setViewportTransform(Batch& batch, uint32 paramOffset) {
|
||||
memcpy(&_transform._viewport, batch.editData(batch._params[paramOffset]._uint), sizeof(Vec4i));
|
||||
_transform._invalidViewport = true;
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::initTransform() {
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
glGenBuffers(1, &_transform._transformObjectBuffer);
|
||||
|
@ -57,10 +63,13 @@ void GLBackend::killTransform() {
|
|||
}
|
||||
|
||||
void GLBackend::syncTransformStateCache() {
|
||||
_transform._invalidViewport = true;
|
||||
_transform._invalidProj = true;
|
||||
_transform._invalidView = true;
|
||||
_transform._invalidModel = true;
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport);
|
||||
|
||||
GLint currentMode;
|
||||
glGetIntegerv(GL_MATRIX_MODE, ¤tMode);
|
||||
_transform._lastMode = currentMode;
|
||||
|
@ -78,6 +87,13 @@ void GLBackend::updateTransform() {
|
|||
GLint originalMatrixMode;
|
||||
glGetIntegerv(GL_MATRIX_MODE, &originalMatrixMode);
|
||||
// Check all the dirty flags and update the state accordingly
|
||||
if (_transform._invalidViewport) {
|
||||
_transform._transformCamera._viewport = glm::vec4(_transform._viewport);
|
||||
|
||||
// Where we assign the GL viewport
|
||||
glViewport(_transform._viewport.x, _transform._viewport.y, _transform._viewport.z, _transform._viewport.w);
|
||||
}
|
||||
|
||||
if (_transform._invalidProj) {
|
||||
_transform._transformCamera._projection = _transform._projection;
|
||||
_transform._transformCamera._projectionInverse = glm::inverse(_transform._projection);
|
||||
|
@ -100,7 +116,7 @@ void GLBackend::updateTransform() {
|
|||
}
|
||||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
|
||||
if (_transform._invalidView || _transform._invalidProj) {
|
||||
if (_transform._invalidView || _transform._invalidProj || _transform._invalidViewport) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW);
|
||||
|
@ -162,7 +178,8 @@ void GLBackend::updateTransform() {
|
|||
#endif
|
||||
|
||||
// Flags are clean
|
||||
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = false;
|
||||
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = _transform._invalidViewport = false;
|
||||
|
||||
glMatrixMode(originalMatrixMode);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,10 +87,18 @@ TransformCamera getTransformCamera() {
|
|||
}
|
||||
|
||||
uniform mat4 transformCamera_viewInverse;
|
||||
uniform vec4 transformCamera_viewport;
|
||||
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformCameraViewport(cameraTransform, viewport)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
<$viewport$> = <$cameraTransform$>._viewport;
|
||||
<@else@>
|
||||
<$viewport$> = transformCamera_viewport;
|
||||
<@endif@>
|
||||
<@endfunc@>
|
||||
|
||||
<@func transformModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@>
|
||||
<@if GPU_TRANSFORM_PROFILE == GPU_CORE@>
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "drawItemBounds_vert.h"
|
||||
#include "drawItemBounds_frag.h"
|
||||
#include "drawItemStatus_vert.h"
|
||||
#include "drawItemStatus_frag.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
@ -55,6 +57,30 @@ const gpu::PipelinePointer& DrawStatus::getDrawItemBoundsPipeline() {
|
|||
return _drawItemBoundsPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DrawStatus::getDrawItemStatusPipeline() {
|
||||
if (!_drawItemStatusPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(drawItemStatus_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawItemStatus_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_drawItemStatusPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
return _drawItemStatusPipeline;
|
||||
}
|
||||
|
||||
void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
@ -92,6 +118,21 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
|
|||
}
|
||||
}
|
||||
|
||||
batch.setPipeline(getDrawItemStatusPipeline());
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Before rendering the batch make sure we re in sync with gl state
|
||||
args->_context->syncCache();
|
||||
renderContext->args->_context->syncCache();
|
||||
|
|
|
@ -14,12 +14,11 @@
|
|||
|
||||
#include "DrawTask.h"
|
||||
#include "gpu/Batch.h"
|
||||
#include <PerfStat.h>
|
||||
|
||||
|
||||
namespace render {
|
||||
class DrawStatus {
|
||||
gpu::PipelinePointer _drawItemBoundsPipeline;
|
||||
gpu::PipelinePointer _drawItemStatusPipeline;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -28,6 +27,7 @@ namespace render {
|
|||
typedef Job::ModelI<DrawStatus, ItemIDsBounds> JobModel;
|
||||
|
||||
const gpu::PipelinePointer& getDrawItemBoundsPipeline();
|
||||
const gpu::PipelinePointer& getDrawItemStatusPipeline();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
19
libraries/render/src/render/drawItemStatus.slf
Normal file
19
libraries/render/src/render/drawItemStatus.slf
Normal file
|
@ -0,0 +1,19 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// drawItemStatus.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/30/15.
|
||||
// Copyright 2015 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
|
||||
//
|
||||
|
||||
varying vec4 varColor;
|
||||
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = varColor;
|
||||
}
|
66
libraries/render/src/render/drawItemStatus.slv
Normal file
66
libraries/render/src/render/drawItemStatus.slv
Normal file
|
@ -0,0 +1,66 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// drawItemStatus.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Sam Gateau on 6/30/2015.
|
||||
// Copyright 2015 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 gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec4 varColor;
|
||||
|
||||
attribute vec4 inStatus;
|
||||
|
||||
vec3 paintRainbow(float nv) {
|
||||
float v = nv * 5.f;
|
||||
if ( v < 0.f )
|
||||
return vec3(1.f, 0.f, 0.f);
|
||||
else if ( v < 1.f)
|
||||
return vec3(1.f, v, 0.f);
|
||||
else if ( v < 2.f)
|
||||
return vec3(1.f - (v-1.f), 1.f, 0.f);
|
||||
else if ( v < 3.f)
|
||||
return vec3(0.f, 1.f, (v-2.f));
|
||||
else if ( v < 4.f)
|
||||
return vec3(0.f, 1.f - (v-3.f), 1.f );
|
||||
else if ( v < 5.f)
|
||||
return vec3((v-4.f), 0.f, 1.f );
|
||||
else
|
||||
return vec3(1.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
const vec2 ICON_PIXEL_SIZE = vec2(10, 10);
|
||||
const vec4 UNIT_QUAD[4] = vec4[4](
|
||||
vec4(-1.0, -1.0, 0.0, 1.0),
|
||||
vec4(1.0, -1.0, 0.0, 1.0),
|
||||
vec4(-1.0, 1.0, 0.0, 1.0),
|
||||
vec4(1.0, 1.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
// Use the status for showing a color ?
|
||||
varColor = vec4(paintRainbow(inStatus.x), 1.0);
|
||||
|
||||
|
||||
vec4 anchorPoint = vec4(0.5, 0.5, 0.5, 1.0);
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, anchorPoint, anchorPoint)$>
|
||||
|
||||
vec4 pos = UNIT_QUAD[gl_VertexID];
|
||||
|
||||
vec4 viewport;
|
||||
<$transformCameraViewport(cam, viewport)$>;
|
||||
vec2 clipIconSize = vec2(ICON_PIXEL_SIZE.x / viewport.z, ICON_PIXEL_SIZE.y / viewport.w);
|
||||
|
||||
gl_Position = anchorPoint + anchorPoint.w * vec4(pos.xy * clipIconSize, 0.0, 0.0);
|
||||
}
|
Loading…
Reference in a new issue