Merge pull request #4049 from ZappoMan/gpuStreamizing

Work on removing immediate mode OpenGL from application
This commit is contained in:
Andrew Meadows 2015-01-07 10:55:15 -08:00
commit d3d80a0b1b
35 changed files with 1066 additions and 1005 deletions

View file

@ -535,12 +535,6 @@ void Application::initializeGL() {
}*/
#endif
// Before we render anything, let's set up our viewFrustumOffsetCamera with a sufficiently large
// field of view and near and far clip to make it interesting.
//viewFrustumOffsetCamera.setFieldOfView(90.0);
_viewFrustumOffsetCamera.setNearClip(DEFAULT_NEAR_CLIP);
_viewFrustumOffsetCamera.setFarClip(DEFAULT_FAR_CLIP);
initDisplay();
qDebug( "Initialized Display.");
@ -627,32 +621,6 @@ void Application::paintGL() {
_myCamera.update(1.0f / _fps);
}
// Note: whichCamera is used to pick between the normal camera myCamera for our
// main camera, vs, an alternate camera. The alternate camera we support right now
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism
// to add other cameras.
//
// Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum()
// code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of
// myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera
Camera* whichCamera = &_myCamera;
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
ViewFrustumOffset viewFrustumOffset = Menu::getInstance()->getViewFrustumOffset();
// set the camera to third-person view but offset so we can see the frustum
glm::quat frustumRotation = glm::quat(glm::radians(glm::vec3(viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll)));
_viewFrustumOffsetCamera.setPosition(_myCamera.getPosition() +
frustumRotation * glm::vec3(0.0f, viewFrustumOffset.up, -viewFrustumOffset.distance));
_viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * frustumRotation);
_viewFrustumOffsetCamera.update(1.0f/_fps);
whichCamera = &_viewFrustumOffsetCamera;
}
if (Menu::getInstance()->getShadowsEnabled()) {
updateShadowMap();
}
@ -663,16 +631,16 @@ void Application::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
//When in mirror mode, use camera rotation. Otherwise, use body rotation
if (whichCamera->getMode() == CAMERA_MODE_MIRROR) {
OculusManager::display(whichCamera->getRotation(), whichCamera->getPosition(), *whichCamera);
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
OculusManager::display(_myCamera.getRotation(), _myCamera.getPosition(), _myCamera);
} else {
OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), *whichCamera);
OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera);
}
_myCamera.update(1.0f / _fps);
} else if (TV3DManager::isConnected()) {
TV3DManager::display(*whichCamera);
TV3DManager::display(_myCamera);
} else {
DependencyManager::get<GlowEffect>()->prepare();
@ -684,7 +652,7 @@ void Application::paintGL() {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
displaySide(*whichCamera);
displaySide(_myCamera);
glPopMatrix();
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
@ -721,7 +689,6 @@ void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height)
}
void Application::resizeGL(int width, int height) {
resetCamerasOnResizeGL(_viewFrustumOffsetCamera, width, height);
resetCamerasOnResizeGL(_myCamera, width, height);
glViewport(0, 0, width, height); // shouldn't this account for the menu???
@ -750,13 +717,6 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum)
if (updateViewFrustum) {
loadViewFrustum(camera, _viewFrustum);
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
// If we're in Display Frustum mode, then we want to use the slightly adjust near/far clip values of the
// _viewFrustumOffsetCamera, so that we can see more of the application content in the application's frustum
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum)) {
nearVal = _viewFrustumOffsetCamera.getNearClip();
farVal = _viewFrustumOffsetCamera.getFarClip();
}
} else {
ViewFrustum tempViewFrustum;
loadViewFrustum(camera, tempViewFrustum);
@ -844,19 +804,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
bool isOption = event->modifiers().testFlag(Qt::AltModifier);
switch (event->key()) {
break;
case Qt::Key_BracketLeft:
case Qt::Key_BracketRight:
case Qt::Key_BraceLeft:
case Qt::Key_BraceRight:
case Qt::Key_ParenLeft:
case Qt::Key_ParenRight:
case Qt::Key_Less:
case Qt::Key_Greater:
case Qt::Key_Comma:
case Qt::Key_Period:
case Qt::Key_QuoteDbl:
Menu::getInstance()->handleViewFrustumOffsetKeyModifier(event->key());
break;
case Qt::Key_L:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::LodTools);
@ -1058,19 +1005,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_Slash:
Menu::getInstance()->triggerOption(MenuOption::UserInterface);
break;
case Qt::Key_F:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::DisplayFrustum);
}
break;
case Qt::Key_P:
Menu::getInstance()->triggerOption(MenuOption::FirstPerson);
break;
case Qt::Key_R:
if (isShifted) {
Menu::getInstance()->triggerOption(MenuOption::FrustumRenderMode);
}
break;
case Qt::Key_Percent:
Menu::getInstance()->triggerOption(MenuOption::Stats);
break;
@ -2707,17 +2644,17 @@ QImage Application::renderAvatarBillboard() {
return image;
}
void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
PROFILE_RANGE(__FUNCTION__);
PerformanceTimer perfTimer("display");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
// transform by eye offset
// load the view frustum
loadViewFrustum(whichCamera, _displayViewFrustum);
loadViewFrustum(theCamera, _displayViewFrustum);
// flip x if in mirror mode (also requires reversing winding order for backface culling)
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
glScalef(-1.0f, 1.0f, 1.0f);
glFrontFace(GL_CW);
@ -2725,32 +2662,32 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
glFrontFace(GL_CCW);
}
glm::vec3 eyeOffsetPos = whichCamera.getEyeOffsetPosition();
glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation();
glm::vec3 eyeOffsetPos = theCamera.getEyeOffsetPosition();
glm::quat eyeOffsetOrient = theCamera.getEyeOffsetOrientation();
glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient);
glRotatef(-glm::degrees(glm::angle(eyeOffsetOrient)), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z);
glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z);
// transform view according to whichCamera
// transform view according to theCamera
// could be myCamera (if in normal mode)
// or could be viewFrustumOffsetCamera if in offset mode
glm::quat rotation = whichCamera.getRotation();
glm::quat rotation = theCamera.getRotation();
glm::vec3 axis = glm::axis(rotation);
glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// store view matrix without translation, which we'll use for precision-sensitive objects
updateUntranslatedViewMatrix(-whichCamera.getPosition());
updateUntranslatedViewMatrix(-theCamera.getPosition());
// Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
// the viewTransofmr object is updatded with the correct values and saved,
// this is what is used for rendering the Entities and avatars
Transform viewTransform;
viewTransform.setTranslation(whichCamera.getPosition());
viewTransform.setTranslation(theCamera.getPosition());
viewTransform.setRotation(rotation);
viewTransform.postTranslate(eyeOffsetPos);
viewTransform.postRotate(eyeOffsetOrient);
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
}
if (renderSide != RenderArgs::MONO) {
@ -2796,9 +2733,9 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
// compute starfield alpha based on distance from atmosphere
float alpha = 1.0f;
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
const EnvironmentData& closestData = _environment.getClosestData(whichCamera.getPosition());
float height = glm::distance(whichCamera.getPosition(),
closestData.getAtmosphereCenter(whichCamera.getPosition()));
const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
float height = glm::distance(theCamera.getPosition(),
closestData.getAtmosphereCenter(theCamera.getPosition()));
if (height < closestData.getAtmosphereInnerRadius()) {
alpha = 0.0f;
@ -2809,7 +2746,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
}
// finally render the starfield
_stars.render(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), whichCamera.getNearClip(), alpha);
_stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
@ -2821,7 +2758,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
PerformanceTimer perfTimer("atmosphere");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... atmosphere...");
_environment.renderAtmospheres(whichCamera);
_environment.renderAtmospheres(theCamera);
}
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
@ -2867,7 +2804,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
bool mirrorMode = (whichCamera.getMode() == CAMERA_MODE_MIRROR);
bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR);
{
PerformanceTimer perfTimer("avatars");
_avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE,
@ -2896,20 +2833,12 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
_nodeBoundsDisplay.draw();
// Render the world box
if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
if (theCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
PerformanceTimer perfTimer("worldBox");
renderWorldBox();
}
// view frustum for debugging
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum) && whichCamera.getMode() != CAMERA_MODE_MIRROR) {
PerformanceTimer perfTimer("viewFrustum");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... renderViewFrustum...");
renderViewFrustum(_viewFrustum);
}
// render octree fades if they exist
if (_octreeFades.size() > 0) {
PerformanceTimer perfTimer("octreeFades");
@ -3136,167 +3065,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
updateProjectionMatrix(_myCamera, updateViewFrustum);
}
// renderViewFrustum()
//
// Description: this will render the view frustum bounds for EITHER the head
// or the "myCamera".
//
// Frustum rendering mode. For debug purposes, we allow drawing the frustum in a couple of different ways.
// We can draw it with each of these parts:
// * Origin Direction/Up/Right vectors - these will be drawn at the point of the camera
// * Near plane - this plane is drawn very close to the origin point.
// * Right/Left planes - these two planes are drawn between the near and far planes.
// * Far plane - the plane is drawn in the distance.
// Modes - the following modes, will draw the following parts.
// * All - draws all the parts listed above
// * Planes - draws the planes but not the origin vectors
// * Origin Vectors - draws the origin vectors ONLY
// * Near Plane - draws only the near plane
// * Far Plane - draws only the far plane
void Application::renderViewFrustum(ViewFrustum& viewFrustum) {
// Load it with the latest details!
loadViewFrustum(_myCamera, viewFrustum);
glm::vec3 position = viewFrustum.getOffsetPosition();
glm::vec3 direction = viewFrustum.getOffsetDirection();
glm::vec3 up = viewFrustum.getOffsetUp();
glm::vec3 right = viewFrustum.getOffsetRight();
// Get ready to draw some lines
glDisable(GL_LIGHTING);
glColor4f(1.0, 1.0, 1.0, 1.0);
glLineWidth(1.0);
glBegin(GL_LINES);
if (Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_ALL
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_VECTORS) {
// Calculate the origin direction vectors
glm::vec3 lookingAt = position + (direction * 0.2f);
glm::vec3 lookingAtUp = position + (up * 0.2f);
glm::vec3 lookingAtRight = position + (right * 0.2f);
// Looking At = white
glColor3f(1,1,1);
glVertex3f(position.x, position.y, position.z);
glVertex3f(lookingAt.x, lookingAt.y, lookingAt.z);
// Looking At Up = purple
glColor3f(1,0,1);
glVertex3f(position.x, position.y, position.z);
glVertex3f(lookingAtUp.x, lookingAtUp.y, lookingAtUp.z);
// Looking At Right = cyan
glColor3f(0,1,1);
glVertex3f(position.x, position.y, position.z);
glVertex3f(lookingAtRight.x, lookingAtRight.y, lookingAtRight.z);
}
if (Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_ALL
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_PLANES
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_NEAR_PLANE) {
// Drawing the bounds of the frustum
// viewFrustum.getNear plane - bottom edge
glColor3f(1,0,0);
glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z);
glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z);
// viewFrustum.getNear plane - top edge
glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z);
glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z);
// viewFrustum.getNear plane - right edge
glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z);
glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z);
// viewFrustum.getNear plane - left edge
glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z);
glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z);
}
if (Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_ALL
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_PLANES
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_FAR_PLANE) {
// viewFrustum.getFar plane - bottom edge
glColor3f(0,1,0);
glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z);
glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z);
// viewFrustum.getFar plane - top edge
glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z);
glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z);
// viewFrustum.getFar plane - right edge
glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z);
glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z);
// viewFrustum.getFar plane - left edge
glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z);
glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z);
}
if (Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_ALL
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_PLANES) {
// RIGHT PLANE IS CYAN
// right plane - bottom edge - viewFrustum.getNear to distant
glColor3f(0,1,1);
glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z);
glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z);
// right plane - top edge - viewFrustum.getNear to distant
glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z);
glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z);
// LEFT PLANE IS BLUE
// left plane - bottom edge - viewFrustum.getNear to distant
glColor3f(0,0,1);
glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z);
glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z);
// left plane - top edge - viewFrustum.getNear to distant
glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z);
glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z);
// focal plane - bottom edge
glColor3f(1.0f, 0.0f, 1.0f);
float focalProportion = (viewFrustum.getFocalLength() - viewFrustum.getNearClip()) /
(viewFrustum.getFarClip() - viewFrustum.getNearClip());
glm::vec3 focalBottomLeft = glm::mix(viewFrustum.getNearBottomLeft(), viewFrustum.getFarBottomLeft(), focalProportion);
glm::vec3 focalBottomRight = glm::mix(viewFrustum.getNearBottomRight(),
viewFrustum.getFarBottomRight(), focalProportion);
glVertex3f(focalBottomLeft.x, focalBottomLeft.y, focalBottomLeft.z);
glVertex3f(focalBottomRight.x, focalBottomRight.y, focalBottomRight.z);
// focal plane - top edge
glm::vec3 focalTopLeft = glm::mix(viewFrustum.getNearTopLeft(), viewFrustum.getFarTopLeft(), focalProportion);
glm::vec3 focalTopRight = glm::mix(viewFrustum.getNearTopRight(), viewFrustum.getFarTopRight(), focalProportion);
glVertex3f(focalTopLeft.x, focalTopLeft.y, focalTopLeft.z);
glVertex3f(focalTopRight.x, focalTopRight.y, focalTopRight.z);
// focal plane - left edge
glVertex3f(focalBottomLeft.x, focalBottomLeft.y, focalBottomLeft.z);
glVertex3f(focalTopLeft.x, focalTopLeft.y, focalTopLeft.z);
// focal plane - right edge
glVertex3f(focalBottomRight.x, focalBottomRight.y, focalBottomRight.z);
glVertex3f(focalTopRight.x, focalTopRight.y, focalTopRight.z);
}
glEnd();
glEnable(GL_LIGHTING);
if (Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_ALL
|| Menu::getInstance()->getFrustumDrawMode() == FRUSTUM_DRAW_MODE_KEYHOLE) {
// Draw the keyhole
float keyholeRadius = viewFrustum.getKeyholeRadius();
if (keyholeRadius > 0.0f) {
glPushMatrix();
glColor4f(1, 1, 0, 1);
glTranslatef(position.x, position.y, position.z); // where we actually want it!
DependencyManager::get<GeometryCache>()->renderSphere(keyholeRadius, 20, 20, false);
glPopMatrix();
}
}
}
void Application::resetSensors() {
DependencyManager::get<Faceshift>()->reset();
DependencyManager::get<Visage>()->reset();

View file

@ -417,7 +417,6 @@ private:
void updateShadowMap();
void renderRearViewMirror(const QRect& region, bool billboard = false);
void renderViewFrustum(ViewFrustum& viewFrustum);
void checkBandwidthMeterClick();
void setMenuShortcutsEnabled(bool enabled);
@ -481,7 +480,6 @@ private:
PrioVR _prioVR;
Camera _myCamera; // My view onto the world
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
Camera _mirrorCamera; // Cammera for mirror view
QRect _mirrorViewRect;
RearMirrorTools* _rearMirrorTools;

View file

@ -78,7 +78,6 @@ Menu* Menu::getInstance() {
return _instance;
}
const ViewFrustumOffset DEFAULT_FRUSTUM_OFFSET = {-135.0f, 0.0f, 0.0f, 25.0f, 0.0f};
const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f;
const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost";
const float DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER = 1.0f;
@ -98,8 +97,6 @@ Menu::Menu() :
_realWorldFieldOfView(DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES),
_faceshiftEyeDeflection(DEFAULT_FACESHIFT_EYE_DEFLECTION),
_faceshiftHostname(DEFAULT_FACESHIFT_HOSTNAME),
_frustumDrawMode(FRUSTUM_DRAW_MODE_ALL),
_viewFrustumOffset(DEFAULT_FRUSTUM_OFFSET),
_jsConsole(NULL),
_octreeStatsDialog(NULL),
_lodToolsDialog(NULL),
@ -365,7 +362,6 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::OffAxisProjection, 0, false);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);
addDisabledActionAndSeparator(viewMenu, "Stats");
@ -513,15 +509,6 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings);
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings);
QMenu* frustumMenu = developerMenu->addMenu("View Frustum");
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
addActionToQMenuAndActionHash(frustumMenu,
MenuOption::FrustumRenderMode,
Qt::SHIFT | Qt::Key_R,
this,
SLOT(cycleFrustumRenderMode()));
updateFrustumRenderModeAction();
Audio::SharedPointer audioIO = DependencyManager::get<Audio>();
QMenu* audioDebugMenu = developerMenu->addMenu("Audio");
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
@ -676,15 +663,6 @@ void Menu::loadSettings(QSettings* settings) {
_speechRecognizer.setEnabled(settings->value("speechRecognitionEnabled", false).toBool());
#endif
settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN
_viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f);
_viewFrustumOffset.pitch = loadSetting(settings, "viewFrustumOffsetPitch", 0.0f);
_viewFrustumOffset.roll = loadSetting(settings, "viewFrustumOffsetRoll", 0.0f);
_viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f);
_viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f);
settings->endGroup();
_walletPrivateKey = settings->value("privateKey").toByteArray();
scanMenuBar(&loadAction, settings);
@ -738,13 +716,6 @@ void Menu::saveSettings(QSettings* settings) {
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
settings->setValue("speechRecognitionEnabled", _speechRecognizer.getEnabled());
#endif
settings->beginGroup("View Frustum Offset Camera");
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
settings->setValue("viewFrustumOffsetRoll", _viewFrustumOffset.roll);
settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance);
settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up);
settings->endGroup();
settings->setValue("privateKey", _walletPrivateKey);
scanMenuBar(&saveAction, settings);
@ -819,66 +790,6 @@ bool Menu::getShadowsEnabled() const {
return isOptionChecked(MenuOption::SimpleShadows) || isOptionChecked(MenuOption::CascadedShadows);
}
void Menu::handleViewFrustumOffsetKeyModifier(int key) {
const float VIEW_FRUSTUM_OFFSET_DELTA = 0.5f;
const float VIEW_FRUSTUM_OFFSET_UP_DELTA = 0.05f;
switch (key) {
case Qt::Key_QuoteDbl:
_viewFrustumOffset.yaw = 0.0f;
_viewFrustumOffset.pitch = 0.0f;
_viewFrustumOffset.roll = 0.0f;
_viewFrustumOffset.up = 0.0f;
_viewFrustumOffset.distance = 0.0f;
break;
case Qt::Key_BracketLeft:
_viewFrustumOffset.yaw -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BracketRight:
_viewFrustumOffset.yaw += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BraceLeft:
_viewFrustumOffset.pitch -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BraceRight:
_viewFrustumOffset.pitch += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_ParenLeft:
_viewFrustumOffset.roll -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_ParenRight:
_viewFrustumOffset.roll += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Less:
_viewFrustumOffset.distance -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Greater:
_viewFrustumOffset.distance += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Comma:
_viewFrustumOffset.up -= VIEW_FRUSTUM_OFFSET_UP_DELTA;
break;
case Qt::Key_Period:
_viewFrustumOffset.up += VIEW_FRUSTUM_OFFSET_UP_DELTA;
break;
default:
break;
}
bumpSettings();
}
void Menu::addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName, int menuItemLocation) {
QAction* actionBefore = NULL;
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
@ -1557,42 +1468,10 @@ void Menu::hmdToolsClosed() {
_hmdToolsDialog->hide();
}
void Menu::cycleFrustumRenderMode() {
_frustumDrawMode = (FrustumDrawMode)((_frustumDrawMode + 1) % FRUSTUM_DRAW_MODE_COUNT);
updateFrustumRenderModeAction();
}
void Menu::runTests() {
runTimingTests();
}
void Menu::updateFrustumRenderModeAction() {
QAction* frustumRenderModeAction = _actionHash.value(MenuOption::FrustumRenderMode);
if (frustumRenderModeAction) {
switch (_frustumDrawMode) {
default:
case FRUSTUM_DRAW_MODE_ALL:
frustumRenderModeAction->setText("Render Mode - All");
break;
case FRUSTUM_DRAW_MODE_VECTORS:
frustumRenderModeAction->setText("Render Mode - Vectors");
break;
case FRUSTUM_DRAW_MODE_PLANES:
frustumRenderModeAction->setText("Render Mode - Planes");
break;
case FRUSTUM_DRAW_MODE_NEAR_PLANE:
frustumRenderModeAction->setText("Render Mode - Near");
break;
case FRUSTUM_DRAW_MODE_FAR_PLANE:
frustumRenderModeAction->setText("Render Mode - Far");
break;
case FRUSTUM_DRAW_MODE_KEYHOLE:
frustumRenderModeAction->setText("Render Mode - Keyhole");
break;
}
}
}
QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) {
QList<QAction*> menuActions;
if (menu) {

View file

@ -51,24 +51,7 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
enum FrustumDrawMode {
FRUSTUM_DRAW_MODE_ALL,
FRUSTUM_DRAW_MODE_VECTORS,
FRUSTUM_DRAW_MODE_PLANES,
FRUSTUM_DRAW_MODE_NEAR_PLANE,
FRUSTUM_DRAW_MODE_FAR_PLANE,
FRUSTUM_DRAW_MODE_KEYHOLE,
FRUSTUM_DRAW_MODE_COUNT
};
struct ViewFrustumOffset {
float yaw;
float pitch;
float roll;
float distance;
float up;
};
const QString SETTINGS_ADDRESS_KEY = "address";
class QSettings;
class AnimationsDialog;
@ -115,16 +98,12 @@ public:
void setScriptsLocation(const QString& scriptsLocation);
BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; }
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
OctreeStatsDialog* getOctreeStatsDialog() const { return _octreeStatsDialog; }
LodToolsDialog* getLodToolsDialog() const { return _lodToolsDialog; }
HMDToolsDialog* getHMDToolsDialog() const { return _hmdToolsDialog; }
bool getShadowsEnabled() const;
void handleViewFrustumOffsetKeyModifier(int key);
// User Tweakable LOD Items
QString getLODFeedbackText();
void autoAdjustLOD(float currentFPS);
@ -216,7 +195,6 @@ private slots:
void octreeStatsDetailsClosed();
void lodToolsClosed();
void hmdToolsClosed();
void cycleFrustumRenderMode();
void runTests();
void showMetavoxelEditor();
void showMetavoxelNetworkSimulator();
@ -252,8 +230,6 @@ private:
const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION);
void updateFrustumRenderModeAction();
QAction* getActionFromName(const QString& menuName, QMenu* menu);
QMenu* getSubMenuFromName(const QString& menuName, QMenu* menu);
QMenu* getMenuParent(const QString& menuName, QString& finalMenuPart);
@ -271,8 +247,6 @@ private:
float _realWorldFieldOfView; // The actual FOV set by the user's monitor size and view distance
float _faceshiftEyeDeflection;
QString _faceshiftHostname;
FrustumDrawMode _frustumDrawMode;
ViewFrustumOffset _viewFrustumOffset;
QPointer<MetavoxelEditor> _MetavoxelEditor;
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
QPointer<ScriptEditorWindow> _ScriptEditor;
@ -359,7 +333,6 @@ namespace MenuOption {
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
const QString DisableLightEntities = "Disable Light Entities";
const QString DisableNackPackets = "Disable NACK Packets";
const QString DisplayFrustum = "Display Frustum";
const QString DisplayHands = "Show Hand Info";
const QString DisplayHandTargets = "Show Hand Targets";
const QString DisplayHermiteData = "Display Hermite Data";
@ -385,13 +358,11 @@ namespace MenuOption {
const QString FilterSixense = "Smooth Sixense Movement";
const QString FirstPerson = "First Person";
const QString FrameTimer = "Show Timer";
const QString FrustumRenderMode = "Render Mode";
const QString Fullscreen = "Fullscreen";
const QString FullscreenMirror = "Fullscreen Mirror";
const QString GlowWhenSpeaking = "Glow When Speaking";
const QString NamesAboveHeads = "Names Above Heads";
const QString GoToUser = "Go To User";
const QString HeadMouse = "Head Mouse";
const QString HMDTools = "HMD Tools";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";

View file

@ -33,6 +33,8 @@
using namespace std;
void renderWorldBox() {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
// Show edge of world
float red[] = {1, 0, 0};
float green[] = {0, 1, 0};
@ -41,22 +43,17 @@ void renderWorldBox() {
glDisable(GL_LIGHTING);
glLineWidth(1.0);
glBegin(GL_LINES);
glColor3fv(red);
glVertex3f(0, 0, 0);
glVertex3f(TREE_SCALE, 0, 0);
geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(TREE_SCALE, 0, 0));
glColor3fv(green);
glVertex3f(0, 0, 0);
glVertex3f(0, TREE_SCALE, 0);
geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, TREE_SCALE, 0));
glColor3fv(blue);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, TREE_SCALE);
geometryCache->renderLine(glm::vec3(0, 0, 0), glm::vec3(0, 0, TREE_SCALE));
glColor3fv(gray);
glVertex3f(0, 0, TREE_SCALE);
glVertex3f(TREE_SCALE, 0, TREE_SCALE);
glVertex3f(TREE_SCALE, 0, TREE_SCALE);
glVertex3f(TREE_SCALE, 0, 0);
glEnd();
geometryCache->renderLine(glm::vec3(0, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, TREE_SCALE));
geometryCache->renderLine(glm::vec3(TREE_SCALE, 0, TREE_SCALE), glm::vec3(TREE_SCALE, 0, 0));
// Draw meter markers along the 3 axis to help with measuring things
const float MARKER_DISTANCE = 1.0f;
const float MARKER_RADIUS = 0.05f;
@ -64,7 +61,6 @@ void renderWorldBox() {
glPushMatrix();
glTranslatef(MARKER_DISTANCE, 0, 0);
glColor3fv(red);
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderSphere(MARKER_RADIUS, 10, 10);
glPopMatrix();
glPushMatrix();
@ -134,51 +130,7 @@ void renderCollisionOverlay(int width, int height, float magnitude, float red, f
}
void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance) {
glBegin(GL_POLYGON);
// left side
glVertex2f(x, y + bevelDistance);
glVertex2f(x, y + height - bevelDistance);
// top side
glVertex2f(x + bevelDistance, y + height);
glVertex2f(x + width - bevelDistance, y + height);
// right
glVertex2f(x + width, y + height - bevelDistance);
glVertex2f(x + width, y + bevelDistance);
// bottom
glVertex2f(x + width - bevelDistance, y);
glVertex2f(x +bevelDistance, y);
glEnd();
}
void renderOrientationDirections(glm::vec3 position, const glm::quat& orientation, float size) {
glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;
glm::vec3 pUp = position + orientation * IDENTITY_UP * size;
glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_LINE_STRIP);
glVertex3f(position.x, position.y, position.z);
glVertex3f(pRight.x, pRight.y, pRight.z);
glEnd();
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_LINE_STRIP);
glVertex3f(position.x, position.y, position.z);
glVertex3f(pUp.x, pUp.y, pUp.z);
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_LINE_STRIP);
glVertex3f(position.x, position.y, position.z);
glVertex3f(pFront.x, pFront.y, pFront.z);
glEnd();
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(x, y, width, height, bevelDistance);
}
// Do some basic timing tests and report the results

