Merge branch 'master' into 20630

This commit is contained in:
David Rowe 2015-07-23 09:46:20 -07:00
commit 68254c1ff0
36 changed files with 652 additions and 463 deletions

View file

@ -1175,13 +1175,22 @@ void OctreeServer::aboutToFinish() {
if (_jurisdictionSender) {
_jurisdictionSender->terminating();
}
QSet<SharedNodePointer> nodesToShutdown;
// force a shutdown of all of our OctreeSendThreads - at this point it has to be impossible for a
// linkedDataCreateCallback to be called for a new node
nodeList->eachNode([this](const SharedNodePointer& node) {
// Force a shutdown of all of our OctreeSendThreads.
// At this point it has to be impossible for a linkedDataCreateCallback to be called for a new node
nodeList->eachNode([&nodesToShutdown](const SharedNodePointer& node) {
nodesToShutdown << node;
});
// What follows is a hack to force OctreeSendThreads to cleanup before the OctreeServer is gone.
// I would prefer to allow the SharedNodePointer ref count drop to zero to do this automatically
// but that isn't possible as long as the OctreeSendThread has an OctreeServer* that it uses.
for (auto& node : nodesToShutdown) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
forceNodeShutdown(node);
});
}
if (_persistThread) {
_persistThread->aboutToFinish();

View file

@ -16,3 +16,4 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")

View file

@ -10,15 +10,16 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// The area over which the birds will fly
var lowerCorner = { x: 1, y: 1, z: 1 };
var upperCorner = { x: 10, y: 10, z: 10 };
// The rectangular area in the domain where the flock will fly
var lowerCorner = { x: 0, y: 0, z: 0 };
var upperCorner = { x: 10, y: 10, z: 10 };
var STARTING_FRACTION = 0.25;
var NUM_BIRDS = 50;
var UPDATE_INTERVAL = 0.016;
var playSounds = true;
var SOUND_PROBABILITY = 0.001;
var STARTING_LIFETIME = (1.0 / SOUND_PROBABILITY) * UPDATE_INTERVAL * 10;
var numPlaying = 0;
var BIRD_SIZE = 0.08;
var BIRD_MASTER_VOLUME = 0.1;
@ -35,6 +36,10 @@ var ALIGNMENT_FORCE = 1.5;
var COHESION_FORCE = 1.0;
var MAX_COHESION_VELOCITY = 0.5;
var followBirds = true;
var AVATAR_FOLLOW_RATE = 0.001;
var AVATAR_FOLLOW_VELOCITY_TIMESCALE = 2.0;
var AVATAR_FOLLOW_ORIENTATION_RATE = 0.005;
var floor = false;
var MAKE_FLOOR = false;
@ -43,6 +48,9 @@ var averagePosition = { x: 0, y: 0, z: 0 };
var birdsLoaded = false;
var oldAvatarOrientation;
var oldAvatarPosition;
var birds = [];
var playing = [];
@ -115,8 +123,9 @@ function updateBirds(deltaTime) {
birds[i].audioId = Audio.playSound(birds[i].sound, options);
}
numPlaying++;
// Change size
Entities.editEntity(birds[i].entityId, { dimensions: Vec3.multiply(1.5, properties.dimensions)});
// Change size, and update lifetime to keep bird alive
Entities.editEntity(birds[i].entityId, { dimensions: Vec3.multiply(1.5, properties.dimensions),
lifetime: properties.ageInSeconds + STARTING_LIFETIME});
} else if (birds[i].audioId) {
// If bird is playing a chirp
@ -166,10 +175,24 @@ function updateBirds(deltaTime) {
if (birdVelocitiesCounted > 0) {
averageVelocity = Vec3.multiply(1.0 / birdVelocitiesCounted, sumVelocity);
//print(Vec3.length(averageVelocity));
if (followBirds) {
MyAvatar.motorVelocity = averageVelocity;
MyAvatar.motorTimescale = AVATAR_FOLLOW_VELOCITY_TIMESCALE;
var polarAngles = Vec3.toPolar(Vec3.normalize(averageVelocity));
if (!isNaN(polarAngles.x) && !isNaN(polarAngles.y)) {
var birdDirection = Quat.fromPitchYawRollRadians(polarAngles.x, polarAngles.y + Math.PI, polarAngles.z);
MyAvatar.orientation = Quat.mix(MyAvatar.orientation, birdDirection, AVATAR_FOLLOW_ORIENTATION_RATE);
}
}
}
if (birdPositionsCounted > 0) {
averagePosition = Vec3.multiply(1.0 / birdPositionsCounted, sumPosition);
// If Following birds, update position
if (followBirds) {
MyAvatar.position = Vec3.sum(Vec3.multiply(AVATAR_FOLLOW_RATE, MyAvatar.position), Vec3.multiply(1.0 - AVATAR_FOLLOW_RATE, averagePosition));
}
}
}
// Connect a call back that happens every frame
@ -183,11 +206,14 @@ Script.scriptEnding.connect(function() {
if (floor) {
Entities.deleteEntity(floor);
}
MyAvatar.orientation = oldAvatarOrientation;
MyAvatar.position = oldAvatarPosition;
});
function loadBirds(howMany) {
while (!Entities.serversExist() || !Entities.canRez()) {
}
oldAvatarOrientation = MyAvatar.orientation;
oldAvatarPosition = MyAvatar.position;
var sound_filenames = ["bushtit_1.raw", "bushtit_2.raw", "bushtit_3.raw"];
/* Here are more sounds/species you can use
, "mexicanWhipoorwill.raw",
@ -247,6 +273,7 @@ function loadBirds(howMany) {
velocity: { x: 0, y: -0.1, z: 0 },
linearDamping: LINEAR_DAMPING,
collisionsWillMove: true,
lifetime: STARTING_LIFETIME,
color: colors[whichBird]
}),
audioId: false,

View file

@ -318,11 +318,15 @@ var toolBar = (function () {
print("Resize failed: timed out waiting for model (" + url + ") to load");
}
} else {
entityProperties.dimensions = naturalDimensions;
Entities.editEntity(entityId, entityProperties);
Entities.editEntity(entityId, { dimensions: naturalDimensions });
// Reset selection so that the selection overlays will be updated
selectionManager.setSelections([entityId]);
}
}
selectionManager.setSelections([entityId]);
Script.setTimeout(resize, RESIZE_INTERVAL);
} else {
print("Can't add model: Model would be out of bounds.");

View file

@ -9,11 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <sstream>
#include "Application.h"
#include <stdlib.h>
#include <cmath>
#include <math.h>
#include <sstream>
#include <glm/glm.hpp>
#include <glm/gtx/component_wise.hpp>
@ -61,6 +59,7 @@
#include <DependencyManager.h>
#include <EntityScriptingInterface.h>
#include <ErrorDialog.h>
#include <FramebufferCache.h>
#include <gpu/Batch.h>
#include <gpu/Context.h>
#include <gpu/GLBackend.h>
@ -87,12 +86,12 @@
#include <SettingHandle.h>
#include <SimpleAverage.h>
#include <SoundCache.h>
#include <TextureCache.h>
#include <Tooltip.h>
#include <UserActivityLogger.h>
#include <UUID.h>
#include <VrMenu.h>
#include "Application.h"
#include "AudioClient.h"
#include "DiscoverabilityManager.h"
#include "GLCanvas.h"
@ -266,6 +265,8 @@ bool setupEssentials(int& argc, char** argv) {
auto audioScope = DependencyManager::set<AudioScope>();
auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
auto textureCache = DependencyManager::set<TextureCache>();
auto framebufferCache = DependencyManager::set<FramebufferCache>();
auto animationCache = DependencyManager::set<AnimationCache>();
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
auto modelBlender = DependencyManager::set<ModelBlender>();
@ -732,6 +733,7 @@ Application::~Application() {
DependencyManager::destroy<OffscreenUi>();
DependencyManager::destroy<AvatarManager>();
DependencyManager::destroy<AnimationCache>();
DependencyManager::destroy<FramebufferCache>();
DependencyManager::destroy<TextureCache>();
DependencyManager::destroy<GeometryCache>();
DependencyManager::destroy<ScriptCache>();
@ -765,32 +767,8 @@ void Application::initializeGL() {
}
#endif
qCDebug(interfaceapp) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
qCDebug(interfaceapp) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
qCDebug(interfaceapp) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR));
qCDebug(interfaceapp) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER));
#ifdef WIN32
GLenum err = glewInit();
if (GLEW_OK != err) {
/* Problem: glewInit failed, something is seriously wrong. */
qCDebug(interfaceapp, "Error: %s\n", glewGetErrorString(err));
}
qCDebug(interfaceapp, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
if (wglewGetExtension("WGL_EXT_swap_control")) {
int swapInterval = wglGetSwapIntervalEXT();
qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF"));
}
#endif
#if defined(Q_OS_LINUX)
// TODO: Write the correct code for Linux...
/* if (wglewGetExtension("WGL_EXT_swap_control")) {
int swapInterval = wglGetSwapIntervalEXT();
qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF"));
}*/
#endif
// Where the gpuContext is created and where the TRUE Backend is created and assigned
_gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend());
initDisplay();
qCDebug(interfaceapp, "Initialized Display.");
@ -879,8 +857,9 @@ void Application::paintGL() {
_glWidget->makeCurrent();
auto lodManager = DependencyManager::get<LODManager>();
gpu::Context context(new gpu::GLBackend());
RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
RenderArgs renderArgs(_gpuContext, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
@ -896,18 +875,17 @@ void Application::paintGL() {
PerformanceWarning warn(showWarnings, "Application::paintGL()");
resizeGL();
{
PerformanceTimer perfTimer("renderOverlay");
// NOTE: There is no batch associated with this renderArgs
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
QSize size = qApp->getDeviceSize();
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
_applicationOverlay.renderOverlay(&renderArgs);
}
glEnable(GL_LINE_SMOOTH);
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
@ -958,7 +936,6 @@ void Application::paintGL() {
}
// Sync up the View Furstum with the camera
// FIXME: it's happening again in the updateSHadow and it shouldn't, this should be the place
loadViewFrustum(_myCamera, _viewFrustum);
@ -978,18 +955,18 @@ void Application::paintGL() {
{
gpu::Batch batch;
auto primaryFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_COLOR1 |
gpu::Framebuffer::BUFFER_COLOR2 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0);
// Viewport is assigned to the size of the framebuffer
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
batch.setViewportTransform(renderArgs._viewport);
renderArgs._context->render(batch);
@ -997,7 +974,7 @@ void Application::paintGL() {
displaySide(&renderArgs, _myCamera);
if (_myCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
renderRearViewMirror(&renderArgs, _mirrorViewRect);
renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
@ -1005,7 +982,7 @@ void Application::paintGL() {
{
auto geometryCache = DependencyManager::get<GeometryCache>();
auto primaryFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
gpu::Batch batch;
batch.blit(primaryFbo, glm::ivec4(0, 0, _renderResolution.x, _renderResolution.y),
nullptr, glm::ivec4(0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height()));
@ -1079,7 +1056,7 @@ void Application::resizeGL() {
if (_renderResolution != toGlm(renderSize)) {
_renderResolution = toGlm(renderSize);
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(renderSize);
loadViewFrustum(_myCamera, _viewFrustum);
}
@ -1821,6 +1798,13 @@ void Application::idle() {
}
double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0;
if (timeSinceLastUpdate > targetFramePeriod) {
{
static const int IDLE_EVENT_PROCESS_MAX_TIME_MS = 2;
PerformanceTimer perfTimer("processEvents");
processEvents(QEventLoop::AllEvents, IDLE_EVENT_PROCESS_MAX_TIME_MS);
}
_lastTimeUpdated.start();
{
PerformanceTimer perfTimer("update");
@ -1845,11 +1829,19 @@ void Application::idle() {
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
_idleLoopStdev.reset();
}
}
// After finishing all of the above work, ensure the idle timer is set to the proper interval,
// depending on whether we're throttling or not
idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1);
// depending on whether we're throttling or not.
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
// perpetuity and not expect events to get backed up.
static const int IDLE_TIMER_DELAY_MS = 0;
int desiredInterval = _glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
if (idleTimer->interval() != desiredInterval) {
idleTimer->start(desiredInterval);
}
}
// check for any requested background downloads.
@ -2981,7 +2973,7 @@ PickRay Application::computePickRay(float x, float y) const {
}
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFramebuffer = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
// clear the alpha channel so the background is transparent
@ -3172,10 +3164,6 @@ namespace render {
model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
}
}
// FIX ME - If I don't call this renderBatch() here, then the atmosphere and skybox don't render, but it
// seems like these payloadRender() methods shouldn't be doing this. We need to investigate why the engine
// isn't rendering our batch
gpu::GLBackend::renderBatch(batch, true);
}
}
@ -3416,11 +3404,11 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
// set the bounds of rear mirror view
gpu::Vec4i viewport;
if (billboard) {
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
viewport = gpu::Vec4i(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
} else {
// if not rendering the billboard, the region is in device independent coordinates; must convert to device
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio;
viewport = gpu::Vec4i(x, size.height() - y - height, width, height);
@ -3441,10 +3429,6 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
renderArgs->_context->render(batch);
}
bool updateViewFrustum = false;
loadViewFrustum(_mirrorCamera, _viewFrustum);
// render rear mirror view
displaySide(renderArgs, _mirrorCamera, true, billboard);
@ -4474,7 +4458,11 @@ void Application::friendsWindowClosed() {
}
void Application::postLambdaEvent(std::function<void()> f) {
QCoreApplication::postEvent(this, new LambdaEvent(f));
if (this->thread() == QThread::currentThread()) {
f();
} else {
QCoreApplication::postEvent(this, new LambdaEvent(f));
}
}
void Application::initPlugins() {

View file

@ -34,7 +34,6 @@
#include <ScriptEngine.h>
#include <ShapeManager.h>
#include <StDev.h>
#include <TextureCache.h>
#include <udt/PacketHeaders.h>
#include <ViewFrustum.h>
@ -69,6 +68,7 @@
#include "octree/OctreePacketProcessor.h"
#include "UndoStackScriptingInterface.h"
#include "gpu/Context.h"
#include "render/Engine.h"
class QGLWidget;
@ -326,6 +326,8 @@ public:
render::ScenePointer getMain3DScene() const { return _main3DScene; }
gpu::ContextPointer getGPUContext() const { return _gpuContext; }
signals:
/// Fired when we're simulating; allows external parties to hook in.
@ -482,6 +484,7 @@ private:
glm::vec3 getSunDirection();
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false);
void setMenuShortcutsEnabled(bool enabled);
static void attachNewHeadToNode(Node *newNode);
@ -632,6 +635,7 @@ private:
render::ScenePointer _main3DScene{ new render::Scene() };
render::EnginePointer _renderEngine{ new render::Engine() };
gpu::ContextPointer _gpuContext; // initialized during window creation
Overlays _overlays;
ApplicationOverlay _applicationOverlay;

View file

@ -14,7 +14,7 @@
#include <mutex>
#include <QElapsedTimer>
#include <gpu/GPUConfig.h>
#include <gpu/Batch.h>
#include <gpu/Context.h>
#include <NumericalConstants.h>
@ -24,14 +24,17 @@
#include <RenderArgs.h>
#include <ViewFrustum.h>
#include "../../libraries/render-utils/standardTransformPNTC_vert.h"
#include "../../libraries/render-utils/stars_vert.h"
#include "../../libraries/render-utils/stars_frag.h"
#include "../../libraries/render-utils/standardTransformPNTC_vert.h"
#include "../../libraries/render-utils/starsGrid_frag.h"
//static const float TILT = 0.23f;
static const float TILT = 0.0f;
static const unsigned int STARFIELD_NUM_STARS = 50000;
static const unsigned int STARFIELD_SEED = 1;
//static const float STAR_COLORIZATION = 0.1f;
static const float STAR_COLORIZATION = 0.1f;
static const float TAU = 6.28318530717958f;
//static const float HALF_TAU = TAU / 2.0f;
@ -109,52 +112,81 @@ unsigned computeStarColor(float colorization) {
return red | (green << 8) | (blue << 16);
}
struct StarVertex {
vec4 position;
vec4 colorAndSize;
};
// FIXME star colors
void Stars::render(RenderArgs* renderArgs, float alpha) {
static gpu::BufferPointer vertexBuffer;
static gpu::Stream::FormatPointer streamFormat;
static gpu::Element positionElement, colorElement;
static gpu::PipelinePointer _pipeline;
static gpu::PipelinePointer _gridPipeline;
static gpu::PipelinePointer _starsPipeline;
static int32_t _timeSlot{ -1 };
static std::once_flag once;
const int VERTICES_SLOT = 0;
//const int COLOR_SLOT = 2;
const int COLOR_SLOT = 1;
std::call_once(once, [&] {
{
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(standardTransformPNTC_vert)));
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(starsGrid_frag)));
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
gpu::Shader::makeProgram((*program));
_timeSlot = program->getBuffers().findLocation(UNIFORM_TIME_NAME);
if (_timeSlot == gpu::Shader::INVALID_LOCATION) {
_timeSlot = program->getUniforms().findLocation(UNIFORM_TIME_NAME);
}
auto state = gpu::StatePointer(new gpu::State());
// enable decal blend
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
_gridPipeline.reset(gpu::Pipeline::create(program, state));
}
{
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(stars_vert)));
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(stars_frag)));
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
gpu::Shader::makeProgram((*program));
auto state = gpu::StatePointer(new gpu::State());
// enable decal blend
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
_starsPipeline.reset(gpu::Pipeline::create(program, state));
}
QElapsedTimer startTime;
startTime.start();
vertexBuffer.reset(new gpu::Buffer);
srand(STARFIELD_SEED);
unsigned limit = STARFIELD_NUM_STARS;
std::vector<vec3> points;
std::vector<StarVertex> points;
points.resize(limit);
for (size_t star = 0; star < limit; ++star) {
points[star] = fromPolar(randPolar());
//auto color = computeStarColor(STAR_COLORIZATION);
//vertexBuffer->append(sizeof(color), (const gpu::Byte*)&color);
points[star].position = vec4(fromPolar(randPolar()), 1);
float size = frand() * 2.5f + 0.5f;
if (frand() < STAR_COLORIZATION) {
vec3 color(frand() / 2.0f + 0.5f, frand() / 2.0f + 0.5f, frand() / 2.0f + 0.5f);
points[star].colorAndSize = vec4(color, size);
} else {
vec3 color(frand() / 2.0f + 0.5f);
points[star].colorAndSize = vec4(color, size);
}
}
vertexBuffer->append(sizeof(vec3) * limit, (const gpu::Byte*)&points[0]);
streamFormat.reset(new gpu::Stream::Format()); // 1 for everyone
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
double timeDiff = (double)startTime.nsecsElapsed() / 1000000.0; // ns to ms
qDebug() << "Total time to generate stars: " << timeDiff << " msec";
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(standardTransformPNTC_vert)));
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(stars_frag)));
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
gpu::Shader::makeProgram((*program));
_timeSlot = program->getBuffers().findLocation(UNIFORM_TIME_NAME);
if (_timeSlot == gpu::Shader::INVALID_LOCATION) {
_timeSlot = program->getUniforms().findLocation(UNIFORM_TIME_NAME);
}
auto state = gpu::StatePointer(new gpu::State());
// enable decal blend
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
_pipeline.reset(gpu::Pipeline::create(program, state));
vertexBuffer->append(sizeof(StarVertex) * limit, (const gpu::Byte*)&points[0]);
streamFormat.reset(new gpu::Stream::Format()); // 1 for everyone
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW), 0);
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::RGBA));
positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
});
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -168,18 +200,31 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
batch.setResourceTexture(0, textureCache->getWhiteTexture());
// Render the world lines
batch.setPipeline(_pipeline);
batch.setPipeline(_gridPipeline);
static auto start = usecTimestampNow();
float msecs = (float)(usecTimestampNow() - start) / (float)USECS_PER_MSEC;
float secs = msecs / (float)MSECS_PER_SECOND;
batch._glUniform1f(_timeSlot, secs);
geometryCache->renderUnitCube(batch);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
static const size_t VERTEX_STRIDE = sizeof(StarVertex);
size_t offset = offsetof(StarVertex, position);
gpu::BufferView posView(vertexBuffer, offset, vertexBuffer->getSize(), VERTEX_STRIDE, positionElement);
offset = offsetof(StarVertex, colorAndSize);
gpu::BufferView colView(vertexBuffer, offset, vertexBuffer->getSize(), VERTEX_STRIDE, colorElement);
// Render the stars
geometryCache->useSimpleDrawPipeline(batch);
batch.setPipeline(_starsPipeline);
batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT);
batch._glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
batch._glEnable(GL_POINT_SMOOTH);
batch.setInputFormat(streamFormat);
batch.setInputBuffer(VERTICES_SLOT, gpu::BufferView(vertexBuffer, positionElement));
batch.setInputBuffer(VERTICES_SLOT, posView);
batch.setInputBuffer(COLOR_SLOT, colView);
batch.draw(gpu::Primitive::POINTS, STARFIELD_NUM_STARS);
renderArgs->_context->render(batch);
}

