void Text3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } Q_ASSERT(args->_batch); auto& batch = *args->_batch; glm::quat rotation; if (_isFacingAvatar) { // rotate about vertical to face the camera rotation = args->_viewFrustum->getOrientation(); } else { rotation = getRotation(); } Transform transform; transform.setTranslation(getPosition()); transform.setRotation(rotation); transform.setScale(getScale()); batch.setModelTransform(transform); const float MAX_COLOR = 255.0f; xColor backgroundColor = getBackgroundColor(); glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, getBackgroundAlpha()); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; const float SLIGHTLY_BEHIND = -0.005f; glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, true, false, true); DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor); // Same font properties as textSize() float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO; float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; glm::vec2 clipMinimum(0.0f, 0.0f); glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, (dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor); transform.setTranslation(getPosition()); transform.postTranslate(glm::vec3(-(halfDimensions.x - _leftMargin) , halfDimensions.y - _topMargin, 0.01f)); transform.setScale(scaleFactor); batch.setModelTransform(transform); glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, getAlpha() }; _textRenderer->draw(batch, 0, 0, _text, textColor); batch.setPipeline(DrawOverlay3D::getOpaquePipeline()); }
void CameraToolBox::render(int x, int y, bool boxed) { glEnable(GL_TEXTURE_2D); if (!_enabledTexture) { _enabledTexture = DependencyManager::get<TextureCache>()->getImageTexture(PathUtils::resourcesPath() + "images/face.svg"); } if (!_mutedTexture) { _mutedTexture = DependencyManager::get<TextureCache>()->getImageTexture(PathUtils::resourcesPath() + "images/face-mute.svg"); } const int MUTE_ICON_SIZE = 24; _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); float iconColor = 1.0f; if (!Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)) { glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_enabledTexture)); } else { glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_mutedTexture)); // Make muted icon pulsate static const float PULSE_MIN = 0.4f; static const float PULSE_MAX = 1.0f; static const float PULSE_FREQUENCY = 1.0f; // in Hz qint64 now = usecTimestampNow(); if (now - _iconPulseTimeReference > (qint64)USECS_PER_SECOND) { // Prevents t from getting too big, which would diminish glm::cos precision _iconPulseTimeReference = now - ((now - _iconPulseTimeReference) % USECS_PER_SECOND); } float t = (float)(now - _iconPulseTimeReference) / (float)USECS_PER_SECOND; float pulseFactor = (glm::cos(t * PULSE_FREQUENCY * 2.0f * PI) + 1.0f) / 2.0f; iconColor = PULSE_MIN + (PULSE_MAX - PULSE_MIN) * pulseFactor; } glm::vec4 quadColor(iconColor, iconColor, iconColor, 1.0f); glm::vec2 topLeft(_iconBounds.left(), _iconBounds.top()); glm::vec2 bottomRight(_iconBounds.right(), _iconBounds.bottom()); glm::vec2 texCoordTopLeft(1,1); glm::vec2 texCoordBottomRight(0,0); if (_boxQuadID == GeometryCache::UNKNOWN_ID) { _boxQuadID = DependencyManager::get<GeometryCache>()->allocateID(); } DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor, _boxQuadID); glDisable(GL_TEXTURE_2D); }
void Text3DOverlay::render(RenderArgs* args) { if (!_renderVisible || !getParentVisible()) { return; // do nothing if we're not visible } Q_ASSERT(args->_batch); auto& batch = *args->_batch; auto transform = getRenderTransform(); batch.setModelTransform(transform); glm::u8vec3 backgroundColor = getBackgroundColor(); glm::vec4 quadColor(toGlm(backgroundColor), getBackgroundAlpha()); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; const float SLIGHTLY_BEHIND = -0.001f; glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, quadColor.a < 1.0f, false, false, false); DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor, _geometryId); // Same font properties as textSize() float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO; float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, (dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor); transform.postTranslate(glm::vec3(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.001f)); transform.setScale(scaleFactor); batch.setModelTransform(transform); glm::vec4 textColor = { toGlm(_color), getTextAlpha() }; // FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline for a gpu performance increase. _textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), true); }
void TextOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } const float MAX_COLOR = 255.0f; xColor backgroundColor = getBackgroundColor(); glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, getBackgroundAlpha()); int left = _bounds.left(); int right = _bounds.right() + 1; int top = _bounds.top(); int bottom = _bounds.bottom() + 1; glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor); // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); const int leftAdjust = -1; // required to make text render relative to left edge of bounds const int topAdjust = -2; // required to make text render relative to top edge of bounds int x = _bounds.left() + _leftMargin + leftAdjust; int y = _bounds.top() + _topMargin + topAdjust; float alpha = getAlpha(); glm::vec4 textColor = {_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, alpha }; QStringList lines = _text.split("\n"); int lineOffset = 0; foreach(QString thisLine, lines) { if (lineOffset == 0) { lineOffset = textRenderer->calculateHeight(qPrintable(thisLine)); } lineOffset += textRenderer->draw(x, y + lineOffset, qPrintable(thisLine), textColor); const int lineGap = 2; lineOffset += lineGap; } }
void Text3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } glPushMatrix(); { glTranslatef(_position.x, _position.y, _position.z); glm::quat rotation; if (_isFacingAvatar) { // rotate about vertical to face the camera rotation = Application::getInstance()->getCamera()->getRotation(); } else { rotation = getRotation(); } glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); const float MAX_COLOR = 255.0f; xColor backgroundColor = getBackgroundColor(); glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, getBackgroundAlpha()); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; const float SLIGHTLY_BEHIND = -0.005f; glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor); // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); float maxHeight = (float)textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO; float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; glTranslatef(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.0f); glm::vec2 clipMinimum(0.0f, 0.0f); glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor, (dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor); glScalef(scaleFactor, -scaleFactor, scaleFactor); enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipDimensions.x); enableClipPlane(GL_CLIP_PLANE1, 1.0f, 0.0f, 0.0f, -clipMinimum.x); enableClipPlane(GL_CLIP_PLANE2, 0.0f, -1.0f, 0.0f, clipMinimum.y + clipDimensions.y); enableClipPlane(GL_CLIP_PLANE3, 0.0f, 1.0f, 0.0f, -clipMinimum.y); glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, getAlpha() }; textRenderer->draw(0, 0, _text, textColor); glDisable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE1); glDisable(GL_CLIP_PLANE2); glDisable(GL_CLIP_PLANE3); } glPopMatrix(); }
void hwColorPerVertexShader::drawTheSwatch( MGeometryData* pGeomData, unsigned int* pIndexing, unsigned int numberOfData, unsigned int indexCount ) { MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if( !pRenderer ) return; // Set the default background color { float r, g, b, a; MHWShaderSwatchGenerator::getSwatchBackgroundColor( r, g, b, a ); glClearColor( r, g, b, a ); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); { // Enable the blending to get the transparency to work // glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // Load in a sample background image if (mSampleImageId == 0) { mSampleImage = new MImage; MStatus rstatus = mSampleImage->readFromFile("C:\\temp\\maya.gif"); if (rstatus == MStatus::kSuccess) { unsigned int w, h; mSampleImage->getSize( w, h ); if (w > 2 && h > 2 ) { glGenTextures( 1, &mSampleImageId ); if (mSampleImageId > 0) { glEnable(GL_TEXTURE_2D); glBindTexture ( GL_TEXTURE_2D, mSampleImageId ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) mSampleImage->pixels() ); } } } if (mSampleImage) { delete mSampleImage; } } // Overlay the background checker board // bool drawBackGround = ( mTranspBias > 0.0f ); bool drawBackGroundTexture = (mSampleImageId != 0); if (drawBackGround) { if (drawBackGroundTexture) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glBindTexture(GL_TEXTURE_2D, mSampleImageId ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); } unsigned int numberOfRepeats = 8; MColor quadColor( 0.5f, 0.5f, 0.5f, 1.0f ); pRenderer->drawSwatchBackGroundQuads( quadColor, drawBackGroundTexture, numberOfRepeats ); if (drawBackGroundTexture) glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); } { // Set some example material // float ambient[4] = { 0.1f, 0.1f, 0.1f, 1.0f }; float diffuse[4] = { 0.7f, 0.7f, 0.7f, 1.0f }; float specular[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; float emission[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission ); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular ); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f); // Track diffuse color float swatchColor[4]; float biasT = 1.0f - mTranspGain - mTranspBias; swatchColor[0] = (diffuse[0] * mColorGain[0]) + mColorBias[0]; swatchColor[1] = (diffuse[1] * mColorGain[1]) + mColorBias[1]; swatchColor[2] = (diffuse[2] * mColorGain[2]) + mColorBias[2]; swatchColor[3] = (diffuse[3] * mTranspGain) + biasT; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, swatchColor ); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glColor4fv( swatchColor ); } if (pGeomData) { glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ); if (mNormalsPerVertex >= 1) { glDisable(GL_LIGHTING); float *normalData = (float *)( pGeomData[1].data() ); float * tangentData = (float *)( pGeomData[3].data() ); float * binormalData = (float *)( pGeomData[4].data() ); if (normalData && mNormalsPerVertex == 1) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, normalData); } else if (tangentData && mNormalsPerVertex == 2) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, tangentData); } else if (binormalData) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, binormalData); } } float *vertexData = (float *)( pGeomData[0].data() ); if (vertexData) { glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer ( 3, GL_FLOAT, 0, vertexData ); } float *normalData = (float *)( pGeomData[1].data() ); if (normalData) { glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer ( GL_FLOAT, 0, normalData ); } if (mSampleImageId > 0) { float *uvData = (float *) (pGeomData[2].data() ); if (uvData) { glBindTexture ( GL_TEXTURE_2D, mSampleImageId ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, 0, uvData ); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef( 0.5f, 0.5f, 1 ); //glTranslatef(0.5f, 0.5f, 0.0f); glRotatef( mTexRotateX, 1.0f, 0.0f, 0.0f); glRotatef( mTexRotateY, 0.0, 1.0f, 0.0f); glRotatef( mTexRotateZ, 0.0, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); } } if (vertexData && normalData && pIndexing ) glDrawElements ( GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, pIndexing ); glPopClientAttrib(); // Release data references pRenderer->dereferenceGeometry( pGeomData, numberOfData ); } glDisable( GL_COLOR_MATERIAL ); glDisable( GL_LIGHTING ); }
void ImageOverlay::render(RenderArgs* args) { if (!_isLoaded && _renderImage) { _isLoaded = true; _texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL); } // If we are not visible or loaded, return. If we are trying to render an // image but the texture hasn't loaded, return. if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) { return; } auto geometryCache = DependencyManager::get<GeometryCache>(); gpu::Batch& batch = *args->_batch; geometryCache->useSimpleDrawPipeline(batch); if (_renderImage) { batch.setResourceTexture(0, _texture->getGPUTexture()); } else { batch.setResourceTexture(0, args->_whiteTexture); } const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glm::vec4 quadColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); int left = _bounds.left(); int right = _bounds.right() + 1; int top = _bounds.top(); int bottom = _bounds.bottom() + 1; glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); batch.setModelTransform(Transform()); // if for some reason our image is not over 0 width or height, don't attempt to render the image if (_renderImage) { float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); if (imageWidth > 0 && imageHeight > 0) { QRect fromImage; if (_wantClipFromImage) { float scaleX = imageWidth / _texture->getOriginalWidth(); float scaleY = imageHeight / _texture->getOriginalHeight(); fromImage.setX(scaleX * _fromImage.x()); fromImage.setY(scaleY * _fromImage.y()); fromImage.setWidth(scaleX * _fromImage.width()); fromImage.setHeight(scaleY * _fromImage.height()); } else { fromImage.setX(0); fromImage.setY(0); fromImage.setWidth(imageWidth); fromImage.setHeight(imageHeight); } float x = fromImage.x() / imageWidth; float y = fromImage.y() / imageHeight; float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure float h = fromImage.height() / imageHeight; glm::vec2 texCoordTopLeft(x, y); glm::vec2 texCoordBottomRight(x + w, y + h); glm::vec4 texcoordRect(texCoordTopLeft, w, h); DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } else { DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor); } } else { DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor); } }
void ImageOverlay::render(RenderArgs* args) { if (!_isLoaded && _renderImage) { _isLoaded = true; _texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL); } // If we are not visible or loaded, return. If we are trying to render an // image but the texture hasn't loaded, return. if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) { return; } if (_renderImage) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _texture->getID()); } const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glm::vec4 quadColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); int left = _bounds.left(); int right = _bounds.right() + 1; int top = _bounds.top(); int bottom = _bounds.bottom() + 1; glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); // if for some reason our image is not over 0 width or height, don't attempt to render the image if (_renderImage) { float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); if (imageWidth > 0 && imageHeight > 0) { QRect fromImage; if (_wantClipFromImage) { float scaleX = imageWidth / _texture->getOriginalWidth(); float scaleY = imageHeight / _texture->getOriginalHeight(); fromImage.setX(scaleX * _fromImage.x()); fromImage.setY(scaleY * _fromImage.y()); fromImage.setWidth(scaleX * _fromImage.width()); fromImage.setHeight(scaleY * _fromImage.height()); } else { fromImage.setX(0); fromImage.setY(0); fromImage.setWidth(imageWidth); fromImage.setHeight(imageHeight); } float x = fromImage.x() / imageWidth; float y = fromImage.y() / imageHeight; float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure float h = fromImage.height() / imageHeight; glm::vec2 texCoordTopLeft(x, y); glm::vec2 texCoordBottomRight(x + w, y + h); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); } else { DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor); } glDisable(GL_TEXTURE_2D); } else { DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor); } }