View file

@ -27,9 +27,6 @@ void drawText(int x, int y, float scale, float radians, int mono,
void renderCollisionOverlay(int width, int height, float magnitude, float red = 0, float blue = 0, float green = 0);
void renderOrientationDirections( glm::vec3 position, const glm::quat& orientation, float size );
void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance);
void runTimingTests();

View file

@ -13,6 +13,7 @@
#include <AudioConstants.h>
#include <DependencyManager.h>
#include <GeometryCache.h>
#include <NodeList.h>
#include <Util.h>
@ -50,21 +51,13 @@ void AudioIOStatsRenderer::render(const float* color, int width, int height) {
static const float backgroundColor[4] = { 0.2f, 0.2f, 0.2f, 0.6f };
int x = std::max((width - (int)STATS_WIDTH) / 2, 0);
int y = std::max((height - CENTERED_BACKGROUND_HEIGHT) / 2, 0);
int backgroundHeight = statsHeight;
int w = STATS_WIDTH;
int h = statsHeight;
glColor4fv(backgroundColor);
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + STATS_WIDTH, y);
glVertex2i(x + STATS_WIDTH, y + backgroundHeight);
glVertex2i(x , y + backgroundHeight);
glEnd();
glColor4f(1, 1, 1, 1);
DependencyManager::get<GeometryCache>()->renderQuad(x, y, w, h);
glColor4f(1, 1, 1, 1);
int horizontalOffset = x + 5;
int verticalOffset = y;