View file

@ -316,15 +316,14 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::S
}
}
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
if (_referential) {
_referential->update();
}
auto& batch = *renderArgs->_batch;
if (postLighting &&
glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
auto geometryCache = DependencyManager::get<GeometryCache>();
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
@ -414,9 +413,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
: GLOW_FROM_AVERAGE_LOUDNESS;
// render body
renderBody(renderArgs, frustum, postLighting, glowLevel);
renderBody(renderArgs, frustum, glowLevel);
if (!postLighting && renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
// add local lights
const float BASE_LIGHT_DISTANCE = 2.0f;
const float LIGHT_EXPONENT = 1.0f;
@ -431,21 +430,17 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
}
}
if (postLighting) {
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
if (renderSkeleton) {
_skeletonModel.renderJointCollisionShapes(0.7f);
}
if (renderHead && shouldRenderHead(renderArgs)) {
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
}
if (renderBounding && shouldRenderHead(renderArgs)) {
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
}
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
if (renderSkeleton) {
_skeletonModel.renderJointCollisionShapes(0.7f);
}
if (renderHead && shouldRenderHead(renderArgs)) {
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
}
if (renderBounding && shouldRenderHead(renderArgs)) {
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
}
// If this is the avatar being looked at, render a little ball above their head
@ -583,24 +578,20 @@ void Avatar::fixupModelsInScene() {
scene->enqueuePendingChanges(pendingChanges);
}
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
fixupModelsInScene();
{
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
if (postLighting || renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
// render the billboard until both models are loaded
renderBillboard(renderArgs);
}
// render the billboard until both models are loaded
renderBillboard(renderArgs);
return;
}
if (postLighting) {
getHand()->render(renderArgs, false);
}
getHand()->render(renderArgs, false);
}
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
getHead()->render(renderArgs, 1.0f, renderFrustum);
}
bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {

View file

@ -81,8 +81,7 @@ public:
void init();
void simulate(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition,
bool postLighting = false);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition);
bool addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene,
render::PendingChanges& pendingChanges);
@ -235,7 +234,7 @@ protected:
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const;
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const;
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f);
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
virtual void fixupModelsInScene();

