void RenderableWebEntityItem::render(RenderArgs* args) { checkFading(); #ifdef WANT_EXTRA_DEBUGGING { gpu::Batch& batch = *args->_batch; batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well glm::vec4 cubeColor{ 1.0f, 0.0f, 0.0f, 1.0f}; DependencyManager::get<GeometryCache>()->renderWireCube(batch, 1.0f, cubeColor); } #endif if (!_webSurface) { #if defined(Q_OS_LINUX) // these don't seem to work on Linux return; #else if (!buildWebSurface(static_cast<EntityTreeRenderer*>(args->_renderer))) { return; } _fadeStartTime = usecTimestampNow(); #endif } _lastRenderTime = usecTimestampNow(); glm::vec2 windowSize = getWindowSize(); // The offscreen surface is idempotent for resizes (bails early // if it's a no-op), so it's safe to just call resize every frame // without worrying about excessive overhead. _webSurface->resize(QSize(windowSize.x, windowSize.y)); PerformanceTimer perfTimer("RenderableWebEntityItem::render"); Q_ASSERT(getType() == EntityTypes::Web); static const glm::vec2 texMin(0.0f), texMax(1.0f), topLeft(-0.5f), bottomRight(0.5f); Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; bool success; batch.setModelTransform(getTransformToCenter(success)); if (!success) { return; } if (_texture) { batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture); } float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio); if (fadeRatio < OPAQUE_ALPHA_THRESHOLD) { DependencyManager::get<GeometryCache>()->bindTransparentWebBrowserProgram(batch); } else { DependencyManager::get<GeometryCache>()->bindOpaqueWebBrowserProgram(batch); } DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio)); }
void RenderableShapeEntityItem::render(RenderArgs* args) { PerformanceTimer perfTimer("RenderableShapeEntityItem::render"); //Q_ASSERT(getType() == EntityTypes::Shape); Q_ASSERT(args->_batch); checkFading(); if (!_procedural) { _procedural.reset(new Procedural(getUserData())); _procedural->_vertexSource = simple_vert; _procedural->_fragmentSource = simple_frag; _procedural->_opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural->_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); PrepareStencil::testMaskDrawShape(*_procedural->_opaqueState); _procedural->_opaqueState->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); } gpu::Batch& batch = *args->_batch; glm::vec4 color(toGlm(getXColor()), getLocalRenderAlpha()); bool success; Transform modelTransform = getTransformToCenter(success); if (!success) { return; } if (_shape == entity::Sphere) { modelTransform.postScale(SPHERE_ENTITY_SCALE); } batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation if (_procedural->ready()) { _procedural->prepare(batch, getPosition(), getDimensions(), getOrientation()); auto outColor = _procedural->getColor(color); outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f; batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a); if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { DependencyManager::get<GeometryCache>()->renderWireShape(batch, MAPPING[_shape]); } else { DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]); } } else { // FIXME, support instanced multi-shape rendering using multidraw indirect color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; auto geometryCache = DependencyManager::get<GeometryCache>(); auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { geometryCache->renderWireShapeInstance(args, batch, MAPPING[_shape], color, pipeline); } else { geometryCache->renderSolidShapeInstance(args, batch, MAPPING[_shape], color, pipeline); } } static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]); args->_details._trianglesRendered += (int)triCount; }
void RenderablePolyLineEntityItem::render(RenderArgs* args) { checkFading(); QWriteLocker lock(&_quadReadWriteLock); if (_points.size() < 2 || _normals.size () < 2 || _strokeWidths.size() < 2) { return; } if (!_pipeline) { createPipeline(); } if (!_texture || _texturesChangedFlag) { auto textureCache = DependencyManager::get<TextureCache>(); QString path = _textures.isEmpty() ? PathUtils::resourcesPath() + "images/paintStroke.png" : _textures; _texture = textureCache->getTexture(QUrl(path)); _texturesChangedFlag = false; } PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render"); Q_ASSERT(getType() == EntityTypes::PolyLine); Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; Transform transform = Transform(); transform.setTranslation(getPosition()); transform.setRotation(getRotation()); batch.setUniformBuffer(0, _uniformBuffer); batch.setModelTransform(transform); batch.setPipeline(_pipeline); if (_texture->isLoaded()) { batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture->getGPUTexture()); } else { batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, args->_whiteTexture); } batch.setInputFormat(_format); batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); if (_isFading) { batch._glColor4f(1.0f, 1.0f, 1.0f, Interpolate::calculateFadeRatio(_fadeStartTime)); } batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); };