View file

@ -14,6 +14,7 @@
#include <limits>
#include <AudioConstants.h>
#include <GeometryCache.h>
#include "Audio.h"
@ -34,7 +35,11 @@ AudioScope::AudioScope() :
_scopeInput(NULL),
_scopeOutputLeft(NULL),
_scopeOutputRight(NULL),
_scopeLastFrame()
_scopeLastFrame(),
_audioScopeGrid(DependencyManager::get<GeometryCache>()->allocateID()),
_inputID(DependencyManager::get<GeometryCache>()->allocateID()),
_outputLeftID(DependencyManager::get<GeometryCache>()->allocateID()),
_outputRightD(DependencyManager::get<GeometryCache>()->allocateID())
{
Audio::SharedPointer audioIO = DependencyManager::get<Audio>();
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedSilence,
@ -122,55 +127,27 @@ void AudioScope::render(int width, int height) {
renderBackground(backgroundColor, x, y, w, h);
renderGrid(gridColor, x, y, w, h, gridRows, gridCols);
renderLineStrip(inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput);
renderLineStrip(outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft);
renderLineStrip(outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight);
renderLineStrip(_inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput);
renderLineStrip(_outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft);
renderLineStrip(_outputRightD, outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight);
}
void AudioScope::renderBackground(const float* color, int x, int y, int width, int height) {
glColor4fv(color);
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + width, y);
glVertex2i(x + width, y + height);
glVertex2i(x , y + height);
glEnd();
glColor4f(1, 1, 1, 1);
DependencyManager::get<GeometryCache>()->renderQuad(x, y, width, height);
glColor4f(1, 1, 1, 1);
}
void AudioScope::renderGrid(const float* color, int x, int y, int width, int height, int rows, int cols) {
glColor4fv(color);
glBegin(GL_LINES);
int dx = width / cols;
int dy = height / rows;
int tx = x;
int ty = y;
// Draw horizontal grid lines
for (int i = rows + 1; --i >= 0; ) {
glVertex2i(x, ty);
glVertex2i(x + width, ty);
ty += dy;
}
// Draw vertical grid lines
for (int i = cols + 1; --i >= 0; ) {
glVertex2i(tx, y);
glVertex2i(tx, y + height);
tx += dx;
}
glEnd();
glColor4f(1, 1, 1, 1);
DependencyManager::get<GeometryCache>()->renderGrid(x, y, width, height, rows, cols, _audioScopeGrid);
glColor4f(1, 1, 1, 1);
}
void AudioScope::renderLineStrip(const float* color, int x, int y, int n, int offset, const QByteArray* byteArray) {
void AudioScope::renderLineStrip(int id, const float* color, int x, int y, int n, int offset, const QByteArray* byteArray) {
glColor4fv(color);
glBegin(GL_LINE_STRIP);
int16_t sample;
int16_t* samples = ((int16_t*) byteArray->data()) + offset;
int numSamplesToAverage = _framesPerScope / DEFAULT_FRAMES_PER_SCOPE;
@ -178,6 +155,11 @@ void AudioScope::renderLineStrip(const float* color, int x, int y, int n, int of
int remainder = (n - offset) % numSamplesToAverage;
y += SCOPE_HEIGHT / 2;
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
QVector<glm::vec2> points;
// Compute and draw the sample averages from the offset position
for (int i = count; --i >= 0; ) {
sample = 0;
@ -185,27 +167,27 @@ void AudioScope::renderLineStrip(const float* color, int x, int y, int n, int of
sample += *samples++;
}
sample /= numSamplesToAverage;
glVertex2i(x++, y - sample);
points << glm::vec2(x++, y - sample);
}
// Compute and draw the sample average across the wrap boundary
if (remainder != 0) {
sample = 0;
for (int j = remainder; --j >= 0; ) {
sample += *samples++;
}
samples = (int16_t*) byteArray->data();
for (int j = numSamplesToAverage - remainder; --j >= 0; ) {
sample += *samples++;
}
sample /= numSamplesToAverage;
glVertex2i(x++, y - sample);
points << glm::vec2(x++, y - sample);
} else {
samples = (int16_t*) byteArray->data();
}
// Compute and draw the sample average from the beginning to the offset
count = (offset - remainder) / numSamplesToAverage;
for (int i = count; --i >= 0; ) {
@ -214,9 +196,13 @@ void AudioScope::renderLineStrip(const float* color, int x, int y, int n, int of
sample += *samples++;
}
sample /= numSamplesToAverage;
glVertex2i(x++, y - sample);
points << glm::vec2(x++, y - sample);
}
glEnd();
geometryCache->updateVertices(id, points);
geometryCache->renderVertices(GL_LINE_STRIP, id);
glColor4f(1, 1, 1, 1);
}

View file

@ -21,11 +21,6 @@ class AudioScope : public QObject {
Q_OBJECT
SINGLETON_DEPENDENCY(AudioScope)
public:
// Audio scope methods for rendering
static void renderBackground(const float* color, int x, int y, int width, int height);
void renderGrid(const float* color, int x, int y, int width, int height, int rows, int cols);
void renderLineStrip(const float* color, int x, int y, int n, int offset, const QByteArray* byteArray);
// Audio scope methods for allocation/deallocation
void allocateScope();
void freeScope();
@ -50,6 +45,11 @@ private slots:
void addInputToScope(const QByteArray& inputSamples);
private:
// Audio scope methods for rendering
static void renderBackground(const float* color, int x, int y, int width, int height);
void renderGrid(const float* color, int x, int y, int width, int height, int rows, int cols);
void renderLineStrip(int id, const float* color, int x, int y, int n, int offset, const QByteArray* byteArray);
// Audio scope methods for data acquisition
int addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_t* source, int sourceSamples,
unsigned int sourceChannel, unsigned int sourceNumberOfChannels, float fade = 1.0f);
@ -65,6 +65,12 @@ private:
QByteArray* _scopeOutputLeft;
QByteArray* _scopeOutputRight;
QByteArray _scopeLastFrame;
int _audioScopeGrid;
int _inputID;
int _outputLeftID;
int _outputRightD;
};
#endif // hifi_AudioScope_h

View file

@ -13,6 +13,7 @@
#include <GLCanvas.h>
#include <PathUtils.h>
#include <GeometryCache.h>
#include "Audio.h"
@ -60,21 +61,12 @@ void AudioToolBox::render(int x, int y, bool boxed) {
} else {
glColor3f(0.41f, 0.41f, 0.41f);
}
glBegin(GL_QUADS);
glTexCoord2f(1, 1);
glVertex2f(boxBounds.left(), boxBounds.top());
glTexCoord2f(0, 1);
glVertex2f(boxBounds.right(), boxBounds.top());
glTexCoord2f(0, 0);
glVertex2f(boxBounds.right(), boxBounds.bottom());
glTexCoord2f(1, 0);
glVertex2f(boxBounds.left(), boxBounds.bottom());
glEnd();
glm::vec2 topLeft(boxBounds.left(), boxBounds.top());
glm::vec2 bottomRight(boxBounds.right(), boxBounds.bottom());
glm::vec2 texCoordTopLeft(1,1);
glm::vec2 texCoordBottomRight(0,0);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
}
float iconColor = 1.0f;
@ -101,21 +93,13 @@ void AudioToolBox::render(int x, int y, bool boxed) {
}
glColor3f(iconColor, iconColor, iconColor);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(_iconBounds.left(), _iconBounds.top());
glTexCoord2f(0.0f, 1.0f);
glVertex2f(_iconBounds.right(), _iconBounds.top());
glTexCoord2f(0.0f, 0.0f);
glVertex2f(_iconBounds.right(), _iconBounds.bottom());
glTexCoord2f(1.0f, 0.0f);
glVertex2f(_iconBounds.left(), _iconBounds.bottom());
glEnd();
glm::vec2 topLeft(_iconBounds.left(), _iconBounds.top());
glm::vec2 bottomRight(_iconBounds.right(), _iconBounds.bottom());
glm::vec2 texCoordTopLeft(1,1);
glm::vec2 texCoordBottomRight(0,0);
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
glDisable(GL_TEXTURE_2D);
}

View file