View file

@ -295,7 +295,7 @@ void Head::relaxLean(float deltaTime) {
_deltaLeanForward *= relaxationFactor;
}
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) {
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum) {
if (_renderLookatVectors) {
renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition());
}

View file

@ -33,7 +33,7 @@ public:
void init();
void reset();
void simulate(float deltaTime, bool isMine, bool billboard = false);
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting);
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum);
void setScale(float scale);
void setPosition(glm::vec3 position) { _position = position; }
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }

View file

@ -79,7 +79,7 @@ const float MyAvatar::ZOOM_MAX = 25.0f;
const float MyAvatar::ZOOM_DEFAULT = 1.5f;
MyAvatar::MyAvatar() :
Avatar(),
Avatar(),
_gravity(0.0f, 0.0f, 0.0f),
_wasPushing(false),
_isPushing(false),
@ -253,6 +253,9 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
return;
}
FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker();
bool inFacetracker = tracker && !tracker->isMuted();
if (inHmd) {
estimatedPosition = qApp->getHeadPosition();
estimatedPosition.x *= -1.0f;
@ -260,12 +263,17 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
const float OCULUS_LEAN_SCALE = 0.05f;
estimatedPosition /= OCULUS_LEAN_SCALE;
} else {
FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker();
if (tracker && !tracker->isMuted()) {
estimatedPosition = tracker->getHeadTranslation();
_trackedHeadPosition = estimatedPosition;
estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation()));
} else if (inFacetracker) {
estimatedPosition = tracker->getHeadTranslation();
_trackedHeadPosition = estimatedPosition;
estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation()));
if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
// Invert yaw and roll when in mirror mode
// NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror
// it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to
// match your body movements.
YAW(estimatedRotation) *= -1.0f;
ROLL(estimatedRotation) *= -1.0f;
}
}
@ -312,7 +320,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
// NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror
// it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to
// match your body movements.
if (inHmd && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
if ((inHmd || inFacetracker) && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
relativePosition.x = -relativePosition.x;
}
@ -324,13 +332,13 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
// virtual
void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
// don't render if we've been asked to disable local rendering
if (!_shouldRender) {
return; // exit early
}
Avatar::render(renderArgs, cameraPosition, postLighting);
Avatar::render(renderArgs, cameraPosition);
// don't display IK constraints in shadow mode
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) &&
@ -1218,7 +1226,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
}
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
return; // wait until all models are loaded
@ -1228,7 +1236,7 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bo
// Render head so long as the camera isn't inside it
if (shouldRenderHead(renderArgs)) {
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
getHead()->render(renderArgs, 1.0f, renderFrustum);
}
getHand()->render(renderArgs, true);
}
@ -1524,8 +1532,8 @@ void MyAvatar::maybeUpdateBillboard() {
return;
}
}
gpu::Context context(new gpu::GLBackend());
RenderArgs renderArgs(&context);
RenderArgs renderArgs(qApp->getGPUContext());
QImage image = qApp->renderAvatarBillboard(&renderArgs);
_billboard.clear();
QBuffer buffer(&_billboard);

View file

@ -45,8 +45,8 @@ public:
void preRender(RenderArgs* renderArgs);
void updateFromTrackers(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false) override;
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f) override;
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f) override;
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
// setters

View file

@ -13,6 +13,7 @@
#include <QMultiMap>
#include <CapsuleShape.h>
#include <DeferredLightingEffect.h>
#include <SphereShape.h>
#include "Application.h"
@ -785,31 +786,34 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
const int BALL_SUBDIVISIONS = 10;
if (_shapes.isEmpty()) {
// the bounding shape has not been propery computed
// the bounding shape has not been properly computed
// so no need to render it
return;
}
// draw a blue sphere at the capsule endpoint
auto geometryCache = DependencyManager::get<GeometryCache>();
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
Transform transform; // = Transform();
// draw a blue sphere at the capsule end point
glm::vec3 endPoint;
_boundingShape.getEndPoint(endPoint);
endPoint = endPoint + _translation;
Transform transform = Transform();
transform.setTranslation(endPoint);
batch.setModelTransform(transform);
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
deferredLighting->bindSimpleProgram(batch);
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
glm::vec4(0.6f, 0.6f, 0.8f, alpha));
// draw a yellow sphere at the capsule startpoint
// draw a yellow sphere at the capsule start point
glm::vec3 startPoint;
_boundingShape.getStartPoint(startPoint);
startPoint = startPoint + _translation;
glm::vec3 axis = endPoint - startPoint;
Transform axisTransform = Transform();
axisTransform.setTranslation(-axis);
batch.setModelTransform(axisTransform);
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
transform.setTranslation(startPoint);
batch.setModelTransform(transform);
deferredLighting->bindSimpleProgram(batch);
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
glm::vec4(0.8f, 0.8f, 0.6f, alpha));
// draw a green cylinder between the two points