@ -272,6 +272,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
}
if (postLighting && glm::distance(Application::getInstance()->getAvatar()->getPosition(), _position) < 10.0f) {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
// render pointing lasers
glm::vec3 laserColor = glm::vec3(1.0f, 0.0f, 1.0f);
float laserLength = 50.0f;
@ -298,11 +300,10 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
float angle = glm::degrees(glm::angle(rotation));
glm::vec3 axis = glm::axis(rotation);
glRotatef(angle, axis.x, axis.y, axis.z);
glBegin(GL_LINES);
glColor3f(laserColor.x, laserColor.y, laserColor.z);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, laserLength, 0.0f);
glEnd();
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f));
} glPopMatrix();
}
}
@ -326,11 +327,9 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
float angle = glm::degrees(glm::angle(rotation));
glm::vec3 axis = glm::axis(rotation);
glRotatef(angle, axis.x, axis.y, axis.z);
glBegin(GL_LINES);
glColor3f(laserColor.x, laserColor.y, laserColor.z);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, laserLength, 0.0f);
glEnd();
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f));
} glPopMatrix();
}
}
@ -987,10 +986,16 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) {
return bytesRead;
}
int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID;
// render a makeshift cone section that serves as a body part connecting joint spheres
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
glBegin(GL_TRIANGLES);
if (_jointConesID == GeometryCache::UNKNOWN_ID) {
_jointConesID = geometryCache->allocateID();
}
glm::vec3 axis = position2 - position1;
float length = glm::length(axis);
@ -1005,6 +1010,7 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
float anglea = 0.0f;
float angleb = 0.0f;
QVector<glm::vec3> points;
for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) {
@ -1023,16 +1029,14 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
glm::vec3 p2a = position2 + perpSin * sa * radius2 + perpCos * ca * radius2;
glm::vec3 p2b = position2 + perpSin * sb * radius2 + perpCos * cb * radius2;
glVertex3f(p1a.x, p1a.y, p1a.z);
glVertex3f(p1b.x, p1b.y, p1b.z);
glVertex3f(p2a.x, p2a.y, p2a.z);
glVertex3f(p1b.x, p1b.y, p1b.z);
glVertex3f(p2a.x, p2a.y, p2a.z);
glVertex3f(p2b.x, p2b.y, p2b.z);
points << p1a << p1b << p2a << p1b << p2a << p2b;
}
// TODO: this is really inefficient constantly recreating these vertices buffers. It would be
// better if the avatars cached these buffers for each of the joints they are rendering
geometryCache->updateVertices(_jointConesID, points);
geometryCache->renderVertices(GL_TRIANGLES, _jointConesID);
}
glEnd();
}
void Avatar::updateCollisionGroups() {

View file

@ -244,6 +244,8 @@ private:
void renderBillboard();
float getBillboardSize() const;
static int _jointConesID;
};
#endif // hifi_Avatar_h

View file

@ -57,7 +57,9 @@ Head::Head(Avatar* owningAvatar) :
_torsoTwist(0.0f),
_isCameraMoving(false),
_isLookingAtMe(false),
_faceModel(this)
_faceModel(this),
_leftEyeLookAtID(DependencyManager::get<GeometryCache>()->allocateID()),
_rightEyeLookAtID(DependencyManager::get<GeometryCache>()->allocateID())
{
}
@ -338,21 +340,17 @@ void Head::addLeanDeltas(float sideways, float forward) {
}
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
DependencyManager::get<GlowEffect>()->begin();
glLineWidth(2.0);
glBegin(GL_LINES);
glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
glVertex3f(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glColor4f(0.2f, 0.2f, 0.2f, 1.0f);
glVertex3f(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
glEnd();
// TODO: implement support for lines with gradient colors
// glColor4f(0.2f, 0.2f, 0.2f, 1.0f); --> to --> glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
geometryCache->renderLine(leftEyePosition, lookatPosition, _leftEyeLookAtID);
geometryCache->renderLine(rightEyePosition, lookatPosition, _rightEyeLookAtID);
DependencyManager::get<GlowEffect>()->end();
}

View file

@ -160,6 +160,9 @@ private:
glm::vec3 _correctedLookAtPosition;
int _leftEyeLookAtID;
int _rightEyeLookAtID;
// private methods
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);

View file