View file

@ -30,6 +30,7 @@
#include <PathUtils.h>
#include <SharedUtil.h>
#include <UserActivityLogger.h>
#include <FramebufferCache.h>
#include <OVR_CAPI_GL.h>
@ -646,7 +647,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
return;
}
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFBO = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFBO));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -706,7 +707,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
_activeEye = ovrEye_Count;
gpu::FramebufferPointer finalFbo;
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
finalFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// restore our normal viewport

View file

@ -270,8 +270,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
gpu::Batch batch;
geometryCache->useSimpleDrawPipeline(batch);
batch._glDisable(GL_DEPTH_TEST);
batch._glDisable(GL_CULL_FACE);
//batch._glDisable(GL_DEPTH_TEST);
//batch._glDisable(GL_CULL_FACE);
//batch._glBindTexture(GL_TEXTURE_2D, texture);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View file

@ -209,7 +209,8 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderAr
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
batch.setProjectionTransform(mat4());
batch.setModelTransform(mat4());
batch.setModelTransform(Transform());
batch.setViewTransform(Transform());
batch.setResourceTexture(0, DependencyManager::get<TextureCache>()->getWhiteTexture());
batch._glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH);

View file

@ -49,7 +49,6 @@ private:
gpu::TexturePointer _overlayDepthTexture;
gpu::TexturePointer _overlayColorTexture;
gpu::FramebufferPointer _overlayFramebuffer;
};
#endif // hifi_ApplicationOverlay_h

View file

@ -91,6 +91,7 @@ void BillboardOverlay::render(RenderArgs* args) {
if (batch) {
Transform transform = _transform;
transform.postScale(glm::vec3(getDimensions(), 1.0f));
transform.setRotation(rotation);
batch->setModelTransform(transform);
batch->setResourceTexture(0, _texture->getGPUTexture());

View file

@ -85,7 +85,6 @@ TextOverlay::TextOverlay() :
_topMargin(DEFAULT_MARGIN),
_fontSize(DEFAULT_FONTSIZE)
{
qApp->postLambdaEvent([=] {
static std::once_flag once;
std::call_once(once, [] {
@ -117,7 +116,7 @@ TextOverlay::TextOverlay(const TextOverlay* textOverlay) :
});
});
while (!_qmlElement) {
QThread::sleep(1);
QThread::msleep(1);
}
}
@ -147,14 +146,12 @@ xColor TextOverlay::getBackgroundColor() {
}
void TextOverlay::render(RenderArgs* args) {
if (!_qmlElement) {
return;
}
if (_visible != _qmlElement->isVisible()) {
_qmlElement->setVisible(_visible);
}
float pulseLevel = updatePulse();
static float _oldPulseLevel = 0.0f;
if (pulseLevel != _oldPulseLevel) {
}
}

View file

@ -134,7 +134,7 @@ protected:
friend class Shader;
};
typedef std::shared_ptr<Context> ContextPointer;
};

View file

@ -1,19 +1,21 @@
//
// Framebuffer.h
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 4/12/2015.
// 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_Framebuffer_h
#define hifi_gpu_Framebuffer_h
#include "Texture.h"
//
// Framebuffer.h
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 4/12/2015.
// 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_Framebuffer_h
#define hifi_gpu_Framebuffer_h
#include "Texture.h"
#include <memory>
class QImage;
namespace gpu {
typedef Element Format;
@ -130,7 +132,9 @@ public:
void resize( uint16 width, uint16 height, uint16 samples = 1 );
static const uint32 MAX_NUM_RENDER_BUFFERS = 8;
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
void getImage(QImage* result) const;
protected:
SwapchainPointer _swapchain;
@ -151,10 +155,10 @@ protected:
// Non exposed
Framebuffer(const Framebuffer& framebuffer) {}
Framebuffer() {}
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
};
@ -162,4 +166,4 @@ typedef std::shared_ptr<Framebuffer> FramebufferPointer;
}
#endif
#endif

View file

@ -8,6 +8,7 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <mutex>
#include "GPULogging.h"
#include "GLBackendShared.h"
#include <glm/gtc/type_ptr.hpp>
@ -89,6 +90,36 @@ GLBackend::GLBackend() :
_pipeline(),
_output()
{
static std::once_flag once;
std::call_once(once, [] {
qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
qCDebug(gpulogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
qCDebug(gpulogging) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR));
qCDebug(gpulogging) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER));
#ifdef WIN32
GLenum err = glewInit();
if (GLEW_OK != err) {
/* Problem: glewInit failed, something is seriously wrong. */
qCDebug(gpulogging, "Error: %s\n", glewGetErrorString(err));
}
qCDebug(gpulogging, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
if (wglewGetExtension("WGL_EXT_swap_control")) {
int swapInterval = wglGetSwapIntervalEXT();
qCDebug(gpulogging, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF"));
}
#endif
#if defined(Q_OS_LINUX)
// TODO: Write the correct code for Linux...
/* if (wglewGetExtension("WGL_EXT_swap_control")) {
int swapInterval = wglGetSwapIntervalEXT();
qCDebug(gpulogging, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF"));
}*/
#endif
});
initInput();
initTransform();
}
@ -113,6 +144,7 @@ void GLBackend::render(Batch& batch) {
}
void GLBackend::renderBatch(Batch& batch, bool syncCache) {
qCDebug(gpulogging) << "GLBackend::renderBatch : Deprecated call, don;t do it!!!";
GLBackend backend;
if (syncCache) {
backend.syncCache();
@ -166,6 +198,8 @@ void GLBackend::syncCache() {
syncTransformStateCache();
syncPipelineStateCache();
syncInputStateCache();
glEnable(GL_LINE_SMOOTH);
}
void GLBackend::do_draw(Batch& batch, uint32 paramOffset) {

View file

@ -447,7 +447,6 @@ protected:
typedef void (GLBackend::*CommandCall)(Batch&, uint32);
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
};

View file

@ -10,7 +10,7 @@
//
#include "Texture.h"
#include <math.h>
#include <glm/gtc/constants.hpp>
#include <QDebug>

View file

@ -43,9 +43,18 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& poin
const float MIN_MARGIN = 0.01f;
glm::vec3 diagonal = maxCorner - minCorner;
float minDimension = glm::min(diagonal[0], diagonal[1]);
minDimension = glm::min(minDimension, diagonal[2]);
margin = glm::min(glm::max(0.5f * minDimension, MIN_MARGIN), margin);
float smallestDimension = glm::min(diagonal[0], diagonal[1]);
smallestDimension = glm::min(smallestDimension, diagonal[2]);
const float MIN_DIMENSION = 2.0f * MIN_MARGIN + 0.001f;
if (smallestDimension < MIN_DIMENSION) {
for (int i = 0; i < 3; ++i) {
if (diagonal[i] < MIN_DIMENSION) {
diagonal[i] = MIN_DIMENSION;
}
}
smallestDimension = MIN_DIMENSION;
}
margin = glm::min(glm::max(0.5f * smallestDimension, MIN_MARGIN), margin);
hull->setMargin(margin);
// add the points, correcting for margin

View file

@ -23,6 +23,7 @@
#include "GeometryCache.h"
#include "RenderUtil.h"
#include "TextureCache.h"
#include "FramebufferCache.h"
#include "simple_vert.h"
@ -215,8 +216,6 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
}
void DeferredLightingEffect::prepare(RenderArgs* args) {
auto textureCache = DependencyManager::get<TextureCache>();
gpu::Batch batch;
// clear the normal and specular buffers
@ -228,29 +227,31 @@ void DeferredLightingEffect::prepare(RenderArgs* args) {
args->_context->render(batch);
}
gpu::FramebufferPointer _copyFBO;
void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
// perform deferred lighting, rendering to free fbo
auto textureCache = DependencyManager::get<TextureCache>();
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = textureCache->getFrameBufferSize();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// binding the first framebuffer
auto freeFBO = DependencyManager::get<TextureCache>()->getSecondaryFramebuffer();
batch.setFramebuffer(freeFBO);
_copyFBO = framebufferCache->getFramebuffer();
batch.setFramebuffer(_copyFBO);
batch.setViewportTransform(args->_viewport);
batch.clearColorFramebuffer(freeFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.setResourceTexture(0, textureCache->getPrimaryColorTexture());
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(1, textureCache->getPrimaryNormalTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, textureCache->getPrimarySpecularTexture());
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
batch.setResourceTexture(3, textureCache->getPrimaryDepthTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
@ -267,7 +268,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
const LightLocations* locations = &_directionalLightLocations;
bool shadowsEnabled = _viewState->getShadowsEnabled();
if (shadowsEnabled) {
batch.setResourceTexture(4, textureCache->getShadowFramebuffer()->getDepthStencilBuffer());
batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer());
program = _directionalLightShadowMap;
locations = &_directionalLightShadowMapLocations;
@ -294,7 +295,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
}
batch.setPipeline(program);
}
batch._glUniform1f(locations->shadowScale, 1.0f / textureCache->getShadowFramebuffer()->getWidth());
batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth());
} else {
if (useSkyboxCubemap) {
@ -535,17 +536,16 @@ void DeferredLightingEffect::render(RenderArgs* args) {
// End of the Lighting pass
}
void DeferredLightingEffect::copyBack(RenderArgs* args) {
gpu::Batch batch;
auto textureCache = DependencyManager::get<TextureCache>();
QSize framebufferSize = textureCache->getFrameBufferSize();
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
auto freeFBO = DependencyManager::get<TextureCache>()->getSecondaryFramebuffer();
batch.setFramebuffer(textureCache->getPrimaryFramebuffer());
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setPipeline(_blitLightBuffer);
batch.setResourceTexture(0, freeFBO->getRenderBuffer(0));
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
@ -567,6 +567,7 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) {
args->_context->syncCache();
args->_context->render(batch);
framebufferCache->releaseFramebuffer(_copyFBO);
}
void DeferredLightingEffect::setupTransparent(RenderArgs* args, int lightBufferUnit) {

View file

@ -0,0 +1,128 @@
//
// FramebufferCache.cpp
// interface/src/renderer
//
// Created by Andrzej Kapolka on 8/6/13.
// Copyright 2013 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 "FramebufferCache.h"
#include <mutex>
#include <glm/glm.hpp>
#include <QMap>
#include <QQueue>
#include <gpu/Batch.h>
#include <gpu/GPUConfig.h>
#include "RenderUtilsLogging.h"
static QQueue<gpu::FramebufferPointer> _cachedFramebuffers;
FramebufferCache::FramebufferCache() {
}
FramebufferCache::~FramebufferCache() {
_cachedFramebuffers.clear();
}
void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
//If the size changed, we need to delete our FBOs
if (_frameBufferSize != frameBufferSize) {
_frameBufferSize = frameBufferSize;
_primaryFramebuffer.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
_cachedFramebuffers.clear();
}
}
void FramebufferCache::createPrimaryFramebuffer() {
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto width = _frameBufferSize.width();
auto height = _frameBufferSize.height();
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
_primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebuffer->setRenderBuffer(2, _primarySpecularTexture);
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
_primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryFramebuffer;
}
gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() {
if (!_primaryDepthTexture) {
createPrimaryFramebuffer();
}
return _primaryDepthTexture;
}
gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() {
if (!_primaryColorTexture) {
createPrimaryFramebuffer();
}
return _primaryColorTexture;
}
gpu::TexturePointer FramebufferCache::getPrimaryNormalTexture() {
if (!_primaryNormalTexture) {
createPrimaryFramebuffer();
}
return _primaryNormalTexture;
}
gpu::TexturePointer FramebufferCache::getPrimarySpecularTexture() {
if (!_primarySpecularTexture) {
createPrimaryFramebuffer();
}
return _primarySpecularTexture;
}
gpu::FramebufferPointer FramebufferCache::getFramebuffer() {
if (_cachedFramebuffers.isEmpty()) {
_cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));
}
gpu::FramebufferPointer result = _cachedFramebuffers.front();
_cachedFramebuffers.pop_front();
return result;
}
void FramebufferCache::releaseFramebuffer(const gpu::FramebufferPointer& framebuffer) {
if (QSize(framebuffer->getSize().x, framebuffer->getSize().y) == _frameBufferSize) {
_cachedFramebuffers.push_back(framebuffer);
}
}
gpu::FramebufferPointer FramebufferCache::getShadowFramebuffer() {
if (!_shadowFramebuffer) {
const int SHADOW_MAP_SIZE = 2048;
_shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE));
}
return _shadowFramebuffer;
}