@ -410,49 +410,6 @@ void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bo
}
}
void MyAvatar::renderHeadMouse(int screenWidth, int screenHeight) const {
Faceshift::SharedPointer faceshift = DependencyManager::get<Faceshift>();
float pixelsPerDegree = screenHeight / Menu::getInstance()->getFieldOfView();
// Display small target box at center or head mouse target that can also be used to measure LOD
float headPitch = getHead()->getFinalPitch();
float headYaw = getHead()->getFinalYaw();
float aspectRatio = (float) screenWidth / (float) screenHeight;
int headMouseX = (int)((float)screenWidth / 2.0f - headYaw * aspectRatio * pixelsPerDegree);
int headMouseY = (int)((float)screenHeight / 2.0f - headPitch * pixelsPerDegree);
glColor3f(1.0f, 1.0f, 1.0f);
glDisable(GL_LINE_SMOOTH);
const int PIXEL_BOX = 16;
glBegin(GL_LINES);
glVertex2f(headMouseX - PIXEL_BOX/2, headMouseY);
glVertex2f(headMouseX + PIXEL_BOX/2, headMouseY);
glVertex2f(headMouseX, headMouseY - PIXEL_BOX/2);
glVertex2f(headMouseX, headMouseY + PIXEL_BOX/2);
glEnd();
glEnable(GL_LINE_SMOOTH);
// If Faceshift is active, show eye pitch and yaw as separate pointer
if (faceshift->isActive()) {
float avgEyePitch = faceshift->getEstimatedEyePitch();
float avgEyeYaw = faceshift->getEstimatedEyeYaw();
int eyeTargetX = (int)((float)(screenWidth) / 2.0f - avgEyeYaw * aspectRatio * pixelsPerDegree);
int eyeTargetY = (int)((float)(screenHeight) / 2.0f - avgEyePitch * pixelsPerDegree);
glColor3f(0.0f, 1.0f, 1.0f);
glDisable(GL_LINE_SMOOTH);
glBegin(GL_LINES);
glVertex2f(eyeTargetX - PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX + PIXEL_BOX/2, eyeTargetY);
glVertex2f(eyeTargetX, eyeTargetY - PIXEL_BOX/2);
glVertex2f(eyeTargetX, eyeTargetY + PIXEL_BOX/2);
glEnd();
}
}
const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f);
glm::vec3 MyAvatar::getLeftPalmPosition() {

View file

@ -42,7 +42,6 @@ public:
void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
void renderDebugBodyPoints();
void renderHeadMouse(int screenWidth, int screenHeight) const;
// setters
void setLeanScale(float scale) { _leanScale = scale; }

View file

@ -31,6 +31,7 @@ enum StandingFootState {
SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) :
Model(parent),
_triangleFanID(DependencyManager::get<GeometryCache>()->allocateID()),
_owningAvatar(owningAvatar),
_boundingShape(),
_boundingShapeLocalOffset(0.0f),
@ -38,7 +39,8 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) :
_defaultEyeModelPosition(glm::vec3(0.0f, 0.0f, 0.0f)),
_standingFoot(NO_FOOT),
_standingOffset(0.0f),
_clampedFootPosition(0.0f) {
_clampedFootPosition(0.0f)
{
}
SkeletonModel::~SkeletonModel() {
@ -320,7 +322,7 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
return;
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const float BASE_DIRECTION_SIZE = 300.0f;
const float BASE_DIRECTION_SIZE = 0.3f;
float directionSize = BASE_DIRECTION_SIZE * extractUniformScale(_scale);
glLineWidth(3.0f);
do {
@ -336,6 +338,9 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
float fanScale = directionSize * 0.75f;
glScalef(fanScale, fanScale, fanScale);
const int AXIS_COUNT = 3;
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
for (int i = 0; i < AXIS_COUNT; i++) {
if (joint.rotationMin[i] <= -PI + EPSILON && joint.rotationMax[i] >= PI - EPSILON) {
continue; // unconstrained
@ -350,20 +355,24 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
otherAxis.x = 1.0f;
}
glColor4f(otherAxis.r, otherAxis.g, otherAxis.b, 0.75f);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f, 0.0f, 0.0f);
QVector<glm::vec3> points;
points << glm::vec3(0.0f, 0.0f, 0.0f);
const int FAN_SEGMENTS = 16;
for (int j = 0; j < FAN_SEGMENTS; j++) {
glm::vec3 rotated = glm::angleAxis(glm::mix(joint.rotationMin[i], joint.rotationMax[i],
(float)j / (FAN_SEGMENTS - 1)), axis) * otherAxis;
glVertex3f(rotated.x, rotated.y, rotated.z);
points << rotated;
}
glEnd();
// TODO: this is really inefficient constantly recreating these vertices buffers. It would be
// better if the skeleton model cached these buffers for each of the joints they are rendering
geometryCache->updateVertices(_triangleFanID, points);
geometryCache->renderVertices(GL_TRIANGLE_FAN, _triangleFanID);
}
glPopMatrix();
renderOrientationDirections(position, _rotation * jointState.getRotation(), directionSize);
renderOrientationDirections(jointIndex, position, _rotation * jointState.getRotation(), directionSize);
jointIndex = joint.parentIndex;
} while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree);
@ -371,6 +380,34 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
glLineWidth(1.0f);
}
void SkeletonModel::renderOrientationDirections(int jointIndex, glm::vec3 position, const glm::quat& orientation, float size) {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
if (!_jointOrientationLines.contains(jointIndex)) {
OrientationLineIDs jointLineIDs;
jointLineIDs._up = geometryCache->allocateID();
jointLineIDs._front = geometryCache->allocateID();
jointLineIDs._right = geometryCache->allocateID();
_jointOrientationLines[jointIndex] = jointLineIDs;
}
OrientationLineIDs& jointLineIDs = _jointOrientationLines[jointIndex];
glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;
glm::vec3 pUp = position + orientation * IDENTITY_UP * size;
glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;
glColor3f(1.0f, 0.0f, 0.0f);
geometryCache->renderLine(position, pRight, jointLineIDs._right);
glColor3f(0.0f, 1.0f, 0.0f);
geometryCache->renderLine(position, pUp, jointLineIDs._up);
glColor3f(0.0f, 0.0f, 1.0f);
geometryCache->renderLine(position, pFront, jointLineIDs._front);
}
void SkeletonModel::setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation) {
// this algorithm is from sample code from sixense
const FBXGeometry& geometry = _geometry->getFBXGeometry();

View file

@ -144,6 +144,15 @@ protected:
private:
void renderJointConstraints(int jointIndex);
void renderOrientationDirections(int jointIndex, glm::vec3 position, const glm::quat& orientation, float size);
struct OrientationLineIDs {
int _up;
int _front;
int _right;
};
QHash<int, OrientationLineIDs> _jointOrientationLines;
int _triangleFanID;
/// \param jointIndex index of joint in model
/// \param position position of joint in model-frame

View file

@ -118,9 +118,6 @@ void ApplicationOverlay::renderReticle(glm::quat orientation, float alpha) {
glm::vec3 bottomLeft = getPoint(reticleSize / 2.0f, reticleSize / 2.0f);
glm::vec3 bottomRight = getPoint(-reticleSize / 2.0f, reticleSize / 2.0f);
glColor4f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha);
if (_reticleQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_reticleQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomLeft, bottomRight, topRight,
glm::vec2(0.0f, 0.0f), glm::vec2(1.0f, 0.0f),
glm::vec2(1.0f, 1.0f), glm::vec2(0.0f, 1.0f), _reticleQuad);
@ -134,15 +131,27 @@ ApplicationOverlay::ApplicationOverlay() :
_alpha(1.0f),
_oculusUIRadius(1.0f),
_crosshairTexture(0),
_reticleQuad(GeometryCache::UNKNOWN_QUAD_ID),
_magnifierQuad(GeometryCache::UNKNOWN_QUAD_ID),
_audioRedQuad(GeometryCache::UNKNOWN_QUAD_ID),
_audioGreenQuad(GeometryCache::UNKNOWN_QUAD_ID),
_audioBlueQuad(GeometryCache::UNKNOWN_QUAD_ID)
_previousBorderWidth(-1),
_previousBorderHeight(-1),
_previousMagnifierBottomLeft(),
_previousMagnifierBottomRight(),
_previousMagnifierTopLeft(),
_previousMagnifierTopRight()
{
memset(_reticleActive, 0, sizeof(_reticleActive));
memset(_magActive, 0, sizeof(_reticleActive));
memset(_magSizeMult, 0, sizeof(_magSizeMult));
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
_reticleQuad = geometryCache->allocateID();
_magnifierQuad = geometryCache->allocateID();
_audioRedQuad = geometryCache->allocateID();
_audioGreenQuad = geometryCache->allocateID();
_audioBlueQuad = geometryCache->allocateID();
_domainStatusBorder = geometryCache->allocateID();
_magnifierBorder = geometryCache->allocateID();
}
ApplicationOverlay::~ApplicationOverlay() {
@ -154,7 +163,6 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
Application* application = Application::getInstance();
Overlays& overlays = application->getOverlays();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
MyAvatar* myAvatar = application->getAvatar();
_textureFov = glm::radians(Menu::getInstance()->getOculusUIAngularSize());
_textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight();
@ -192,10 +200,6 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
renderAudioMeter();
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
myAvatar->renderHeadMouse(glCanvas->width(), glCanvas->height());
}
renderStatsAndLogs();
// give external parties a change to hook in
@ -403,10 +407,6 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
if (_reticleQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_reticleQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(glm::vec3(x + mouseX, y + mouseY, -distance),
glm::vec3(x + mouseX + reticleSize, y + mouseY, -distance),
glm::vec3(x + mouseX + reticleSize, y + mouseY - reticleSize, -distance),
@ -741,30 +741,36 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool
const glm::vec3 bottomRight = getPoint(bottomRightYawPitch.x, bottomRightYawPitch.y);
const glm::vec3 topLeft = getPoint(topLeftYawPitch.x, topLeftYawPitch.y);
const glm::vec3 topRight = getPoint(bottomRightYawPitch.x, topLeftYawPitch.y);
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
if (bottomLeft != _previousMagnifierBottomLeft || bottomRight != _previousMagnifierBottomRight
|| topLeft != _previousMagnifierTopLeft || topRight != _previousMagnifierTopRight) {
QVector<glm::vec3> border;
border << topLeft;
border << bottomLeft;
border << bottomRight;
border << topRight;
border << topLeft;
geometryCache->updateVertices(_magnifierBorder, border);
_previousMagnifierBottomLeft = bottomLeft;
_previousMagnifierBottomRight = bottomRight;
_previousMagnifierTopLeft = topLeft;
_previousMagnifierTopRight = topRight;
}
glPushMatrix(); {
if (showBorder) {
glDisable(GL_TEXTURE_2D);
glLineWidth(1.0f);
//Outer Line
glBegin(GL_LINE_STRIP); {
glColor4f(1.0f, 0.0f, 0.0f, _alpha);
glVertex3f(topLeft.x, topLeft.y, topLeft.z);
glVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
glVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
glVertex3f(topRight.x, topRight.y, topRight.z);
glVertex3f(topLeft.x, topLeft.y, topLeft.z);
} glEnd();
glColor4f(1.0f, 0.0f, 0.0f, _alpha);
geometryCache->renderVertices(GL_LINE_STRIP, _magnifierBorder);
glEnable(GL_TEXTURE_2D);
}
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
if (_magnifierQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_magnifierQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(bottomLeft, bottomRight, topRight, topLeft,
glm::vec2(magnifyULeft, magnifyVBottom),
glm::vec2(magnifyURight, magnifyVBottom),
@ -856,9 +862,6 @@ void ApplicationOverlay::renderAudioMeter() {
glColor3f(1, 1, 1);
}
// Draw Red Quad
if (_audioRedQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_audioRedQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START,
audioMeterY + AUDIO_METER_INSET,
audioLevel - AUDIO_RED_START,
@ -875,9 +878,6 @@ void ApplicationOverlay::renderAudioMeter() {
glColor3f(1, 1, 1);
}
// Draw Green Quad
if (_audioGreenQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_audioGreenQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START,
audioMeterY + AUDIO_METER_INSET,
audioLevel - AUDIO_GREEN_START,
@ -893,9 +893,6 @@ void ApplicationOverlay::renderAudioMeter() {
glColor3f(1, 1, 1);
}
// Draw Blue (low level) quad
if (_audioBlueQuad == GeometryCache::UNKNOWN_QUAD_ID) {
_audioBlueQuad = DependencyManager::get<GeometryCache>()->allocateQuad();
}
DependencyManager::get<GeometryCache>()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET,
audioMeterY + AUDIO_METER_INSET,
audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET,
@ -948,23 +945,29 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
NodeList* nodeList = NodeList::getInstance();
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
int right = glCanvas->width();
int bottom = glCanvas->height();
int width = glCanvas->width();
int height = glCanvas->height();
if (width != _previousBorderWidth || height != _previousBorderHeight) {
QVector<glm::vec2> border;
border << glm::vec2(0, 0);
border << glm::vec2(0, height);
border << glm::vec2(width, height);
border << glm::vec2(width, 0);
border << glm::vec2(0, 0);
geometryCache->updateVertices(_domainStatusBorder, border);
_previousBorderWidth = width;
_previousBorderHeight = height;
}
glColor3f(CONNECTION_STATUS_BORDER_COLOR[0],
CONNECTION_STATUS_BORDER_COLOR[1],
CONNECTION_STATUS_BORDER_COLOR[2]);
glLineWidth(CONNECTION_STATUS_BORDER_LINE_WIDTH);
glBegin(GL_LINE_LOOP);
glVertex2i(0, 0);
glVertex2i(0, bottom);
glVertex2i(right, bottom);
glVertex2i(right, 0);
glEnd();
geometryCache->renderVertices(GL_LINE_STRIP, _domainStatusBorder);
}
}

View file

@ -113,6 +113,17 @@ private:
int _audioRedQuad;
int _audioGreenQuad;
int _audioBlueQuad;
int _domainStatusBorder;
int _magnifierBorder;
int _previousBorderWidth;
int _previousBorderHeight;
glm::vec3 _previousMagnifierBottomLeft;
glm::vec3 _previousMagnifierBottomRight;
glm::vec3 _previousMagnifierTopLeft;
glm::vec3 _previousMagnifierTopRight;
};
#endif // hifi_ApplicationOverlay_h

View file

@ -99,11 +99,7 @@ void BandwidthMeter::renderBox(int x, int y, int w, int h) {
}
void BandwidthMeter::renderVerticalLine(int x, int y, int h) {
glBegin(GL_LINES);
glVertex2i(x, y);
glVertex2i(x, y + h);
glEnd();
DependencyManager::get<GeometryCache>()->renderLine(glm::vec2(x, y), glm::vec2(x, y + h));
}
inline int BandwidthMeter::centered(int subject, int object) {

View file

@ -12,6 +12,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <DependencyManager.h>
#include <GeometryCache.h>
#include "Application.h"
@ -148,52 +149,11 @@ void NodeBounds::draw() {
void NodeBounds::drawNodeBorder(const glm::vec3& center, float scale, float red, float green, float blue) {
glPushMatrix();
glTranslatef(center.x, center.y, center.z);
glScalef(scale, scale, scale);
glLineWidth(2.5);
glColor3f(red, green, blue);
glBegin(GL_LINES);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();
DependencyManager::get<GeometryCache>()->renderWireCube(1.0f);
glPopMatrix();
}

View file

@ -186,34 +186,3 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3
float& distance, BoxFace& face) {
return false;
}
void Base3DOverlay::drawDashedLine(const glm::vec3& start, const glm::vec3& end) {
glBegin(GL_LINES);
// draw each line segment with appropriate gaps
const float DASH_LENGTH = 0.05f;
const float GAP_LENGTH = 0.025f;
const float SEGMENT_LENGTH = DASH_LENGTH + GAP_LENGTH;
float length = glm::distance(start, end);
float segmentCount = length / SEGMENT_LENGTH;
int segmentCountFloor = (int)glm::floor(segmentCount);
glm::vec3 segmentVector = (end - start) / segmentCount;
glm::vec3 dashVector = segmentVector / SEGMENT_LENGTH * DASH_LENGTH;
glm::vec3 gapVector = segmentVector / SEGMENT_LENGTH * GAP_LENGTH;
glm::vec3 point = start;
glVertex3f(point.x, point.y, point.z);
for (int i = 0; i < segmentCountFloor; i++) {
point += dashVector;
glVertex3f(point.x, point.y, point.z);
point += gapVector;
glVertex3f(point.x, point.y, point.z);
}
glVertex3f(end.x, end.y, end.z);
glEnd();
}

View file

@ -60,8 +60,6 @@ public:
}
protected:
void drawDashedLine(const glm::vec3& start, const glm::vec3& end);
glm::vec3 _position;
float _lineWidth;
glm::quat _rotation;

View file

@ -12,6 +12,7 @@
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <GeometryCache.h>
#include <GlowEffect.h>
#include <SharedUtil.h>
#include <StreamUtils.h>
@ -27,7 +28,15 @@ Circle3DOverlay::Circle3DOverlay() :
_majorTickMarksAngle(0.0f),
_minorTickMarksAngle(0.0f),
_majorTickMarksLength(0.0f),
_minorTickMarksLength(0.0f)
_minorTickMarksLength(0.0f),
_quadVerticesID(GeometryCache::UNKNOWN_ID),
_lineVerticesID(GeometryCache::UNKNOWN_ID),
_majorTicksVerticesID(GeometryCache::UNKNOWN_ID),
_minorTicksVerticesID(GeometryCache::UNKNOWN_ID),
_lastStartAt(-1.0f),
_lastEndAt(-1.0f),
_lastOuterRadius(-1.0f),
_lastInnerRadius(-1.0f)
{
_majorTickMarksColor.red = _majorTickMarksColor.green = _majorTickMarksColor.blue = (unsigned char)0;
_minorTickMarksColor.red = _minorTickMarksColor.green = _minorTickMarksColor.blue = (unsigned char)0;
@ -45,7 +54,15 @@ Circle3DOverlay::Circle3DOverlay(const Circle3DOverlay* circle3DOverlay) :
_majorTickMarksLength(circle3DOverlay->_majorTickMarksLength),
_minorTickMarksLength(circle3DOverlay->_minorTickMarksLength),
_majorTickMarksColor(circle3DOverlay->_majorTickMarksColor),
_minorTickMarksColor(circle3DOverlay->_minorTickMarksColor)
_minorTickMarksColor(circle3DOverlay->_minorTickMarksColor),
_quadVerticesID(GeometryCache::UNKNOWN_ID),
_lineVerticesID(GeometryCache::UNKNOWN_ID),
_majorTicksVerticesID(GeometryCache::UNKNOWN_ID),
_minorTicksVerticesID(GeometryCache::UNKNOWN_ID),
_lastStartAt(-1.0f),
_lastEndAt(-1.0f),
_lastOuterRadius(-1.0f),
_lastInnerRadius(-1.0f)
{
}
@ -63,6 +80,16 @@ void Circle3DOverlay::render(RenderArgs* args) {
return; // do nothing if our alpha is 0, we're not visible
}
// Create the circle in the coordinates origin
float outerRadius = getOuterRadius();
float innerRadius = getInnerRadius(); // only used in solid case
float startAt = getStartAt();
float endAt = getEndAt();
bool geometryChanged = (startAt != _lastStartAt || endAt != _lastEndAt ||
innerRadius != _lastInnerRadius || outerRadius != _lastOuterRadius);
const float FULL_CIRCLE = 360.0f;
const float SLICES = 180.0f; // The amount of segment to create the circle
const float SLICE_ANGLE = FULL_CIRCLE / SLICES;
@ -95,148 +122,178 @@ void Circle3DOverlay::render(RenderArgs* args) {
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, 1.0f);
// Create the circle in the coordinates origin
float outerRadius = getOuterRadius();
float innerRadius = getInnerRadius(); // only used in solid case
float startAt = getStartAt();
float endAt = getEndAt();
glLineWidth(_lineWidth);
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
// for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
// we just draw a line...
if (getIsSolid()) {
glBegin(GL_QUAD_STRIP);
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(firstInnerPoint.x, firstInnerPoint.y);
glVertex2f(firstOuterPoint.x, firstOuterPoint.y);
while (angle < endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(thisOuterPoint.x, thisOuterPoint.y);
glVertex2f(thisInnerPoint.x, thisInnerPoint.y);
angle += SLICE_ANGLE;
}
// get the last slice portion....
angle = endAt;
angleInRadians = glm::radians(angle);
glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(lastOuterPoint.x, lastOuterPoint.y);
glVertex2f(lastInnerPoint.x, lastInnerPoint.y);
glEnd();
} else {
if (getIsDashedLine()) {
glBegin(GL_LINES);
} else {
glBegin(GL_LINE_STRIP);
if (_quadVerticesID == GeometryCache::UNKNOWN_ID) {
_quadVerticesID = geometryCache->allocateID();
}
if (geometryChanged) {
QVector<glm::vec2> points;
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(firstPoint.x, firstPoint.y);
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
while (angle < endAt) {
angle += SLICE_ANGLE;
angleInRadians = glm::radians(angle);
glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(thisPoint.x, thisPoint.y);
points << firstInnerPoint << firstOuterPoint;
if (getIsDashedLine()) {
angle += SLICE_ANGLE / 2.0f; // short gap
while (angle < endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(dashStartPoint.x, dashStartPoint.y);
glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << thisOuterPoint << thisInnerPoint;
angle += SLICE_ANGLE;
}
}
// get the last slice portion....
angle = endAt;
angleInRadians = glm::radians(angle);
glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
glVertex2f(lastOuterPoint.x, lastOuterPoint.y);
glEnd();
// get the last slice portion....
angle = endAt;
angleInRadians = glm::radians(angle);
glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius);
glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << lastOuterPoint << lastInnerPoint;
geometryCache->updateVertices(_quadVerticesID, points);
}
geometryCache->renderVertices(GL_QUAD_STRIP, _quadVerticesID);
} else {
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
_lineVerticesID = geometryCache->allocateID();
}
if (geometryChanged) {
QVector<glm::vec2> points;
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << firstPoint;
while (angle < endAt) {
angle += SLICE_ANGLE;
angleInRadians = glm::radians(angle);
glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << thisPoint;
if (getIsDashedLine()) {
angle += SLICE_ANGLE / 2.0f; // short gap
angleInRadians = glm::radians(angle);
glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << dashStartPoint;
}
}
// get the last slice portion....
angle = endAt;
angleInRadians = glm::radians(angle);
glm::vec2 lastPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius);
points << lastPoint;
geometryCache->updateVertices(_lineVerticesID, points);
}
if (getIsDashedLine()) {
geometryCache->renderVertices(GL_LINES, _lineVerticesID);
} else {
geometryCache->renderVertices(GL_LINE_STRIP, _lineVerticesID);
}
}
// draw our tick marks
// for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
// we just draw a line...
if (getHasTickMarks()) {
glBegin(GL_LINES);
// draw our major tick marks
if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
xColor color = getMajorTickMarksColor();
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
float tickMarkAngle = getMajorTickMarksAngle();
float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle;
float angleInRadians = glm::radians(angle);
float tickMarkLength = getMajorTickMarksLength();
float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
float endRadius = startRadius + tickMarkLength;
while (angle <= endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);
glVertex2f(thisPointA.x, thisPointA.y);
glVertex2f(thisPointB.x, thisPointB.y);
angle += tickMarkAngle;
}
if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
_majorTicksVerticesID = geometryCache->allocateID();
}
if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
_minorTicksVerticesID = geometryCache->allocateID();
}
// draw our minor tick marks
if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
xColor color = getMinorTickMarksColor();
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
float tickMarkAngle = getMinorTickMarksAngle();
float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle;
float angleInRadians = glm::radians(angle);
float tickMarkLength = getMinorTickMarksLength();
float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
float endRadius = startRadius + tickMarkLength;
if (geometryChanged) {
QVector<glm::vec2> majorPoints;
QVector<glm::vec2> minorPoints;
while (angle <= endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);
glVertex2f(thisPointA.x, thisPointA.y);
glVertex2f(thisPointB.x, thisPointB.y);
// draw our major tick marks
if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
angle += tickMarkAngle;
float tickMarkAngle = getMajorTickMarksAngle();
float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle;
float angleInRadians = glm::radians(angle);
float tickMarkLength = getMajorTickMarksLength();
float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
float endRadius = startRadius + tickMarkLength;
while (angle <= endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);
majorPoints << thisPointA << thisPointB;
angle += tickMarkAngle;
}
}
// draw our minor tick marks
if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
float tickMarkAngle = getMinorTickMarksAngle();
float angle = startAt - fmod(startAt, tickMarkAngle) + tickMarkAngle;
float angleInRadians = glm::radians(angle);
float tickMarkLength = getMinorTickMarksLength();
float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
float endRadius = startRadius + tickMarkLength;
while (angle <= endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius);
glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius);
minorPoints << thisPointA << thisPointB;
angle += tickMarkAngle;
}
}
geometryCache->updateVertices(_majorTicksVerticesID, majorPoints);
geometryCache->updateVertices(_minorTicksVerticesID, minorPoints);
}
glEnd();
xColor majorColor = getMajorTickMarksColor();
glColor4f(majorColor.red / MAX_COLOR, majorColor.green / MAX_COLOR, majorColor.blue / MAX_COLOR, alpha);
geometryCache->renderVertices(GL_LINES, _majorTicksVerticesID);
xColor minorColor = getMinorTickMarksColor();
glColor4f(minorColor.red / MAX_COLOR, minorColor.green / MAX_COLOR, minorColor.blue / MAX_COLOR, alpha);
geometryCache->renderVertices(GL_LINES, _minorTicksVerticesID);
}
glPopMatrix();
glPopMatrix();
if (geometryChanged) {
_lastStartAt = startAt;
_lastEndAt = endAt;
_lastInnerRadius = innerRadius;
_lastOuterRadius = outerRadius;
}
if (glower) {
delete glower;
}

View file

@ -64,6 +64,16 @@ protected:
float _minorTickMarksLength;
xColor _majorTickMarksColor;
xColor _minorTickMarksColor;
int _quadVerticesID;
int _lineVerticesID;
int _majorTicksVerticesID;
int _minorTicksVerticesID;
float _lastStartAt;
float _lastEndAt;
float _lastOuterRadius;
float _lastInnerRadius;
};

View file

@ -110,21 +110,23 @@ void Cube3DOverlay::render(RenderArgs* args) {
glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z);
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
drawDashedLine(bottomLeftNear, bottomRightNear);
drawDashedLine(bottomRightNear, bottomRightFar);
drawDashedLine(bottomRightFar, bottomLeftFar);
drawDashedLine(bottomLeftFar, bottomLeftNear);
geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear);
geometryCache->renderDashedLine(bottomRightNear, bottomRightFar);
geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar);
geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear);
drawDashedLine(topLeftNear, topRightNear);
drawDashedLine(topRightNear, topRightFar);
drawDashedLine(topRightFar, topLeftFar);
drawDashedLine(topLeftFar, topLeftNear);
geometryCache->renderDashedLine(topLeftNear, topRightNear);
geometryCache->renderDashedLine(topRightNear, topRightFar);
geometryCache->renderDashedLine(topRightFar, topLeftFar);
geometryCache->renderDashedLine(topLeftFar, topLeftNear);
drawDashedLine(bottomLeftNear, topLeftNear);
drawDashedLine(bottomRightNear, topRightNear);
drawDashedLine(bottomLeftFar, topLeftFar);
drawDashedLine(bottomRightFar, topRightFar);
geometryCache->renderDashedLine(bottomLeftNear, topLeftNear);
geometryCache->renderDashedLine(bottomRightNear, topRightNear);
geometryCache->renderDashedLine(bottomLeftFar, topLeftFar);
geometryCache->renderDashedLine(bottomRightFar, topRightFar);
} else {
glScalef(dimensions.x, dimensions.y, dimensions.z);

View file

@ -12,6 +12,7 @@
#include "InterfaceConfig.h"
#include <GlowEffect.h>
#include <GeometryCache.h>
#include "Line3DOverlay.h"
@ -21,7 +22,8 @@ Line3DOverlay::Line3DOverlay() {
Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) :
Base3DOverlay(line3DOverlay),
_end(line3DOverlay->_end)
_end(line3DOverlay->_end),
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{
}
@ -57,12 +59,9 @@ void Line3DOverlay::render(RenderArgs* args) {
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
if (getIsDashedLine()) {
drawDashedLine(_position, _end);
DependencyManager::get<GeometryCache>()->renderDashedLine(_position, _end, _geometryCacheID);
} else {
glBegin(GL_LINES);
glVertex3f(_start.x, _start.y, _start.z);
glVertex3f(_end.x, _end.y, _end.z);
glEnd();
DependencyManager::get<GeometryCache>()->renderLine(_start, _end, _geometryCacheID);
}
glEnable(GL_LIGHTING);

View file

@ -38,6 +38,7 @@ public:
protected:
glm::vec3 _start;
glm::vec3 _end;
int _geometryCacheID;
};

View file

@ -23,7 +23,8 @@ Rectangle3DOverlay::Rectangle3DOverlay() {
}
Rectangle3DOverlay::Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay) :
Planar3DOverlay(rectangle3DOverlay)
Planar3DOverlay(rectangle3DOverlay),
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{
}
@ -64,6 +65,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
//glScalef(dimensions.x, dimensions.y, 1.0f);
glLineWidth(_lineWidth);
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
// for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line...
if (getIsSolid()) {
@ -78,21 +81,26 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
glm::vec3 point3(halfDimensions.x, 0.0f, halfDimensions.y);
glm::vec3 point4(-halfDimensions.x, 0.0f, halfDimensions.y);
drawDashedLine(point1, point2);
drawDashedLine(point2, point3);
drawDashedLine(point3, point4);
drawDashedLine(point4, point1);
geometryCache->renderDashedLine(point1, point2);
geometryCache->renderDashedLine(point2, point3);
geometryCache->renderDashedLine(point3, point4);
geometryCache->renderDashedLine(point4, point1);
} else {
glBegin(GL_LINE_STRIP);
glVertex3f(-halfDimensions.x, 0.0f, -halfDimensions.y);
glVertex3f(halfDimensions.x, 0.0f, -halfDimensions.y);
glVertex3f(halfDimensions.x, 0.0f, halfDimensions.y);
glVertex3f(-halfDimensions.x, 0.0f, halfDimensions.y);
glVertex3f(-halfDimensions.x, 0.0f, -halfDimensions.y);
glEnd();
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;
border << glm::vec3(-halfDimensions.x, 0.0f, -halfDimensions.y);
border << glm::vec3(halfDimensions.x, 0.0f, -halfDimensions.y);
border << glm::vec3(halfDimensions.x, 0.0f, halfDimensions.y);
border << glm::vec3(-halfDimensions.x, 0.0f, halfDimensions.y);
border << glm::vec3(-halfDimensions.x, 0.0f, -halfDimensions.y);
geometryCache->updateVertices(_geometryCacheID, border);
_previousHalfDimensions = halfDimensions;
}
geometryCache->renderVertices(GL_LINE_STRIP, _geometryCacheID);
}
}

View file

@ -24,6 +24,9 @@ public:
virtual void setProperties(const QScriptValue& properties);
virtual Rectangle3DOverlay* createClone() const;
private:
int _geometryCacheID;
glm::vec2 _previousHalfDimensions;
};

View file