View file

@ -0,0 +1,64 @@
//
// Created by Bradley Austin Davis on 2015/07/20
// 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
//
#ifndef hifi_FramebufferCache_h
#define hifi_FramebufferCache_h
#include <QSize>
#include <gpu/Framebuffer.h>
#include <DependencyManager.h>
namespace gpu {
class Batch;
}
/// Stores cached textures, including render-to-texture targets.
class FramebufferCache : public Dependency {
SINGLETON_DEPENDENCY
public:
/// Sets the desired texture resolution for the framebuffer objects.
void setFrameBufferSize(QSize frameBufferSize);
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::TexturePointer getPrimaryDepthTexture();
gpu::TexturePointer getPrimaryColorTexture();
gpu::TexturePointer getPrimaryNormalTexture();
gpu::TexturePointer getPrimarySpecularTexture();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
/// Returns a free framebuffer with a single color attachment for temp or intra-frame operations
gpu::FramebufferPointer getFramebuffer();
// TODO add sync functionality to the release, so we don't reuse a framebuffer being read from
/// Releases a free framebuffer back for reuse
void releaseFramebuffer(const gpu::FramebufferPointer& framebuffer);
private:
FramebufferCache();
virtual ~FramebufferCache();
void createPrimaryFramebuffer();
gpu::FramebufferPointer _primaryFramebuffer;
gpu::TexturePointer _primaryDepthTexture;
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;
gpu::TexturePointer _primarySpecularTexture;
gpu::FramebufferPointer _shadowFramebuffer;
QSize _frameBufferSize{ 100, 100 };
};
#endif // hifi_FramebufferCache_h

View file

@ -9,6 +9,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TextureCache.h"
#include <mutex>
#include <glm/glm.hpp>
#include <glm/gtc/random.hpp>
#include <gpu/Batch.h>
#include <gpu/GLBackend.h>
#include <gpu/GPUConfig.h>
@ -19,21 +26,10 @@
#include <QThreadPool>
#include <qimagereader.h>
#include <glm/glm.hpp>
#include <glm/gtc/random.hpp>
#include "RenderUtilsLogging.h"
#include "TextureCache.h"
#include <mutex>
TextureCache::TextureCache() :
_permutationNormalTexture(0),
_whiteTexture(0),
_blueTexture(0),
_frameBufferSize(100, 100)
{
TextureCache::TextureCache() {
const qint64 TEXTURE_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
setUnusedResourceCacheSize(TEXTURE_DEFAULT_UNUSED_MAX_SIZE);
}
@ -41,23 +37,6 @@ TextureCache::TextureCache() :
TextureCache::~TextureCache() {
}
void TextureCache::setFrameBufferSize(QSize frameBufferSize) {
//If the size changed, we need to delete our FBOs
if (_frameBufferSize != frameBufferSize) {
_frameBufferSize = frameBufferSize;
_primaryFramebuffer.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
_secondaryFramebuffer.reset();
_tertiaryFramebuffer.reset();
}
}
// use fixed table of permutations. Could also make ordered list programmatically
// and then shuffle algorithm. For testing, this ensures consistent behavior in each run.
// this list taken from Ken Perlin's Improved Noise reference implementation (orig. in Java) at
@ -175,113 +154,6 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type
return texture;
}
void TextureCache::createPrimaryFramebuffer() {
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto width = _frameBufferSize.width();
auto height = _frameBufferSize.height();
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
_primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebuffer->setRenderBuffer(2, _primarySpecularTexture);
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
_primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer TextureCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryFramebuffer;
}
gpu::TexturePointer TextureCache::getPrimaryDepthTexture() {
if (!_primaryDepthTexture) {
createPrimaryFramebuffer();
}
return _primaryDepthTexture;
}
gpu::TexturePointer TextureCache::getPrimaryColorTexture() {
if (!_primaryColorTexture) {
createPrimaryFramebuffer();
}
return _primaryColorTexture;
}
gpu::TexturePointer TextureCache::getPrimaryNormalTexture() {
if (!_primaryNormalTexture) {
createPrimaryFramebuffer();
}
return _primaryNormalTexture;
}
gpu::TexturePointer TextureCache::getPrimarySpecularTexture() {
if (!_primarySpecularTexture) {
createPrimaryFramebuffer();
}
return _primarySpecularTexture;
}
GLuint TextureCache::getPrimaryDepthTextureID() {
return gpu::GLBackend::getTextureID(getPrimaryDepthTexture());
}
void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular) {
gpu::Batch batch;
setPrimaryDrawBuffers(batch, color, normal, specular);
gpu::GLBackend::renderBatch(batch);
}
void TextureCache::setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal, bool specular) {
GLenum buffers[3];
int bufferCount = 0;
if (color) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
}
if (normal) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
}
if (specular) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
}
batch._glDrawBuffers(bufferCount, buffers);
}
gpu::FramebufferPointer TextureCache::getSecondaryFramebuffer() {
if (!_secondaryFramebuffer) {
_secondaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _secondaryFramebuffer;
}
gpu::FramebufferPointer TextureCache::getTertiaryFramebuffer() {
if (!_tertiaryFramebuffer) {
_tertiaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _tertiaryFramebuffer;
}
gpu::FramebufferPointer TextureCache::getShadowFramebuffer() {
if (!_shadowFramebuffer) {
const int SHADOW_MAP_SIZE = 2048;
_shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE));
_shadowTexture = _shadowFramebuffer->getDepthStencilBuffer();
}
return _shadowFramebuffer;
}
/// Returns a texture version of an image file
gpu::TexturePointer TextureCache::getImageTexture(const QString& path) {
QImage image = QImage(path).mirrored(false, true);

View file

@ -13,8 +13,6 @@
#define hifi_TextureCache_h
#include <gpu/Texture.h>
#include <gpu/Framebuffer.h>
#include <model/Light.h>
#include <QImage>
@ -39,10 +37,6 @@ class TextureCache : public ResourceCache, public Dependency {
SINGLETON_DEPENDENCY
public:
/// Sets the desired texture resolution for the framebuffer objects.
void setFrameBufferSize(QSize frameBufferSize);
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
/// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and
/// the second, a set of random unit vectors to be used as noise gradients.
@ -67,33 +61,6 @@ public:
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false,
const QByteArray& content = QByteArray());
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::TexturePointer getPrimaryDepthTexture();
gpu::TexturePointer getPrimaryColorTexture();
gpu::TexturePointer getPrimaryNormalTexture();
gpu::TexturePointer getPrimarySpecularTexture();
/// Returns the ID of the primary framebuffer object's depth texture. This contains the Z buffer used in rendering.
uint32_t getPrimaryDepthTextureID();
/// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound.
void setPrimaryDrawBuffers(bool color, bool normal = false, bool specular = false);
void setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal = false, bool specular = false);
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
/// screen effects.
gpu::FramebufferPointer getSecondaryFramebuffer();
/// Returns a pointer to the tertiary framebuffer object, used as an additional render target when performing full
/// screen effects.
gpu::FramebufferPointer getTertiaryFramebuffer();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url,
@ -110,23 +77,7 @@ private:
gpu::TexturePointer _blueTexture;
gpu::TexturePointer _blackTexture;
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
gpu::TexturePointer _primaryDepthTexture;
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;
gpu::TexturePointer _primarySpecularTexture;
gpu::FramebufferPointer _primaryFramebuffer;
void createPrimaryFramebuffer();
gpu::FramebufferPointer _secondaryFramebuffer;
gpu::FramebufferPointer _tertiaryFramebuffer;
gpu::FramebufferPointer _shadowFramebuffer;
gpu::TexturePointer _shadowTexture;
QSize _frameBufferSize;
};
/// A simple object wrapper for an OpenGL texture.