@ -25,10 +25,10 @@
//#define WANT_DEBUG
const int GeometryCache::UNKNOWN_QUAD_ID = -1;
const int GeometryCache::UNKNOWN_ID = -1;
GeometryCache::GeometryCache() :
_nextQuadID(0)
_nextID(0)
{
}
@ -513,6 +513,169 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions) {
buffer.release();
}
void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, int cols, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3Pair key(glm::vec3(x, y, width), glm::vec3(height, rows, cols));
QOpenGLBuffer& buffer = registered ? _registeredAlternateGridBuffers[id] : _alternateGridBuffers[key];
// if this is a registered , and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && buffer.isCreated()) {
Vec3Pair& lastKey = _lastRegisteredGrid[id];
if (lastKey != key) {
buffer.destroy();
#ifdef WANT_DEBUG
qDebug() << "renderGrid()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
else {
qDebug() << "renderGrid()... REUSING PREVIOUSLY REGISTERED";
}
#endif // def WANT_DEBUG
}
int vertices = (cols + 1 + rows + 1) * 2;
if (!buffer.isCreated()) {
_lastRegisteredGrid[id] = key;
GLfloat* vertexData = new GLfloat[vertices * 2];
GLfloat* vertex = vertexData;
int dx = width / cols;
int dy = height / rows;
int tx = x;
int ty = y;
// Draw horizontal grid lines
for (int i = rows + 1; --i >= 0; ) {
*(vertex++) = x;
*(vertex++) = ty;
*(vertex++) = x + width;
*(vertex++) = ty;
ty += dy;
}
// Draw vertical grid lines
for (int i = cols + 1; --i >= 0; ) {
//glVertex2i(tx, y);
//glVertex2i(tx, y + height);
*(vertex++) = tx;
*(vertex++) = y;
*(vertex++) = tx;
*(vertex++) = y + height;
tx += dx;
}
buffer.create();
buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
buffer.bind();
buffer.allocate(vertexData, vertices * 2 * sizeof(GLfloat));
delete[] vertexData;
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qDebug() << "new grid buffer made -- _alternateGridBuffers.size():" << _alternateGridBuffers.size();
} else {
qDebug() << "new registered grid buffer made -- _registeredAlternateGridBuffers.size():" << _registeredAlternateGridBuffers.size();
}
#endif
} else {
buffer.bind();
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, 0);
glDrawArrays(GL_LINES, 0, vertices);
glDisableClientState(GL_VERTEX_ARRAY);
buffer.release();
}
void GeometryCache::updateVertices(int id, const QVector<glm::vec2>& points) {
BufferDetails& details = _registeredVertices[id];
if (details.buffer.isCreated()) {
details.buffer.destroy();
#ifdef WANT_DEBUG
qDebug() << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2;
details.vertices = points.size();
details.vertexSize = FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX];
GLfloat* vertex = vertexData;
foreach (const glm::vec2& point, points) {
*(vertex++) = point.x;
*(vertex++) = point.y;
}
details.buffer.create();
details.buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
details.buffer.bind();
details.buffer.allocate(vertexData, details.vertices * FLOATS_PER_VERTEX * sizeof(GLfloat));
delete[] vertexData;
#ifdef WANT_DEBUG
qDebug() << "new registered vertices buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
}
void GeometryCache::updateVertices(int id, const QVector<glm::vec3>& points) {
BufferDetails& details = _registeredVertices[id];
if (details.buffer.isCreated()) {
details.buffer.destroy();
#ifdef WANT_DEBUG
qDebug() << "updateVertices()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3;
details.vertices = points.size();
details.vertexSize = FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX];
GLfloat* vertex = vertexData;
foreach (const glm::vec3& point, points) {
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = point.z;
}
details.buffer.create();
details.buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
details.buffer.bind();
details.buffer.allocate(vertexData, details.vertices * FLOATS_PER_VERTEX * sizeof(GLfloat));
delete[] vertexData;
#ifdef WANT_DEBUG
qDebug() << "new registered linestrip buffer made -- _registeredVertices.size():" << _registeredVertices.size();
#endif
}
void GeometryCache::renderVertices(GLenum mode, int id) {
BufferDetails& details = _registeredVertices[id];
if (details.buffer.isCreated()) {
details.buffer.bind();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(details.vertexSize, GL_FLOAT, 0, 0);
glDrawArrays(mode, 0, details.vertices);
glDisableClientState(GL_VERTEX_ARRAY);
details.buffer.release();
}
}
void GeometryCache::renderSolidCube(float size) {
VerticesIndices& vbo = _solidCubeVBOs[size];
const int FLOATS_PER_VERTEX = 3;
@ -667,15 +830,115 @@ void GeometryCache::renderWireCube(float size) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, int quadID) {
void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, int id) {
bool registeredRect = (id != UNKNOWN_ID);
Vec3Pair key(glm::vec3(x, y, 0.0f), glm::vec3(width, height, bevelDistance));
VerticesIndices& vbo = registeredRect ? _registeredRectVBOs[id] : _rectVBOs[key];
bool registeredQuad = (quadID != UNKNOWN_QUAD_ID);
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredRect && vbo.first != 0) {
Vec3Pair& lastKey = _lastRegisteredRect[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
vbo.first = vbo.second = 0;
#ifdef WANT_DEBUG
qDebug() << "renderBevelCornersRect()... RELEASING REGISTERED RECT";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
else {
qDebug() << "renderBevelCornersRect()... REUSING PREVIOUSLY REGISTERED RECT";
}
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2;
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
const int vertices = 8;
const int indices = 8;
if (vbo.first == 0) {
_lastRegisteredRect[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
GLfloat* vertex = vertexData;
static GLubyte cannonicalIndices[indices] = {0, 1, 2, 3, 4, 5, 6, 7};
int vertexPoint = 0;
// left side
vertex[vertexPoint++] = x;
vertex[vertexPoint++] = y + bevelDistance;
vertex[vertexPoint++] = x;
vertex[vertexPoint++] = y + height - bevelDistance;
// top side
vertex[vertexPoint++] = x + bevelDistance;
vertex[vertexPoint++] = y + height;
vertex[vertexPoint++] = x + width - bevelDistance;
vertex[vertexPoint++] = y + height;
// right
vertex[vertexPoint++] = x + width;
vertex[vertexPoint++] = y + height - bevelDistance;
vertex[vertexPoint++] = x + width;
vertex[vertexPoint++] = y + bevelDistance;
// bottom
vertex[vertexPoint++] = x + width - bevelDistance;
vertex[vertexPoint++] = y;
vertex[vertexPoint++] = x +bevelDistance;
vertex[vertexPoint++] = y;
glGenBuffers(1, &vbo.first);
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
delete[] vertexData;
GLushort* indexData = new GLushort[indices];
GLushort* index = indexData;
for (int i = 0; i < indices; i++) {
index[i] = cannonicalIndices[i];
}
glGenBuffers(1, &vbo.second);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
delete[] indexData;
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qDebug() << "new rect VBO made -- _rectVBOs.size():" << _rectVBOs.size();
} else {
qDebug() << "new registered rect VBO made -- _registeredRectVBOs.size():" << _registeredRectVBOs.size();
}
#endif
} else {
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
glDrawRangeElementsEXT(GL_POLYGON, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, int id) {
bool registeredQuad = (id != UNKNOWN_ID);
Vec2Pair key(minCorner, maxCorner);
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad2DVBOs[key];
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[id] : _quad2DVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredQuad && vbo.first != 0) {
Vec2Pair& lastKey = _lastRegisteredQuad2D[quadID];
Vec2Pair& lastKey = _lastRegisteredQuad2D[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
@ -696,7 +959,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
const int vertices = 4;
const int indices = 4;
if (vbo.first == 0) {
_lastRegisteredQuad2D[quadID] = key;
_lastRegisteredQuad2D[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
GLfloat* vertex = vertexData;
@ -728,7 +991,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
delete[] indexData;
#ifdef WANT_DEBUG
if (quadID == UNKNOWN_QUAD_ID) {
if (id == UNKNOWN_ID) {
qDebug() << "new quad VBO made -- _quad2DVBOs.size():" << _quad2DVBOs.size();
} else {
qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size();
@ -750,15 +1013,15 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner,
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, int quadID) {
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, int id) {
bool registeredQuad = (quadID != UNKNOWN_QUAD_ID);
bool registeredQuad = (id != UNKNOWN_ID);
Vec2PairPair key(Vec2Pair(minCorner, maxCorner), Vec2Pair(texCoordMinCorner, texCoordMaxCorner));
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad2DTextureVBOs[key];
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[id] : _quad2DTextureVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredQuad && vbo.first != 0) {
Vec2PairPair& lastKey = _lastRegisteredQuad2DTexture[quadID];
Vec2PairPair& lastKey = _lastRegisteredQuad2DTexture[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
@ -779,7 +1042,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
const int vertices = 4;
const int indices = 4;
if (vbo.first == 0) {
_lastRegisteredQuad2DTexture[quadID] = key;
_lastRegisteredQuad2DTexture[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // text coords & vertices
GLfloat* vertex = vertexData;
@ -823,7 +1086,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
delete[] indexData;
#ifdef WANT_DEBUG
if (quadID == UNKNOWN_QUAD_ID) {
if (id == UNKNOWN_ID) {
qDebug() << "new quad + texture VBO made -- _quad2DTextureVBOs.size():" << _quad2DTextureVBOs.size();
} else {
qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size();
@ -848,15 +1111,15 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, int quadID) {
void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, int id) {
bool registeredQuad = (quadID != UNKNOWN_QUAD_ID);
bool registeredQuad = (id != UNKNOWN_ID);
Vec3Pair key(minCorner, maxCorner);
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad3DVBOs[key];
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[id] : _quad3DVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredQuad && vbo.first != 0) {
Vec3Pair& lastKey = _lastRegisteredQuad3D[quadID];
Vec3Pair& lastKey = _lastRegisteredQuad3D[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
@ -877,7 +1140,7 @@ void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxC
const int vertices = 4;
const int indices = 4;
if (vbo.first == 0) {
_lastRegisteredQuad3D[quadID] = key;
_lastRegisteredQuad3D[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices
GLfloat* vertex = vertexData;
@ -917,7 +1180,7 @@ void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxC
delete[] indexData;
#ifdef WANT_DEBUG
if (quadID == UNKNOWN_QUAD_ID) {
if (id == UNKNOWN_ID) {
qDebug() << "new quad VBO made -- _quad3DVBOs.size():" << _quad3DVBOs.size();
} else {
qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size();
@ -941,7 +1204,7 @@ void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxC
void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft,
const glm::vec3& bottomRight, const glm::vec3& topRight,
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int quadID) {
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int id) {
#ifdef WANT_DEBUG
qDebug() << "renderQuad() vec3 + texture VBO...";
@ -953,13 +1216,13 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom
qDebug() << " texCoordBottomRight:" << texCoordBottomRight;
#endif //def WANT_DEBUG
bool registeredQuad = (quadID != UNKNOWN_QUAD_ID);
bool registeredQuad = (id != UNKNOWN_ID);
Vec3PairVec2Pair key(Vec3Pair(topLeft, bottomRight), Vec2Pair(texCoordTopLeft, texCoordBottomRight));
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[quadID] : _quad3DTextureVBOs[key];
VerticesIndices& vbo = registeredQuad ? _registeredQuadVBOs[id] : _quad3DTextureVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredQuad && vbo.first != 0) {
Vec3PairVec2Pair& lastKey = _lastRegisteredQuad3DTexture[quadID];
Vec3PairVec2Pair& lastKey = _lastRegisteredQuad3DTexture[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
@ -980,7 +1243,7 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom
const int vertices = 4;
const int indices = 4;
if (vbo.first == 0) {
_lastRegisteredQuad3DTexture[quadID] = key;
_lastRegisteredQuad3DTexture[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // text coords & vertices
GLfloat* vertex = vertexData;
@ -1028,7 +1291,7 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom
delete[] indexData;
#ifdef WANT_DEBUG
if (quadID == UNKNOWN_QUAD_ID) {
if (id == UNKNOWN_ID) {
qDebug() << " _quad3DTextureVBOs.size():" << _quad3DTextureVBOs.size();
} else {
qDebug() << "new registered quad VBO made -- _registeredQuadVBOs.size():" << _registeredQuadVBOs.size();
@ -1052,6 +1315,257 @@ void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottom
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void GeometryCache::renderDashedLine(const glm::vec3& start, const glm::vec3& end, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3Pair key(start, end);
BufferDetails& details = registered ? _registeredDashedLines[id] : _dashedLines[key];
// if this is a registered , and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.buffer.isCreated()) {
if (_lastRegisteredDashedLines[id] != key) {
details.buffer.destroy();
_lastRegisteredDashedLines[id] = key;
#ifdef WANT_DEBUG
qDebug() << "renderDashedLine()... RELEASING REGISTERED";
#endif // def WANT_DEBUG
}
}
if (!details.buffer.isCreated()) {
// draw each line segment with appropriate gaps
const float DASH_LENGTH = 0.05f;
const float GAP_LENGTH = 0.025f;
const float SEGMENT_LENGTH = DASH_LENGTH + GAP_LENGTH;
float length = glm::distance(start, end);
float segmentCount = length / SEGMENT_LENGTH;
int segmentCountFloor = (int)glm::floor(segmentCount);
glm::vec3 segmentVector = (end - start) / segmentCount;
glm::vec3 dashVector = segmentVector / SEGMENT_LENGTH * DASH_LENGTH;
glm::vec3 gapVector = segmentVector / SEGMENT_LENGTH * GAP_LENGTH;
const int FLOATS_PER_VERTEX = 3;
details.vertices = (segmentCountFloor + 1) * 2;
details.vertexSize = FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[details.vertices * FLOATS_PER_VERTEX];
GLfloat* vertex = vertexData;
glm::vec3 point = start;
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = point.z;
for (int i = 0; i < segmentCountFloor; i++) {
point += dashVector;
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = point.z;
point += gapVector;
*(vertex++) = point.x;
*(vertex++) = point.y;
*(vertex++) = point.z;
}
*(vertex++) = end.x;
*(vertex++) = end.y;
*(vertex++) = end.z;
details.buffer.create();
details.buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
details.buffer.bind();
details.buffer.allocate(vertexData, details.vertices * FLOATS_PER_VERTEX * sizeof(GLfloat));
delete[] vertexData;
#ifdef WANT_DEBUG
if (registered) {
qDebug() << "new registered dashed line buffer made -- _registeredVertices:" << _registeredDashedLines.size();
} else {
qDebug() << "new dashed lines buffer made -- _dashedLines:" << _dashedLines.size();
}
#endif
} else {
details.buffer.bind();
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(details.vertexSize, GL_FLOAT, 0, 0);
glDrawArrays(GL_LINES, 0, details.vertices);
glDisableClientState(GL_VERTEX_ARRAY);
details.buffer.release();
}
void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, int id) {
bool registeredLine = (id != UNKNOWN_ID);
Vec3Pair key(p1, p2);
VerticesIndices& vbo = registeredLine ? _registeredLine3DVBOs[id] : _line3DVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredLine && vbo.first != 0) {
Vec3Pair& lastKey = _lastRegisteredLine3D[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
vbo.first = vbo.second = 0;
#ifdef WANT_DEBUG
qDebug() << "renderLine() 3D ... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
else {
qDebug() << "renderLine() 3D ... REUSING PREVIOUSLY REGISTERED line";
}
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 3;
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
const int vertices = 2;
const int indices = 2;
if (vbo.first == 0) {
_lastRegisteredLine3D[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
GLfloat* vertex = vertexData;
static GLubyte cannonicalIndices[indices] = {0, 1};
int vertexPoint = 0;
// p1
vertex[vertexPoint++] = p1.x;
vertex[vertexPoint++] = p1.y;
vertex[vertexPoint++] = p1.z;
// p2
vertex[vertexPoint++] = p2.x;
vertex[vertexPoint++] = p2.y;
vertex[vertexPoint++] = p2.z;
glGenBuffers(1, &vbo.first);
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
delete[] vertexData;
GLushort* indexData = new GLushort[indices];
GLushort* index = indexData;
for (int i = 0; i < indices; i++) {
index[i] = cannonicalIndices[i];
}
glGenBuffers(1, &vbo.second);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
delete[] indexData;
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qDebug() << "new renderLine() 3D VBO made -- _line3DVBOs.size():" << _line3DVBOs.size();
} else {
qDebug() << "new registered renderLine() 3D VBO made -- _registeredLine3DVBOs.size():" << _registeredLine3DVBOs.size();
}
#endif
} else {
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
glDrawRangeElementsEXT(GL_LINES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, int id) {
bool registeredLine = (id != UNKNOWN_ID);
Vec2Pair key(p1, p2);
VerticesIndices& vbo = registeredLine ? _registeredLine2DVBOs[id] : _line2DVBOs[key];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registeredLine && vbo.first != 0) {
Vec2Pair& lastKey = _lastRegisteredLine2D[id];
if (lastKey != key) {
glDeleteBuffers(1, &vbo.first);
glDeleteBuffers(1, &vbo.second);
vbo.first = vbo.second = 0;
#ifdef WANT_DEBUG
qDebug() << "renderLine() 2D... RELEASING REGISTERED line";
#endif // def WANT_DEBUG
}
#ifdef WANT_DEBUG
else {
qDebug() << "renderLine() 2D... REUSING PREVIOUSLY REGISTERED line";
}
#endif // def WANT_DEBUG
}
const int FLOATS_PER_VERTEX = 2;
const int NUM_BYTES_PER_VERTEX = FLOATS_PER_VERTEX * sizeof(GLfloat);
const int vertices = 2;
const int indices = 2;
if (vbo.first == 0) {
_lastRegisteredLine2D[id] = key;
int vertexPoints = vertices * FLOATS_PER_VERTEX;
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a 2D quad
GLfloat* vertex = vertexData;
static GLubyte cannonicalIndices[indices] = {0, 1};
int vertexPoint = 0;
// p1
vertex[vertexPoint++] = p1.x;
vertex[vertexPoint++] = p1.y;
// p2
vertex[vertexPoint++] = p2.x;
vertex[vertexPoint++] = p2.y;
glGenBuffers(1, &vbo.first);
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
delete[] vertexData;
GLushort* indexData = new GLushort[indices];
GLushort* index = indexData;
for (int i = 0; i < indices; i++) {
index[i] = cannonicalIndices[i];
}
glGenBuffers(1, &vbo.second);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
delete[] indexData;
#ifdef WANT_DEBUG
if (id == UNKNOWN_ID) {
qDebug() << "new renderLine() 2D VBO made -- _line2DVBOs.size():" << _line2DVBOs.size();
} else {
qDebug() << "new registered renderLine() 2D VBO made -- _registeredLine2DVBOs.size():" << _registeredLine2DVBOs.size();
}
#endif
} else {
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
glDrawRangeElementsEXT(GL_LINES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) {
return getResource(url, fallback, delayLoad).staticCast<NetworkGeometry>();
}

View file

@ -81,32 +81,43 @@ class GeometryCache : public ResourceCache {
SINGLETON_DEPENDENCY(GeometryCache)
public:
int allocateID() { return _nextID++; }
static const int UNKNOWN_ID;
void renderHemisphere(int slices, int stacks);
void renderSphere(float radius, int slices, int stacks, bool solid = true);
void renderSquare(int xDivisions, int yDivisions);
void renderHalfCylinder(int slices, int stacks);
void renderCone(float base, float height, int slices, int stacks);
void renderGrid(int xDivisions, int yDivisions);
void renderGrid(int x, int y, int width, int height, int rows, int cols, int id = UNKNOWN_ID);
void renderSolidCube(float size);
void renderWireCube(float size);
void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, int id = UNKNOWN_ID);
int allocateQuad() { return _nextQuadID++; }
static const int UNKNOWN_QUAD_ID;
void renderQuad(int x, int y, int width, int height, int quadID = UNKNOWN_QUAD_ID)
{ renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height), quadID); }
void renderQuad(int x, int y, int width, int height, int id = UNKNOWN_ID)
{ renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height), id); }
void renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, int quadID = UNKNOWN_QUAD_ID);
void renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, int id = UNKNOWN_ID);
void renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner,
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, int quadID = UNKNOWN_QUAD_ID);
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, int id = UNKNOWN_ID);
void renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, int quadID = UNKNOWN_QUAD_ID);
void renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, int id = UNKNOWN_ID);
void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft,
const glm::vec3& bottomRight, const glm::vec3& topRight,
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int quadID = UNKNOWN_QUAD_ID);
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, int id = UNKNOWN_ID);
void renderLine(const glm::vec3& p1, const glm::vec3& p2, int id = UNKNOWN_ID);
void renderDashedLine(const glm::vec3& start, const glm::vec3& end, int id = UNKNOWN_ID);
void renderLine(const glm::vec2& p1, const glm::vec2& p2, int id = UNKNOWN_ID);
void updateVertices(int id, const QVector<glm::vec2>& points);
void updateVertices(int id, const QVector<glm::vec3>& points);
void renderVertices(GLenum mode, int id);
/// Loads geometry from the specified URL.
/// \param fallback a fallback URL to load if the desired one is unavailable
@ -137,14 +148,44 @@ private:
QHash<Vec3Pair, VerticesIndices> _quad3DVBOs;
QHash<Vec3PairVec2Pair, VerticesIndices> _quad3DTextureVBOs;
QHash<int, VerticesIndices> _registeredQuadVBOs;
int _nextQuadID;
int _nextID;
QHash<int, Vec2Pair> _lastRegisteredQuad2D;
QHash<int, Vec2PairPair> _lastRegisteredQuad2DTexture;
QHash<int, Vec3Pair> _lastRegisteredQuad3D;
QHash<int, Vec3PairVec2Pair> _lastRegisteredQuad3DTexture;
QHash<int, Vec3Pair> _lastRegisteredRect;
QHash<Vec3Pair, VerticesIndices> _rectVBOs;
QHash<int, VerticesIndices> _registeredRectVBOs;
QHash<int, Vec3Pair> _lastRegisteredLine3D;
QHash<Vec3Pair, VerticesIndices> _line3DVBOs;
QHash<int, VerticesIndices> _registeredLine3DVBOs;
QHash<int, Vec2Pair> _lastRegisteredLine2D;
QHash<Vec2Pair, VerticesIndices> _line2DVBOs;
QHash<int, VerticesIndices> _registeredLine2DVBOs;
struct BufferDetails {
QOpenGLBuffer buffer;
int vertices;
int vertexSize;
};
QHash<int, BufferDetails> _registeredVertices;
QHash<int, Vec3Pair> _lastRegisteredDashedLines;
QHash<Vec3Pair, BufferDetails> _dashedLines;
QHash<int, BufferDetails> _registeredDashedLines;
QHash<IntPair, QOpenGLBuffer> _gridBuffers;
QHash<int, QOpenGLBuffer> _registeredAlternateGridBuffers;
QHash<Vec3Pair, QOpenGLBuffer> _alternateGridBuffers;
QHash<int, Vec3Pair> _lastRegisteredGrid;
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
};

View file

@ -447,59 +447,6 @@ void Model::setJointStates(QVector<JointState> states) {
_boundingRadius = radius;
}
bool Model::renderTriangleProxies() {
if (!isActive()) {
return false;
}
if (_calculatedMeshTrianglesValid) {
int color = 0;
foreach (const QVector<Triangle>& meshTriangles, _calculatedMeshTriangles) {
switch(color) {
case 0: glColor3ub( 0, 0, 255); break;
case 1: glColor3ub( 0, 255, 0); break;
case 2: glColor3ub( 0, 255, 255); break;
case 3: glColor3ub(255, 0, 0); break;
case 4: glColor3ub(255, 0, 255); break;
case 5: glColor3ub(255, 255, 0); break;
case 6: glColor3ub( 0, 0, 128); break;
case 7: glColor3ub( 0, 128, 0); break;
case 8: glColor3ub( 0, 128, 128); break;
case 9: glColor3ub(128, 0, 0); break;
case 10: glColor3ub(128, 0, 128); break;
case 11: glColor3ub(128, 128, 0); break;
case 12: glColor3ub(128, 128, 255); break;
case 13: glColor3ub(128, 255, 128); break;
case 14: glColor3ub(128, 255, 255); break;
case 15: glColor3ub(255, 128, 128); break;
case 16: glColor3ub(255, 128, 255); break;
case 17: glColor3ub(255, 255, 128); break;
default: glColor3ub(255,255, 255); break;
}
if (_calculatedMeshBoxes.size() > color) {
const AABox& box = _calculatedMeshBoxes[color];
glm::vec3 center = box.calcCenter();
glm::vec3 dimensions = box.getDimensions();
glPushMatrix();
glTranslatef(center.x, center.y, center.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f);
glPopMatrix();
}
glBegin(GL_TRIANGLES);
foreach (const Triangle& triangle, meshTriangles) {
glVertex3f( triangle.v0.x, triangle.v0.y, triangle.v0.z);
glVertex3f( triangle.v1.x, triangle.v1.y, triangle.v1.z);
glVertex3f( triangle.v2.x, triangle.v2.y, triangle.v2.z);
}
glEnd();
color++;
}
}
return _calculatedMeshTrianglesValid;
}
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles) {

View file

@ -94,7 +94,6 @@ public:
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE };
bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL);
bool renderTriangleProxies();
// Scene rendering support
static void startScene(RenderArgs::RenderSide renderSide);