View file

@ -1,63 +1,17 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
#line __LINE__
// Generated on <$_SCRIBE_DATE$>
// stars.frag
// fragment shader
//
// Created by Bradley Austin Davis on 2015/06/19
// Created by Bradley Austin Davis on 6/10/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 vec2 varTexcoord;
varying vec3 varNomral;
varying vec3 varPosition;
uniform float iGlobalTime;
const float PI = 3.14159;
const float TAU = 3.14159 * 2.0;
const int latitudeCount = 5;
const float latitudeDist = PI / 2.0 / float(latitudeCount);
const int meridianCount = 4;
const float merdianDist = PI / float(meridianCount);
float clampLine(float val, float target) {
return clamp((1.0 - abs((val - target)) - 0.998) * 500.0, 0.0, 1.0);
}
float latitude(vec2 pos, float angle) {
float result = clampLine(pos.y, angle);
if (angle != 0.0) {
result += clampLine(pos.y, -angle);
}
return result;
}
float meridian(vec2 pos, float angle) {
return clampLine(pos.x, angle) + clampLine(pos.x + PI, angle);
}
vec2 toPolar(in vec3 dir) {
vec2 polar = vec2(atan(dir.z, dir.x), asin(dir.y));
return polar;
}
void mainVR( out vec4 fragColor, in vec2 fragCoord, in vec3 fragRayOri, in vec3 fragRayDir )
{
vec2 polar = toPolar(fragRayDir);
//polar.x += mod(iGlobalTime / 12.0, PI / 4.0) - PI / 4.0;
float c = 0.0;
for (int i = 0; i < latitudeCount - 1; ++i) {
c += latitude(polar, float(i) * latitudeDist);
}
for (int i = 0; i < meridianCount; ++i) {
c += meridian(polar, float(i) * merdianDist);
}
const vec3 col_lines = vec3(102.0 / 255.0, 136.0 / 255.0, 221.0 / 255.0);
fragColor = vec4(c * col_lines, 0.2);
}
varying vec4 varColor;
void main(void) {
mainVR(gl_FragColor, gl_FragCoord.xy, vec3(0.0), normalize(varPosition));
gl_FragColor = varColor; //vec4(varColor, 1.0);
}

View file

@ -0,0 +1,32 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// standardTransformPNTC.slv
// vertex shader
//
// Created by Sam Gateau on 6/10/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 vec3 varPosition;
varying vec4 varColor;
void main(void) {
varColor = gl_Color.rgba;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
varPosition = gl_Vertex.xyz;
gl_PointSize = gl_Color.a;
}

View file

@ -0,0 +1,63 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
#line __LINE__
// Generated on <$_SCRIBE_DATE$>
// stars.frag
// fragment shader
//
// Created by Bradley Austin Davis on 2015/06/19
varying vec2 varTexcoord;
varying vec3 varNomral;
varying vec3 varPosition;
uniform float iGlobalTime;
const float PI = 3.14159;
const float TAU = 3.14159 * 2.0;
const int latitudeCount = 5;
const float latitudeDist = PI / 2.0 / float(latitudeCount);
const int meridianCount = 4;
const float merdianDist = PI / float(meridianCount);
float clampLine(float val, float target) {
return clamp((1.0 - abs((val - target)) - 0.998) * 500.0, 0.0, 1.0);
}
float latitude(vec2 pos, float angle) {
float result = clampLine(pos.y, angle);
if (angle != 0.0) {
result += clampLine(pos.y, -angle);
}
return result;
}
float meridian(vec2 pos, float angle) {
return clampLine(pos.x, angle) + clampLine(pos.x + PI, angle);
}
vec2 toPolar(in vec3 dir) {
vec2 polar = vec2(atan(dir.z, dir.x), asin(dir.y));
return polar;
}
void mainVR( out vec4 fragColor, in vec2 fragCoord, in vec3 fragRayOri, in vec3 fragRayDir )
{
vec2 polar = toPolar(fragRayDir);
//polar.x += mod(iGlobalTime / 12.0, PI / 4.0) - PI / 4.0;
float c = 0.0;
for (int i = 0; i < latitudeCount - 1; ++i) {
c += latitude(polar, float(i) * latitudeDist);
}
for (int i = 0; i < meridianCount; ++i) {
c += meridian(polar, float(i) * merdianDist);
}
const vec3 col_lines = vec3(102.0 / 255.0, 136.0 / 255.0, 221.0 / 255.0);
fragColor = vec4(c * col_lines, 0.2);
}
void main(void) {
mainVR(gl_FragColor, gl_FragCoord.xy, vec3(0.0), normalize(varPosition));
}

View file

@ -80,7 +80,7 @@ public:
RENDER_DEBUG_SIMULATION_OWNERSHIP = 2,
};
RenderArgs(gpu::Context* context = nullptr,
RenderArgs(std::shared_ptr<gpu::Context> context = nullptr,
OctreeRenderer* renderer = nullptr,
ViewFrustum* viewFrustum = nullptr,
float sizeScale = 1.0f,
@ -102,7 +102,7 @@ public:
_shouldRender(shouldRender) {
}
gpu::Context* _context = nullptr;
std::shared_ptr<gpu::Context> _context = nullptr;
OctreeRenderer* _renderer = nullptr;
ViewFrustum* _viewFrustum = nullptr;
glm::ivec4 _viewport{ 0, 0, 1, 1 };

View file

@ -9,7 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OffscreenUi.h"
#include <QOpenGLFramebufferObject>
#include <QOpenGLDebugLogger>
#include <QQuickWindow>
#include <QGLWidget>