int XunoGLSLFilter::addFBO(int scale, bool rotate) { int texture_width=0, texture_height=0; int prev_id=m_fbo.size()-1; if (prev_id<0){ texture_width=fbo()->size().width();//texture->width(); texture_height=fbo()->size().height();//texture->height(); //qDebug()<<"addFBO first original"<<texture_width<<texture_height; //qDebug()<<"addFBO first scaled "<<texture_width*scale<<texture_height*scale; }else{ texture_width=m_fbo[prev_id]->width(); texture_height=m_fbo[prev_id]->height(); //qDebug()<<"addFBO next original"<<texture_width<<texture_height; //qDebug()<<"addFBO next scaled "<<texture_width*scale<<texture_height*scale<<"prev_id"<<prev_id; } texture_width*=scale; texture_height*=scale; if (rotate){ int t=texture_width; texture_width=texture_height; texture_height=t; } QOpenGLFramebufferObject* cfbo = new QOpenGLFramebufferObject(texture_width,texture_height,QOpenGLFramebufferObject::NoAttachment,GL_TEXTURE_2D,GL_RGBA16); m_fbo.append(cfbo); return m_fbo.size()-1; }
void tst_QOpenGL::fboSimpleRendering() { QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; QVERIFY(ctx.create()); QVERIFY(ctx.makeCurrent(surface.data())); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); // No multisample with combined depth/stencil attachment: QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment); const QSize size(200, 100); QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(size, fboFormat)); QVERIFY(fbo->bind()); glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFinish(); const QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(fb.size(), size); QImage reference(size, QImage::Format_RGB32); reference.fill(0xffff0000); QFUZZY_COMPARE_IMAGES(fb, reference); }
GLuint fastuidraw::gl::detail::PainterBackendGL:: clear_buffers_of_current_surface(bool clear_depth, bool clear_color_buffer) { GLuint fbo(0); if (clear_depth || clear_color_buffer) { fastuidraw::c_array<const GLenum> draw_buffers; fbo = m_surface_gl->fbo(true); draw_buffers = m_surface_gl->draw_buffers(true); fastuidraw_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); fastuidraw_glDrawBuffers(draw_buffers.size(), draw_buffers.c_ptr()); if (clear_depth) { fastuidraw_glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0); } if (clear_color_buffer) { fastuidraw_glClearBufferfv(GL_COLOR, 0, m_surface_gl->m_clear_color.c_ptr()); } } return fbo; }
void XunoGLSLFilter::initTextures() { //qDebug()<<"hasOpenGLFramebufferBlit()"<<QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); // Load cube.png image //QImage image=QImage(":/savefbo_pass_0_1920x1080-empty-shader.bmp");//RAW_Yamaha_960x540.bmp //QImage image=QImage("/home/lex/temp/RAW_Yamaha_960x540.bmp"); QImage image=fbo()->toImage(false); //this->resize(image.size()); //qDebug()<<"After Resize"; if (texture!=Q_NULLPTR){ texture->release(texture->textureId(),QOpenGLTexture::ResetTextureUnit); delete texture; texture=Q_NULLPTR; } texture = new QOpenGLTexture(image);//.mirrored() // Set nearest filtering mode for texture minification texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); // Set bilinear filtering mode for texture magnification texture->setMagnificationFilter(QOpenGLTexture::Linear);//Linear Nearest // Wrap texture coordinates by repeating // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) texture->setWrapMode(QOpenGLTexture::Repeat); //qDebug()<<"Texture ID:"<<texture->textureId(); //image.save("/home/lex/temp/savefbo_manual_initTextures.bmp"); }
void tst_QOpenGL::openGLPaintDevice() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("QTBUG-22617"); #endif QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; QVERIFY(ctx.create()); QSurfaceFormat format = ctx.format(); if (format.majorVersion() < 2) QSKIP("This test requires at least OpenGL 2.0"); QVERIFY(ctx.makeCurrent(surface.data())); const QSize size(128, 128); QImage image(size, QImage::Format_RGB32); QPainter p(&image); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); QOpenGLFramebufferObject fbo(size); QVERIFY(fbo.bind()); QOpenGLPaintDevice device(size); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); QImage actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.drawImage(0, 0, image); p.end(); actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.fillRect(0, 0, image.width(), image.height(), QBrush(image)); p.end(); actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(image.size(), actual.size()); QCOMPARE(image, actual); }
QImage OpenGLCompositor::grab() { Q_ASSERT(m_context && m_targetWindow); m_context->makeCurrent(m_targetWindow); QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(m_targetWindow->geometry().size())); renderAll(fbo.data()); return fbo->toImage(); }
void output(char buf[], const all_tests& to) { std::ofstream fstr("test.raw"); ostream_buffer fbo(fstr); raw_format<ostream_buffer> rfo(fbo); obj_output<raw_format<ostream_buffer> > os(rfo); os.composite(to); }
void RenderSurface::render(QPainter *painter) { Q_UNUSED(painter); QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setSamples(1); fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); const QRect drawRect(0, 0, m_outWidth, m_outHeight); const QSize drawRectSize = drawRect.size(); QOpenGLFramebufferObject fbo(drawRectSize, fboFormat); fbo.bind(); glViewport(0, 0, m_outWidth, m_outHeight); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ONE); m_program->bind(); int texCount = 0; for (size_t i = 0; i < sp.size(); ++i) { if (sp[i].bind == ShaderParameter::BindTextureSampler) { textures[sp[i].name].obj->bind(texCount); m_program->setUniformValue(sp[i].name.c_str(), texCount); texCount++; } else if (sp[i].bind == ShaderParameter::BindTextureResolution) { const QImage& image = textures[sp[i].texture].image; m_program->setUniformValue(sp[i].name.c_str(), QVector2D(image.width(),image.height())); } else if (sp[i].bind == ShaderParameter::BindGlobalTime) { m_program->setUniformValue(sp[i].name.c_str(), m_globalTime); } else if (sp[i].bind == ShaderParameter::BindOutputResolution) { m_program->setUniformValue(sp[i].name.c_str(), QVector2D(m_outWidth,m_outHeight)); } } GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(0); m_program->release(); imageFrame = fbo.toImage(); }
void XunoGLSLFilter::beforeRendering() { //qDebug()<<"XunoGLSLFilter::beforeRendering"<<fbo()->size(); colorTransform(); // return; if (fbo() && fbo()->isValid()){ QOpenGLFunctions *f=opengl()->openGLContext()->functions(); if (f && fbo()->textures().size()){ GLenum target=GL_TEXTURE_2D; f->glBindTexture(target,fbo()->texture()); //f->glGenerateMipmap(target); f->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); f->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //f->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //f->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); f->glBindTexture(target,0); } } }
void SaveViewFromFbo(std::string prefix, View& view, float scale) { PANGOLIN_UNUSED(prefix); #ifndef HAVE_GLES const Viewport orig = view.v; view.v.l = 0; view.v.b = 0; view.v.w = (int)(view.v.w * scale); view.v.h = (int)(view.v.h * scale); const int w = view.v.w; const int h = view.v.h; float origLineWidth; glGetFloatv(GL_LINE_WIDTH, &origLineWidth); glLineWidth(origLineWidth * scale); float origPointSize; glGetFloatv(GL_POINT_SIZE, &origPointSize); glPointSize(origPointSize * scale); // Create FBO GlTexture color(w,h); GlRenderBuffer depth(w,h); GlFramebuffer fbo(color, depth); // Render into FBO fbo.Bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); view.Render(); glFlush(); #ifdef HAVE_PNG const PixelFormat fmt = PixelFormatFromString("RGBA32"); TypedImage buffer(w, h, fmt ); glReadBuffer(GL_BACK); glPixelStorei(GL_PACK_ALIGNMENT, 1); // TODO: Avoid this? glReadPixels(0,0,w,h, GL_RGBA, GL_UNSIGNED_BYTE, buffer.ptr ); SaveImage(buffer, fmt, prefix + ".png", false); #endif // HAVE_PNG // unbind FBO fbo.Unbind(); // restore viewport / line width view.v = orig; glLineWidth(origLineWidth); glPointSize(origPointSize); #endif // HAVE_GLES }
void OpenGLWidget::slotSendImage(){ makeCurrent(); QOpenGLFramebufferObject fbo(240, 780); glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION); glPushMatrix(); glViewport(0, 0, 240,780); glMatrixMode(GL_PROJECTION); fbo.bind(); paintImg(imgOrig); emit signalSendImage(new QImage(fbo.toImage())); }
bool SupportedCombinationTest::tryCombination (const FormatCombination& comb) { glu::Framebuffer fbo(m_ctx.getRenderContext()); FboBuilder builder(*fbo, GL_FRAMEBUFFER, fboc::gl(*this)); attachTargetToNew(GL_COLOR_ATTACHMENT0, comb.colorKind, comb.colorFmt, 64, 64, builder); attachTargetToNew(GL_DEPTH_ATTACHMENT, comb.depthKind, comb.depthFmt, 64, 64, builder); attachTargetToNew(GL_STENCIL_ATTACHMENT, comb.stencilKind, comb.stencilFmt, 64, 64, builder); const GLenum glStatus = fboc::gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER); return (glStatus == GL_FRAMEBUFFER_COMPLETE); }
osg::FrameBufferObject* createDestinationFBO() { osg::ref_ptr< osg::Texture2D > tex( new osg::Texture2D ); tex->setTextureSize( 1920, 1200 ); tex->dirtyTextureObject(); tex->setInternalFormat( GL_RGBA ); tex->setBorderWidth( 0 ); tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST ); tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST ); osg::ref_ptr< osg::FrameBufferObject > fbo( new osg::FrameBufferObject ); fbo->setAttachment( osg::Camera::COLOR_BUFFER0, osg::FrameBufferAttachment( tex.get() ) ); // backdropFX doesn't output depth buffer, so no need to specify it. return( fbo.release() ); }
// NOTE: This tests that CombinedDepthStencil attachment works by assuming the // GL2 engine is being used and is implemented the same way as it was when // this autotest was written. If this is not the case, there may be some // false-positives: I.e. The test passes when either the depth or stencil // buffer is actually missing. But that's probably ok anyway. void tst_QOpenGL::fboRendering() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("QTBUG-22617"); #endif QFETCH(int, surfaceClass); QScopedPointer<QSurface> surface(createSurface(surfaceClass)); QOpenGLContext ctx; QVERIFY(ctx.create()); QVERIFY(ctx.makeCurrent(surface.data())); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); // No multisample with combined depth/stencil attachment: QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); // Uncomplicate things by using NPOT: const QSize size(256, 128); QOpenGLFramebufferObject fbo(size, fboFormat); if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil) QSKIP("FBOs missing combined depth~stencil support"); QVERIFY(fbo.bind()); QPainter fboPainter; QOpenGLPaintDevice device(fbo.width(), fbo.height()); bool painterBegun = fboPainter.begin(&device); QVERIFY(painterBegun); qt_opengl_draw_test_pattern(&fboPainter, fbo.width(), fbo.height()); fboPainter.end(); const QImage fb = fbo.toImage().convertToFormat(QImage::Format_RGB32); QCOMPARE(fb.size(), size); qt_opengl_check_test_pattern(fb); }
void FullscreenPass::render_scene(Camera const& camera, SceneGraph const&, RenderContext const& ctx, std::size_t view) { if (!depth_stencil_state_) depth_stencil_state_ = ctx.render_device ->create_depth_stencil_state(false, false, scm::gl::COMPARISON_NEVER); if (!fullscreen_quad_) fullscreen_quad_ = scm::gl::quad_geometry_ptr(new scm::gl::quad_geometry( ctx.render_device, math::vec2(-1.f, -1.f), math::vec2(1.f, 1.f))); set_uniforms(pipeline_->get_current_scene(CameraMode::CENTER), ctx); for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) { CameraMode eye(CameraMode::CENTER); if (gbuffer_->get_eye_buffers().size() > 1 && i == 0) eye = CameraMode::LEFT; if (gbuffer_->get_eye_buffers().size() > 1 && i == 1) eye = CameraMode::RIGHT; pre_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx); FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]); fbo->bind(ctx); ctx.render_context->set_viewport(scm::gl::viewport( math::vec2(0, 0), math::vec2(float(fbo->width()), float(fbo->height())))); ctx.render_context->set_depth_stencil_state(depth_stencil_state_); rendering(camera, pipeline_->get_current_scene(eye), eye, ctx); ctx.render_context->reset_state_objects(); fbo->unbind(ctx); post_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx); } }
void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) QSKIP("QTBUG-22617"); #endif QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); window.setGeometry(0, 0, 128, 128); window.create(); QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(&window); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); QOpenGLFramebufferObject fbo(128, 128); fbo.bind(); QOpenGLPaintDevice device(128, 128); // QTBUG-15621 is only a problem when qreal is double, but do the test anyway. qreal delta = sizeof(qreal) == sizeof(float) ? 1e-4 : 1e-8; QVERIFY(128 != 128 + delta); QPainterPath path; path.moveTo(16 + delta, 16); path.moveTo(16, 16); path.lineTo(16 + delta, 16); // Short lines to check for division by zero. path.lineTo(112 - delta, 16); path.lineTo(112, 16); path.quadTo(112, 16, 112, 16 + delta); path.quadTo(112, 64, 112, 112 - delta); path.quadTo(112, 112, 112, 112); path.cubicTo(112, 112, 112, 112, 112 - delta, 112); path.cubicTo(80, 112, 48, 112, 16 + delta, 112); path.cubicTo(16 + delta, 112, 16 + delta, 112, 16, 112); path.closeSubpath(); QPen pen(Qt::red, 28, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); QPainter p(&device); p.fillRect(QRect(0, 0, 128, 128), Qt::blue); p.strokePath(path, pen); p.end(); QImage image = fbo.toImage().convertToFormat(QImage::Format_RGB32); const QRgb red = 0xffff0000; const QRgb blue = 0xff0000ff; QCOMPARE(image.pixel(8, 8), red); QCOMPARE(image.pixel(119, 8), red); QCOMPARE(image.pixel(8, 119), red); QCOMPARE(image.pixel(119, 119), red); QCOMPARE(image.pixel(0, 0), blue); QCOMPARE(image.pixel(127, 0), blue); QCOMPARE(image.pixel(0, 127), blue); QCOMPARE(image.pixel(127, 127), blue); QCOMPARE(image.pixel(32, 32), blue); QCOMPARE(image.pixel(95, 32), blue); QCOMPARE(image.pixel(32, 95), blue); QCOMPARE(image.pixel(95, 95), blue); }
void XunoGLSLFilter::afterRendering() { //qDebug()<<"XunoGLSLFilter::afterRendering()"; //return; lastSuperscaleTexureId=0; pass=0; if (fbo() && fbo()->isValid() ) { //need save image after rendering if (needSave){ QString name=defineFileName(); if (name.isEmpty()) name=savePath.append(QString("SaveFBOafterRendering-%1.tif").arg(QDateTime().currentMSecsSinceEpoch())); qDebug()<<"XunoGLSLFilter::afterRendering() fbo size() saving"<<fbo()->size()<<name; //SAVE FBO for text result; QImage s=fbo()->toImage(false); //QMatrix matrix = QMatrix().scale(1,-1); //OpenGL rotate; //s.transformed(matrix).save(name); if (m_player->videoCapture()->quality()>0){ s.save(name,Q_NULLPTR,m_player->videoCapture()->quality()); }else{ s.save(name); } needSave=false; } //clear custom programs and fbos while (m_fbo.size()) { delete m_fbo.takeLast(); } while (programs.size()) { delete programs.takeLast(); } //need superscale image after rendering and replace fbo for show by opengl if (0 && needSuperScale){ superscale(2.0f,1.0f); } GLuint sfbotextid; if (1){ sfbotextid=sharpShader(frameTexture()); if (sfbotextid) lastSuperscaleTexureId=sfbotextid; } needAdaptiveSharpen=needSuperScale; if (0 && needAdaptiveSharpen){ sfbotextid=adaptiveSharpen(frameTexture()); if (sfbotextid) lastSuperscaleTexureId=sfbotextid; } //fxaa if (needToUseFXAAFiltering){ sfbotextid=fxaaShader(frameTexture()); if (sfbotextid) lastSuperscaleTexureId=sfbotextid; } //need last linear filtering image if (needSuperScaleLastLinearFiltering){ QOpenGLFunctions *f=opengl()->openGLContext()->functions(); if (f && fbo()->textures().size()){ GLenum target=GL_TEXTURE_2D; f->glBindTexture(target,frameTexture()); //f->glGenerateMipmap(target); //TextureMinFilter //#define GL_NEAREST_MIPMAP_NEAREST 0x2700 //#define GL_LINEAR_MIPMAP_NEAREST 0x2701 //#define GL_NEAREST_MIPMAP_LINEAR 0x2702 //#define GL_LINEAR_MIPMAP_LINEAR 0x2703 f->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); f->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//GL_LINEAR //GL_LINEAR_MIPMAP_LINEAR f->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); f->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); f->glBindTexture(target,0); } } } }
//virtual void VirtualCamera::trigger() { //if either the size is 0,0 or the pixmap is null, then setup hasn't run (successfully) so bail // if ((m_viewport.isEmpty()) || (!m_qp_pix)) // { // qDebug() << __FUNCTION__ << ": failed. Re-run setup()"; // return; // } if (!m_triggerAble) { qDebug() << __FUNCTION__ << ": failed. Re-run setup()"; return; } QSize psize; if (GraphicsSettings::settings()->useFixedVCamPixSize) { psize = GraphicsSettings::settings()->fixedVCamPixSize; } else { psize = QSize(qMin((quint32)GraphicsSettings::settings()->maxVCamPixSize.width(),(quint32)m_viewport.width()), qMin((quint32)GraphicsSettings::settings()->maxVCamPixSize.height(),(quint32)m_viewport.height())); } qDebug() << "Vcam using output size of " << psize; qDebug() << "Viewport is: " << m_viewport; qreal Xscale = (GraphicsSettings::settings()->vCamHorizontalFlip ? -1.0 : 1.0); qreal Yscale = (GraphicsSettings::settings()->vCamVerticalFlip ? -1.0 : 1.0); #if defined(HAVE_OPENGL) && defined(TARGET_DEVICE) QGLContext* gc = (QGLContext*) QGLContext::currentContext(); if (!gc) { qDebug() << __FUNCTION__ << ": couldn't get QGL context. exiting."; return; } QGLFramebufferObject fbo(psize.width(),psize.height()); fbo.bind(); QPainter painter(&fbo); painter.scale(Xscale,Yscale); render(&painter); painter.end(); m_img = fbo.toImage(); fbo.release(); #else QPixmap pix(psize.width(),psize.height()); QPainter painter(&pix); painter.scale(Xscale,Yscale); render(&painter); painter.end(); m_img = pix.toImage(); #endif if (GraphicsSettings::settings()->dbgSaveVcamOutput) { m_img.save(QString("/media/internal/camerasave.png"),0,100); } }
void SkyDomeStage::draw( osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous ) { if( _stageDrawnThisFrame ) return; _stageDrawnThisFrame = true; osg::notify( osg::DEBUG_INFO ) << "backdropFX: SkyDomeStage::draw" << std::endl; // Fix for redmine 434. Camera must be set in renderInfo. // Required for any draw-time code that queries the camera // from renderInfo, such as OcclusionQueryNode. // The parent camera/RenderStage doesn't do this because we // are pre-render stages; it hasn't had a chance yet. if( _camera ) renderInfo.pushCamera( _camera ); osg::State& state( *renderInfo.getState() ); const unsigned int contextID( state.getContextID() ); osg::FBOExtensions* fboExt( osg::FBOExtensions::instance( contextID, true ) ); if( fboExt == NULL ) { osg::notify( osg::WARN ) << "backdropFX: SDS: FBOExtensions == NULL." << std::endl; return; } // Bind the FBO. osg::FrameBufferObject* fbo( _backdropCommon->getFBO() ); if( fbo != NULL ) { fbo->apply( state ); } else { osgwTools::glBindFramebuffer( fboExt, GL_DRAW_FRAMEBUFFER_EXT, 0 ); osgwTools::glBindFramebuffer( fboExt, GL_READ_FRAMEBUFFER_EXT, 0 ); } state.applyAttribute( getViewport() ); // Draw { UTIL_GL_ERROR_CHECK( "SDS pre performClear()" ); _backdropCommon->performClear( renderInfo ); if( _enable ) { UTIL_GL_ERROR_CHECK( "SDS pre drawImplementation()" ); RenderBin::drawImplementation( renderInfo, previous ); } // I believe this has the net result of restoring OpenGL to the // current state at the corresponding SkyDome node. //state.apply(); } const bool dumpImages = ( ( _backdropCommon->getDebugMode() & backdropFX::BackdropCommon::debugImages ) != 0 ); if( dumpImages ) { osg::Viewport* vp = getViewport(); GLint x( 0 ), y( 0 ); GLsizei w, h; if( vp != NULL ) { w = vp->width(); h = vp->height(); } else { osg::notify( osg::WARN ) << "BDFX: SkyDome: Null viewport dumping images. Using 512x512." << std::endl; w = h = 512; } const std::string fileName( createFileName( contextID ) ); char* pixels = new char[ w * h * 4 ]; glReadPixels( x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pixels ); backdropFX::debugDumpImage( fileName, pixels, w, h ); delete[] pixels; } if( state.getCheckForGLErrors() != osg::State::NEVER_CHECK_GL_ERRORS ) { std::string msg( "at SDS draw end" ); UTIL_GL_ERROR_CHECK( msg ); UTIL_GL_FBO_ERROR_CHECK( msg, fboExt ); } // Fix for redmine 434. See SkyDomeStage::draw() for more info. if( _camera ) renderInfo.popCamera(); }
//opt_sharpness [0...2] default 1.0f //opt_edge_strength [0...1] default 0.6f void XunoGLSLFilter::superscale(GLfloat opt_sharpness, GLfloat opt_edge_strength) { if ( geometries==Q_NULLPTR) geometries = new GeometryEngine; QOpenGLFunctions *f=opengl()->openGLContext()->functions(); if (!f) return; //if (initSize.isEmpty()){ initSize=outputSize(); //} //qDebug()<<"superscale" << initSize; //setOutputSize(initSize*2); //qDebug()<<"superscale x2" << outputSize(); //initTextures(); frame++; // Enable depth buffer f->glEnable(GL_DEPTH_TEST); // Enable back face culling // QtAV move freeze with it. //f->glEnable(GL_CULL_FACE); //--------------------------------------------- //GLuint fbotextid=texture->textureId(); GLuint fbotextid=fbo()->texture(); //used last fbo of player as source frame //qDebug()<<"Texture id start"<<fbotextid<<"texure size:"<<texture->width()<<"x"<<texture->height(); for (pass=0;pass<=maxPass;pass++){ bool rotate=false;//(pass>0); //qDebug()<<"Programs:"<< addProgram(); if (initShaders_xbr(pass) && !scales.isEmpty()){ int fboID=addFBO(scales.at(pass),/*rotate*/0); QOpenGLShaderProgram *program=Q_NULLPTR; if (pass<=programs.size()){ program=programs.at(pass); } m_fbo[fboID]->bind(); f->glViewport(0,0,m_fbo[fboID]->width(),m_fbo[fboID]->height()); // Use texture unit 0 which contains cube.png program->bind(); //qDebug()<<"texture0 is"; program->setUniformValue("texture0", 0); QVector2D textureSize=QVector2D (float(m_fbo[fboID]->width()),float(m_fbo[fboID]->height())); //qDebug()<<"texture_size0 is"; program->setUniformValue("texture_size0", textureSize); //qDebug()<<"pixel_size0 is"; program->setUniformValue("pixel_size0", QVector2D(1.0f,1.0f)/textureSize); //qDebug()<<"texture_rot0 is"; program->setUniformValue("texture_rot0", QVector2D(0.0f,0.0f)); //options program->setUniformValue("sharpness", opt_sharpness); // [0...2] default 1.0f program->setUniformValue("edge_strength",opt_edge_strength); // [0...1] default 0.6f QMatrix4x4 matrix; matrix.setToIdentity(); if (rotate) { int sign=(pass==2)?-1:1; matrix.rotate(180*sign,0.,0.,1.); } program->setUniformValue("MVPMatrix", matrix); //if (1) { //if (0){ //pass==0 // f->glActiveTexture(GL_TEXTURE0); // texture->bind(); //}else{ f->glActiveTexture(GL_TEXTURE0); f->glBindTexture(GL_TEXTURE_2D, fbotextid); f->glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//GL_NEAREST GL_LINEAR f->glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);//GL_CLAMP_TO_EDGE //f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); //} f->glClearColor(1.0,0.0,0.0,1.0);//RED f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw cube geometry geometries->drawCubeGeometry(program); // if (0){//pass==0 // texture->release(); // }else{ f->glBindTexture(GL_TEXTURE_2D, 0); // } // } program->release(); m_fbo[fboID]->release(); #if (unix) // QString filename=QString("/home/lex/temp/savefbo_pass_%1_%2x%3-%4.bmp").arg(pass).arg(m_fbo[fboID]->width()).arg(m_fbo[fboID]->height()).arg(frame); #else // QString filename=QString("e:/temp/shader/savefbo_pass_%1_%2x%3-%4.bmp").arg(pass).arg(m_fbo[fboID]->width()).arg(m_fbo[fboID]->height()).arg(frame); #endif // qDebug()<<"Saving:"<<filename; // m_fbo[fboID]->toImage(false).save(filename); fbotextid=m_fbo[fboID]->texture(); //qDebug()<<"Texture id"<<fbotextid<<"texure size:"<<m_fbo[fboID]->width()<<"x"<<m_fbo[fboID]->height(); }else{ qDebug()<<"initShaders error (pass)"<<pass; } } if (fbotextid) lastSuperscaleTexureId=fbotextid; }
int indexAt( /*GLuint *buffer,*/ NifModel * model, Scene * scene, QList<DrawFunc> drawFunc, int cycle, const QPoint & pos, int & furn ) { Q_UNUSED( model ); Q_UNUSED( cycle ); // Color Key O(1) selection // Open GL 3.0 says glRenderMode is deprecated // ATI OpenGL API implementation of GL_SELECT corrupts NifSkope memory // // Create FBO for sharp edges and no shading. // Texturing, blending, dithering, lighting and smooth shading should be disabled. // The FBO can be used for the drawing operations to keep the drawing operations invisible to the user. GLint viewport[4]; glGetIntegerv( GL_VIEWPORT, viewport ); // Create new FBO with multisampling disabled QOpenGLFramebufferObjectFormat fboFmt; fboFmt.setTextureTarget( GL_TEXTURE_2D ); fboFmt.setInternalTextureFormat( GL_RGB32F_ARB ); fboFmt.setAttachment( QOpenGLFramebufferObject::Attachment::CombinedDepthStencil ); QOpenGLFramebufferObject fbo( viewport[2], viewport[3], fboFmt ); fbo.bind(); glEnable( GL_LIGHTING ); glDisable( GL_MULTISAMPLE ); glDisable( GL_MULTISAMPLE_ARB ); glDisable( GL_LINE_SMOOTH ); glDisable( GL_POINT_SMOOTH ); glDisable( GL_POLYGON_SMOOTH ); glDisable( GL_TEXTURE_1D ); glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_3D ); glDisable( GL_BLEND ); glDisable( GL_DITHER ); glDisable( GL_FOG ); glDisable( GL_LIGHTING ); glShadeModel( GL_FLAT ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); glClearColor( 0, 0, 0, 1 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Rasterize the scene Node::SELECTING = 1; for ( DrawFunc df : drawFunc ) { (scene->*df)(); } Node::SELECTING = 0; fbo.release(); QImage img( fbo.toImage() ); QColor pixel = img.pixel( pos ); #ifndef QT_NO_DEBUG img.save( "fbo.png" ); #endif // Encode RGB to Int int a = 0; a |= pixel.red() << 0; a |= pixel.green() << 8; a |= pixel.blue() << 16; // Decode: // R = (id & 0x000000FF) >> 0 // G = (id & 0x0000FF00) >> 8 // B = (id & 0x00FF0000) >> 16 int choose = COLORKEY2ID( a ); // Pick BSFurnitureMarker if ( choose > 0 ) { auto furnBlock = model->getBlock( model->index( 3, 0, model->getBlock( choose & 0x0ffff ) ), "BSFurnitureMarker" ); if ( furnBlock.isValid() ) { furn = choose >> 16; choose &= 0x0ffff; }
void OpenGLViewer::setsize(int width, int height) { //Resize fbo if (fbo_enabled) fbo(width, height); }
QSGNode* BrowserUtils::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData) { Q_UNUSED(updatePaintNodeData); if (!(m_webview && (flags() & QQuickItem::ItemHasContents))) { return oldNode; } setFlag(QQuickItem::ItemHasContents, false); #if 0 QQuickWebPage* page = m_webview->page(); qreal xmin = qMin(page->width(), m_webview->width()); qreal ymin = qMin(m_webview->height(), page->height()); #else // Here the screenshot of the page might be too large if the page is tiny qreal xmin = m_webview->width(); qreal ymin = m_webview->height(); #endif ymin = qMin(static_cast<int>(ymin), m_imageSize.height()); xmin = qMin(static_cast<int>(xmin), m_imageSize.width()); QSize size(xmin, ymin); QSGNode* node = QQuickItemPrivate::get(m_webview)->itemNode(); QSGNode* parent = node->QSGNode::parent(); QSGNode* previousSibling = node->previousSibling(); if (parent) { parent->removeChildNode(node); } QSGRootNode root; root.appendChildNode(node); QSGRenderer* renderer; #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) renderer = QQuickItemPrivate::get(this)->sceneGraphContext()->createRenderer(); #else renderer = QQuickItemPrivate::get(this)->sceneGraphRenderContext()->createRenderer(); #endif renderer->setRootNode(static_cast<QSGRootNode*>(&root)); QOpenGLFramebufferObject fbo(size); renderer->setDeviceRect(size); renderer->setViewportRect(size); renderer->setProjectionMatrixToRect(QRectF(QPointF(), size)); renderer->setClearColor(Qt::transparent); renderer->renderScene(BindableFbo(&fbo)); fbo.release(); QImage image = fbo.toImage().scaled(m_imageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); QFileInfo imageInfo(m_outFile); QDir imageDir(imageInfo.path()); if (!imageDir.exists()) { imageDir.mkpath("."); } bool saved = image.save(m_outFile); root.removeChildNode(node); renderer->setRootNode(0); delete renderer; if (parent) { if (previousSibling) { parent->insertChildNodeAfter(node, previousSibling); } else { parent->prependChildNode(node); } } Q_EMIT webViewSaved(saved, m_outFile); return oldNode; }
int main(int argc, char **argv) { #ifdef CONSOLE_APPLICATION QApplication app(argc, argv, QApplication::Tty); #else QApplication app(argc, argv); #endif #ifdef DO_QWS_DEBUGGING qt_show_painter_debug_output = false; #endif DeviceType type = WidgetType; bool checkers_background = true; QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied; QLocale::setDefault(QLocale::c()); QStringList files; bool interactive = false; bool printdlg = false; bool highres = false; bool show_cmp = false; int width = 800, height = 800; int scaledWidth = width, scaledHeight = height; qreal scalefactor = 1.0; bool verboseMode = false; #ifndef QT_NO_OPENGL QGLFormat f = QGLFormat::defaultFormat(); f.setSampleBuffers(true); f.setStencil(true); f.setAlpha(true); f.setAlphaBufferSize(8); QGLFormat::setDefaultFormat(f); #endif char *arg; for (int i=1; i<argc; ++i) { arg = argv[i]; if (*arg == '-') { QString option = QString(arg + 1).toLower(); if (option == "widget") type = WidgetType; else if (option == "bitmap") type = BitmapType; else if (option == "pixmap") type = PixmapType; else if (option == "image") type = ImageType; else if (option == "imageformat") { Q_ASSERT_X(i + 1 < argc, "main", "-imageformat must be followed by a value"); QString format = QString(argv[++i]).toLower(); imageFormat = QImage::Format_Invalid; static const int formatCount = sizeof(imageFormats) / sizeof(imageFormats[0]); for (int ff = 0; ff < formatCount; ++ff) { if (QLatin1String(imageFormats[ff].name) == format) { imageFormat = imageFormats[ff].format; break; } } if (imageFormat == QImage::Format_Invalid) { printf("Invalid image format. Available formats are:\n"); for (int ff = 0; ff < formatCount; ++ff) printf("\t%s\n", imageFormats[ff].name); return -1; } } else if (option == "imagemono") type = ImageMonoType; else if (option == "imagewidget") type = ImageWidgetType; #ifndef QT_NO_OPENGL else if (option == "opengl") type = OpenGLType; else if (option == "glbuffer") type = OpenGLBufferType; #endif #ifdef USE_CUSTOM_DEVICE else if (option == "customdevice") type = CustomDeviceType; else if (option == "customwidget") type = CustomWidgetType; #endif else if (option == "pdf") type = PdfType; else if (option == "ps") type = PsType; else if (option == "picture") type = PictureType; else if (option == "printer") type = PrinterType; else if (option == "highres") { type = PrinterType; highres = true; } else if (option == "printdialog") { type = PrinterType; printdlg = true; } else if (option == "grab") type = GrabType; else if (option == "i") interactive = true; else if (option == "v") verboseMode = true; else if (option == "commands") { displayCommands(); return 0; } else if (option == "w") { Q_ASSERT_X(i + 1 < argc, "main", "-w must be followed by a value"); width = atoi(argv[++i]); } else if (option == "h") { Q_ASSERT_X(i + 1 < argc, "main", "-h must be followed by a value"); height = atoi(argv[++i]); } else if (option == "scalefactor") { Q_ASSERT_X(i + 1 < argc, "main", "-scalefactor must be followed by a value"); scalefactor = atof(argv[++i]); } else if (option == "cmp") { show_cmp = true; } else if (option == "bg-white") { checkers_background = false; } } else { #if defined (Q_WS_WIN) QString input = QString::fromLocal8Bit(argv[i]); if (input.indexOf('*') >= 0) { QFileInfo info(input); QDir dir = info.dir(); QFileInfoList infos = dir.entryInfoList(QStringList(info.fileName())); for (int ii=0; ii<infos.size(); ++ii) files.append(infos.at(ii).absoluteFilePath()); } else { files.append(input); } #else files.append(QString(argv[i])); #endif } } scaledWidth = width * scalefactor; scaledHeight = height * scalefactor; PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); QWidget *activeWidget = 0; if (interactive) { runInteractive(); if (!files.isEmpty()) interactive_widget->load(files.at(0)); } else if (files.isEmpty()) { printHelp(); return 0; } else { for (int j=0; j<files.size(); ++j) { const QString &fileName = files.at(j); QStringList content; QFile file(fileName); QFileInfo fileinfo(file); if (file.open(QIODevice::ReadOnly)) { QTextStream textFile(&file); QString script = textFile.readAll(); content = script.split("\n", QString::SkipEmptyParts); } else { printf("failed to read file: '%s'\n", qPrintable(fileinfo.absoluteFilePath())); continue; } pcmd.setContents(content); if (show_cmp) { QString pmFile = QString(files.at(j)).replace(".qps", "_qps") + ".png"; qDebug() << pmFile << QFileInfo(pmFile).exists(); QPixmap pixmap(pmFile); if (!pixmap.isNull()) { QLabel *label = createLabel(); label->setWindowTitle("VERIFY: " + pmFile); label->setPixmap(pixmap); label->show(); } } switch (type) { case WidgetType: { OnScreenWidget<QWidget> *qWidget = new OnScreenWidget<QWidget>(files.at(j)); qWidget->setVerboseMode(verboseMode); qWidget->setType(type); qWidget->setCheckersBackground(checkers_background); qWidget->m_commands = content; qWidget->resize(width, height); qWidget->show(); activeWidget = qWidget; break; } case ImageWidgetType: { OnScreenWidget<QWidget> *qWidget = new OnScreenWidget<QWidget>(files.at(j)); qWidget->setVerboseMode(verboseMode); qWidget->setType(type); qWidget->setCheckersBackground(checkers_background); qWidget->m_commands = content; qWidget->resize(width, height); qWidget->show(); activeWidget = qWidget; break; } #ifndef QT_NO_OPENGL case OpenGLBufferType: { QWindow win; win.setSurfaceType(QSurface::OpenGLSurface); win.create(); QOpenGLFramebufferObjectFormat fmt; fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); fmt.setSamples(4); QOpenGLContext ctx; ctx.create(); ctx.makeCurrent(&win); QOpenGLFramebufferObject fbo(width, height, fmt); fbo.bind(); QOpenGLPaintDevice pdev(width, height); QPainter pt(&pdev); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image = fbo.toImage(); QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case OpenGLType: { OnScreenWidget<QGLWidget> *qGLWidget = new OnScreenWidget<QGLWidget>(files.at(j)); qGLWidget->setVerboseMode(verboseMode); qGLWidget->setType(type); qGLWidget->setCheckersBackground(checkers_background); qGLWidget->m_commands = content; qGLWidget->resize(width, height); qGLWidget->show(); activeWidget = qGLWidget; break; } #else case OpenGLType: case OpenGLBufferType: { printf("OpenGL type not supported in this Qt build\n"); break; } #endif #ifdef USE_CUSTOM_DEVICE case CustomDeviceType: { CustomPaintDevice custom(width, height); QPainter pt; pt.begin(&custom); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage *img = custom.image(); if (img) { QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(*img)); label->resize(label->sizeHint()); label->show(); activeWidget = label; img->save("custom_output_pixmap.png", "PNG"); } else { custom.save("custom_output_pixmap.png", "PNG"); } break; } case CustomWidgetType: { OnScreenWidget<CustomWidget> *cWidget = new OnScreenWidget<CustomWidget>; cWidget->setVerboseMode(verboseMode); cWidget->setType(type); cWidget->setCheckersBackground(checkers_background); cWidget->m_filename = files.at(j); cWidget->setWindowTitle(fileinfo.filePath()); cWidget->m_commands = content; cWidget->resize(width, height); cWidget->show(); activeWidget = cWidget; break; } #endif case PixmapType: { QPixmap pixmap(scaledWidth, scaledHeight); pixmap.setDevicePixelRatio(scalefactor); pixmap.fill(Qt::white); QPainter pt(&pixmap); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); pixmap.save("output_pixmap.png", "PNG"); break; } case BitmapType: { QBitmap bitmap(scaledWidth, scaledHeight); bitmap.setDevicePixelRatio(scalefactor); QPainter pt(&bitmap); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); bitmap.save("output_bitmap.png", "PNG"); QLabel *label = createLabel(); label->setPixmap(bitmap); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case ImageMonoType: case ImageType: { qDebug() << "Creating image"; QImage image(scaledWidth, scaledHeight, type == ImageMonoType ? QImage::Format_MonoLSB : imageFormat); image.setDevicePixelRatio(scalefactor); image.fill(0); QPainter pt(&image); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); image.convertToFormat(QImage::Format_ARGB32).save("output_image.png", "PNG"); image.setDevicePixelRatio(1.0); // reset scale factor: display "large" image. #ifndef CONSOLE_APPLICATION QLabel *label = createLabel(); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; #endif break; } case PictureType: { QPicture pic; QPainter pt(&pic); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image(width, height, QImage::Format_ARGB32_Premultiplied); image.fill(0); pt.begin(&image); pt.drawPicture(0, 0, pic); pt.end(); QLabel *label = createLabel(); label->setWindowTitle(fileinfo.absolutePath()); label->setPixmap(QPixmap::fromImage(image)); label->resize(label->sizeHint()); label->show(); activeWidget = label; break; } case PrinterType: { #ifndef QT_NO_PRINTER PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); pcmd.setContents(content); QString file = QString(files.at(j)).replace(".", "_") + ".ps"; QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution); if (printdlg) { QPrintDialog printDialog(&p, 0); if (printDialog.exec() != QDialog::Accepted) break; } else { p.setOutputFileName(file); } QPainter pt(&p); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); if (!printdlg) { printf("wrote file: %s\n", qPrintable(file)); } Q_ASSERT(!p.paintingActive()); #endif break; } case PsType: case PdfType: { #ifndef QT_NO_PRINTER PaintCommands pcmd(QStringList(), 800, 800); pcmd.setVerboseMode(verboseMode); pcmd.setType(type); pcmd.setCheckersBackground(checkers_background); pcmd.setContents(content); QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution); QFileInfo input(files.at(j)); const QString file = input.baseName() + QLatin1Char('_') + input.suffix() + QStringLiteral(".pdf"); p.setOutputFormat(QPrinter::PdfFormat); p.setOutputFileName(file); p.setPageSize(QPrinter::A4); QPainter pt(&p); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); printf("write file: %s\n", qPrintable(file)); #endif break; } case GrabType: { QImage image(width, height, QImage::Format_ARGB32_Premultiplied); image.fill(QColor(Qt::white).rgb()); QPainter pt(&image); pcmd.setPainter(&pt); pcmd.setFilePath(fileinfo.absolutePath()); pcmd.runCommands(); pt.end(); QImage image1(width, height, QImage::Format_RGB32); image1.fill(QColor(Qt::white).rgb()); QPainter pt1(&image1); pt1.drawImage(QPointF(0, 0), image); pt1.end(); QString filename = QString(files.at(j)).replace(".qps", "_qps") + ".png"; image1.save(filename, "PNG"); printf("%s grabbed to %s\n", qPrintable(files.at(j)), qPrintable(filename)); break; } default: break; } } } #ifndef CONSOLE_APPLICATION if (activeWidget || interactive) { QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); app.exec(); } delete activeWidget; #endif delete interactive_widget; return 0; }
int main() { DEBUGLOG->setAutoPrint(true); ////////////////////////////////////////////////////////////////////////////// /////////////////////// INIT ////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // create window and opengl context auto window = generateWindow(800,800); ////////////////////////////////////////////////////////////////////////////// /////////////////////////////// RENDERING /////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ///////////////////// Scene / View Settings ////////////////////////// glm::mat4 model = glm::mat4(1.0f); glm::vec4 eye(0.0f, 0.0f, 3.0f, 1.0f); glm::vec4 center(0.0f,0.0f,0.0f,1.0f); glm::mat4 view = glm::lookAt(glm::vec3(eye), glm::vec3(center), glm::vec3(0,1,0)); // glm::mat4 perspective = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, -1.0f, 6.0f); /// perspective projection is experimental; yields weird warping effects due to vertex interpolation of uv-coordinates glm::mat4 perspective = glm::perspective(glm::radians(65.f), getRatio(window), 0.1f, 10.f); // create object // Sphere grid; Grid grid(10,10,0.1f,0.1f,true); // Volume grid; // load grass texture s_texHandle = TextureTools::loadTexture(RESOURCES_PATH + std::string( "/grass.png")); glBindTexture(GL_TEXTURE_2D, s_texHandle); /////////////////////// Renderpass /////////////////////////// DEBUGLOG->log("Shader Compilation: volume uvw coords"); DEBUGLOG->indent(); ShaderProgram shaderProgram("/modelSpace/GBuffer.vert", "/modelSpace/GBuffer.frag"); DEBUGLOG->outdent(); shaderProgram.update("model", model); shaderProgram.update("view", view); shaderProgram.update("projection", perspective); shaderProgram.update("color", glm::vec4(1.0f,0.0f,0.0f,1.0f)); DEBUGLOG->log("FrameBufferObject Creation: volume uvw coords"); DEBUGLOG->indent(); FrameBufferObject fbo(getResolution(window).x, getResolution(window).y); FrameBufferObject::s_internalFormat = GL_RGBA32F; // to allow arbitrary values in G-Buffer fbo.addColorAttachments(4); DEBUGLOG->outdent(); // G-Buffer FrameBufferObject::s_internalFormat = GL_RGBA; // restore default RenderPass renderPass(&shaderProgram, &fbo); renderPass.addEnable(GL_DEPTH_TEST); renderPass.addClearBit(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); renderPass.addRenderable(&grid); ShaderProgram compShader("/screenSpace/fullscreen.vert", "/screenSpace/finalCompositing.frag"); // ShaderProgram compShader("/screenSpace/fullscreen.vert", "/screenSpace/simpleAlphaTexture.frag"); Quad quad; RenderPass compositing(&compShader, 0); compositing.addClearBit(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); compositing.addRenderable(&quad); // Geometry test shader ShaderProgram geomShader("/modelSpace/geometry.vert", "/modelSpace/simpleLighting.frag", "/geometry/simpleGeom.geom"); RenderPass geom(&geomShader, 0); geom.addClearBit(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); geom.addRenderable(&grid); geom.addEnable(GL_DEPTH_TEST); geom.addEnable(GL_ALPHA_TEST); geom.addEnable(GL_BLEND); glAlphaFunc(GL_GREATER, 0); geomShader.update("projection", perspective); ////////////////////////////////////////////////////////////////////////////// /////////////////////// GUI / USER INPUT //////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Setup ImGui binding ImGui_ImplGlfwGL3_Init(window, true); Turntable turntable; double old_x; double old_y; glfwGetCursorPos(window, &old_x, &old_y); auto cursorPosCB = [&](double x, double y) { ImGuiIO& io = ImGui::GetIO(); if ( io.WantCaptureMouse ) { return; } // ImGUI is handling this double d_x = x - old_x; double d_y = y - old_y; if ( turntable.getDragActive() ) { turntable.dragBy(d_x, d_y, view); } old_x = x; old_y = y; }; auto mouseButtonCB = [&](int b, int a, int m) { if (b == GLFW_MOUSE_BUTTON_LEFT && a == GLFW_PRESS) { turntable.setDragActive(true); } if (b == GLFW_MOUSE_BUTTON_LEFT && a == GLFW_RELEASE) { turntable.setDragActive(false); } ImGui_ImplGlfwGL3_MouseButtonCallback(window, b, a, m); }; auto keyboardCB = [&](int k, int s, int a, int m) { if (a == GLFW_RELEASE) {return;} switch (k) { case GLFW_KEY_W: eye += glm::inverse(view) * glm::vec4(0.0f,0.0f,-0.1f,0.0f); center += glm::inverse(view) * glm::vec4(0.0f,0.0f,-0.1f,0.0f); break; case GLFW_KEY_A: eye += glm::inverse(view) * glm::vec4(-0.1f,0.0f,0.0f,0.0f); center += glm::inverse(view) * glm::vec4(-0.1f,0.0f,0.0f,0.0f); break; case GLFW_KEY_S: eye += glm::inverse(view) * glm::vec4(0.0f,0.0f,0.1f,0.0f); center += glm::inverse(view) * glm::vec4(0.0f,0.0f,0.1f,0.0f); break; case GLFW_KEY_D: eye += glm::inverse(view) * glm::vec4(0.1f,0.0f,0.0f,0.0f); center += glm::inverse(view) * glm::vec4(0.1f,0.0f,0.0f,0.0f); break; default: break; } ImGui_ImplGlfwGL3_KeyCallback(window,k,s,a,m); }; setCursorPosCallback(window, cursorPosCB); setMouseButtonCallback(window, mouseButtonCB); setKeyCallback(window, keyboardCB); ////////////////////////////////////////////////////////////////////////////// //////////////////////////////// RENDER LOOP ///////////////////////////////// ////////////////////////////////////////////////////////////////////////////// double elapsedTime = 0.0; render(window, [&](double dt) { elapsedTime += dt; std::string window_header = "Volume Renderer - " + std::to_string( 1.0 / dt ) + " FPS"; glfwSetWindowTitle(window, window_header.c_str() ); //////////////////////////////// GUI //////////////////////////////// ImGuiIO& io = ImGui::GetIO(); ImGui_ImplGlfwGL3_NewFrame(); // tell ImGui a new frame is being rendered ImGui::PushItemWidth(-100); if (ImGui::CollapsingHeader("Geometry Shader Settings")) { ImGui::ColorEdit4( "color", glm::value_ptr( s_color)); // color mixed at max distance ImGui::SliderFloat("strength", &s_strength, 0.0f, 2.0f); // influence of color shift } ImGui::Checkbox("auto-rotate", &s_isRotating); // enable/disable rotating volume ImGui::PopItemWidth(); ////////////////////////////////////////////////////////////////////////////// ///////////////////////////// MATRIX UPDATING /////////////////////////////// if (s_isRotating) // update view matrix { model = glm::rotate(glm::mat4(1.0f), (float) dt, glm::vec3(0.0f, 1.0f, 0.0f) ) * model; } view = glm::lookAt(glm::vec3(eye), glm::vec3(center), glm::vec3(0.0f, 1.0f, 0.0f)); ////////////////////////////////////////////////////////////////////////////// //////////////////////// SHADER / UNIFORM UPDATING ////////////////////////// // update view related uniforms shaderProgram.update( "view", view); shaderProgram.update( "model", turntable.getRotationMatrix() * model); geomShader.update( "view", view); geomShader.update( "model", turntable.getRotationMatrix() * model); compShader.update( "vLightPos", view * turntable.getRotationMatrix() * s_lightPos); updateVectorTexture(elapsedTime); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, s_vectorTexture); // glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // this is altered by ImGui::Render(), so reset it every frame glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, s_texHandle); geomShader.update("tex", 1); geomShader.update("blendColor", 2.0); geomShader.update("color", s_color); geomShader.update("strength", s_strength); ////////////////////////////////////////////////////////////////////////////// //////////////////////////////// RENDERING //// ///////////////////////////// // glActiveTexture(GL_TEXTURE0); // glBindTexture(GL_TEXTURE_2D, fbo.getColorAttachmentTextureHandle(GL_COLOR_ATTACHMENT0)); // color // glActiveTexture(GL_TEXTURE1); // glBindTexture(GL_TEXTURE_2D, fbo.getColorAttachmeHntTextureHandle(GL_COLOR_ATTACHMENT1)); // normal // glActiveTexture(GL_TEXTURE2); // glBindTexture(GL_TEXTURE_2D, fbo.getColorAttachmentTextureHandle(GL_COLOR_ATTACHMENT2)); // position // glActiveTexture(GL_TEXTURE0); // compShader.update("colorMap", 0); // compShader.update("normalMap", 1); // compShader.update("positionMap", 2); // renderPass.render(); // compositing.render(); geom.render(); ImGui::Render(); glDisable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); // this is altered by ImGui::Render(), so reset it every frame ////////////////////////////////////////////////////////////////////////////// }); destroyWindow(window); return 0; }
void GLWidget::paintGL() { if (data.currentFile != data.nextFile) { if (data.nextFile == -1) loadShaders(data.filePath); else loadShaders(fileList[data.nextFile]); data.currentFile = data.nextFile; data.zoom = 0; data.moveX = 0; data.moveY = 0; data.pause = false; updateTitle(); } double posX = (data.moveX + 1.) * float(DIM / 2); double posY = (data.moveY - 1.) * float(DIM / 2) * -1.; glUniform1ui(data.loc.dim, DIM); glUniform1f(data.loc.zoom, data.zoom); glUniform2d(data.loc.position, posX, posY); glVertexAttribPointer(data.loc.vertex, 2, GL_FLOAT, GL_FALSE, 0, data.vertex.constData()); if (data.loc.animation != -1 && !data.pause) { glUniform1f((float)data.loc.animation, (double)QTime::currentTime().msecsSinceStartOfDay() / 1000.); update(); } render(); if (!data.saving) return; data.saving = false; QImage *img = saveDialog->img; QImage imgRen(data.save.blockSize, QImage::Format_RGB888); if (img == 0) { saveDialog->failed(tr("img allocation failed")); return; } if (img->isNull()) { saveDialog->failed(tr("img is null")); return; } if (imgRen.isNull()) { saveDialog->failed(tr("imgRen is null")); return; } QOpenGLFramebufferObject fbo(data.save.blockSize); fbo.bind(); glViewport(0, 0, data.save.blockSize.width(), data.save.blockSize.height()); QPoint pos; int w = data.save.blockSize.width() * data.save.blockCount.width(); int h = data.save.blockSize.height() * data.save.blockCount.height(); float asp = (float)h / (float)w; render: // Select region data.projection.setToIdentity(); float left = float(2 * pos.x() - data.save.blockCount.width()) / data.save.blockCount.width(); float top = float(2 * pos.y() - data.save.blockCount.height()) / data.save.blockCount.height(); data.projection.ortho(left, left + 2. / data.save.blockCount.width(), asp * top, asp * (top + 2. / data.save.blockCount.height()), -1., 1.); render(); QPoint imgPos(pos.x() * data.save.blockSize.width(), pos.y() * data.save.blockSize.height()); glReadPixels(0, 0, imgRen.width(), imgRen.height(), GL_RGB, GL_UNSIGNED_BYTE, imgRen.bits()); unsigned char *imgPtr = img->scanLine(img->height() - imgPos.y() - 1) + imgPos.x() * 3; for (int i = 0; i < imgRen.height(); i++) { memcpy(imgPtr, imgRen.constScanLine(i), imgRen.bytesPerLine()); imgPtr -= img->bytesPerLine(); } if (pos.x() != data.save.blockCount.width() - 1) pos.setX(pos.x() + 1); else if (pos.y() != data.save.blockCount.height() - 1) { pos.setX(0); pos.setY(pos.y() + 1); } else { fbo.release(); resizeGL(width(), height()); saveDialog->done(); return; } goto render; }
void OpenGLViewer::open(int w, int h) { //OpenGLViewer window created //Always use the output width when set for hidden window fbo_enabled = !visible; //Always use fbo for hidden window if (!visible && outwidth > 0 && outwidth != w) { h = outheight; w = outwidth; } width = w; height = h; GLboolean b; GLint i, d, s, u, a, sb, ss; glGetBooleanv(GL_RGBA_MODE, &b); glGetIntegerv(GL_ALPHA_BITS, &i); glGetIntegerv(GL_STENCIL_BITS, &s); glGetIntegerv(GL_DEPTH_BITS, &d); glGetIntegerv(GL_ACCUM_RED_BITS, &a); glGetIntegerv(GL_MAX_TEXTURE_UNITS, &u); glGetIntegerv(GL_SAMPLE_BUFFERS, &sb); glGetIntegerv(GL_SAMPLES, &ss); glGetBooleanv(GL_STEREO, &stereoBuffer); glGetBooleanv(GL_DOUBLEBUFFER, &doubleBuffer); //Set buffers if (doubleBuffer) renderBuffer = GL_BACK; else renderBuffer = GL_FRONT; debug_print("Stereo %d Double-buffer %d RGBA Mode = %d, Alpha bits = %d, Depth bits = %d, Stencil bits = %d, Accum bits = %d, Texture units %d, SampleBuffers %d, Samples %d\n", stereoBuffer, doubleBuffer, b, i, d, s, a, u, sb, ss); //Load OpenGL extensions OpenGL_Extensions_Init(); //Depth testing glEnable(GL_DEPTH_TEST); //Transparency glEnable(GL_BLEND); //Smooth shading glShadeModel(GL_SMOOTH); //Font textures (bitmap fonts) lucSetupRasterFont(); //Setup lighting light(); //Enable scissor test glEnable(GL_SCISSOR_TEST); //Init fbo if (fbo_enabled) fbo(width, height); // Clear full window buffer glViewport(0, 0, width, height); glScissor(0, 0, width, height); glDrawBuffer(renderBuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Call the application open function app->open(width, height); //Flag window opened if (!isopen) { isopen = true; //Begin polling for input animate(TIMER_INC); } //Call open on any output interfaces for (int o=0; o<outputs.size(); o++) outputs[o]->open(w, h); }
void QwtPlotGLCanvas::paintGL() { const bool hasFocusIndicator = hasFocus() && focusIndicator() == CanvasFocusIndicator; QPainter painter; #if QT_VERSION < 0x040600 painter.begin( this ); draw( &painter ); #else if ( testPaintAttribute( QwtPlotGLCanvas::BackingStore ) ) { if ( d_data->fbo == NULL || d_data->fbo->size() != size() ) { invalidateBackingStore(); const int numSamples = 16; QGLFramebufferObjectFormat format; format.setSamples( numSamples ); format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); QGLFramebufferObject fbo( size(), format ); QPainter fboPainter( &fbo ); draw( &fboPainter); fboPainter.end(); d_data->fbo = new QGLFramebufferObject( size() ); QRect rect(0, 0, width(), height()); QGLFramebufferObject::blitFramebuffer(d_data->fbo, rect, &fbo, rect); } // drawTexture( QRectF( -1.0, 1.0, 2.0, -2.0 ), d_data->fbo->texture() ); if ( hasFocusIndicator ) painter.begin( this ); glBindTexture(GL_TEXTURE_2D, d_data->fbo->texture()); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); } else { painter.begin( this ); draw( &painter ); } #endif if ( hasFocus() && focusIndicator() == CanvasFocusIndicator ) drawFocusIndicator( &painter ); }
std::shared_ptr<Texture> RenderPass:: get_buffer(std::string const& name, CameraMode mode, bool draw_fps) { // check for existance of desired buffer if ((mode == CENTER && center_eye_buffers_.find(name) == center_eye_buffers_.end()) || (mode == LEFT && left_eye_buffers_.find(name) == left_eye_buffers_.end()) || (mode == RIGHT && right_eye_buffers_.find(name) == right_eye_buffers_.end())) { WARNING("Failed to get buffer \"%s\" from pass \"%s\": " "A buffer with this name does not exist!", name.c_str(), get_name().c_str()); return NULL; } // return appropriate buffer if it has been rendered already if (mode == CENTER && rendererd_center_eye_) return center_eye_buffers_[name]; if (mode == LEFT && rendererd_left_eye_) return left_eye_buffers_[name]; if (mode == RIGHT && rendererd_right_eye_) return right_eye_buffers_[name]; // serialize the scenegraph Optimizer optimizer; optimizer.check(pipeline_->get_current_graph(), render_mask_); // if there are dynamic texture inputs for this render pass, get the // according buffers recursively for (auto& node: optimizer.get_data().nodes_) { auto material(inputs_.find(node.material_)); if (material != inputs_.end()) { for (auto& uniform: material->second) { overwrite_uniform_texture(material->first, uniform.first, pipeline_->get_render_pass(uniform.second.first)-> get_buffer(uniform.second.second, mode)); } } } // we'll need these two very often now... OptimizedScene const& scene(optimizer.get_data()); RenderContext const& ctx(pipeline_->get_context()); // get the fbo which should be rendered to FrameBufferObject* fbo(NULL); switch (mode) { case CENTER: fbo = ¢er_eye_fbo_; break; case LEFT: fbo = &left_eye_fbo_; break; case RIGHT: fbo = &right_eye_fbo_; break; } fbo->bind(ctx); fbo->clear_color_buffers(ctx); fbo->clear_depth_stencil_buffer(ctx); ctx.render_context->set_viewport(scm::gl::viewport(math::vec2(0,0), math::vec2(fbo->width(), fbo->height()))); auto camera_it(scene.cameras_.find(camera_)); auto screen_it(scene.screens_.find(screen_)); if (camera_it != scene.cameras_.end() && screen_it != scene.screens_.end()) { auto camera(camera_it->second); auto screen(screen_it->second); math::mat4 camera_transform(camera.transform_); if (mode == LEFT) { scm::math::translate(camera_transform, -camera.stereo_width_*0.5f, 0.f, 0.f); } else if (mode == RIGHT) { scm::math::translate(camera_transform, camera.stereo_width_*0.5f, 0.f, 0.f); } auto projection(math::compute_frustum(camera_transform.column(3), screen.transform_, 0.1, 100000.f)); math::mat4 view_transform(screen.transform_); view_transform[12] = 0.f; view_transform[13] = 0.f; view_transform[14] = 0.f; view_transform[15] = 1.f; math::vec3 camera_position(camera_transform.column(3)[0], camera_transform.column(3)[1], camera_transform.column(3)[2]); view_transform = scm::math::make_translation(camera_position) * view_transform; math::mat4 view_matrix(scm::math::inverse(view_transform)); // update light data uniform block if (scene.lights_.size() > 0) { if (!light_information_) { light_information_ = new scm::gl::uniform_block<LightInformation>(ctx.render_device); } light_information_->begin_manipulation(ctx.render_context); LightInformation light; light.light_count = math::vec4i(scene.lights_.size(), scene.lights_.size(), scene.lights_.size(), scene.lights_.size()); for (unsigned i(0); i < scene.lights_.size(); ++i) { math::mat4 transform(scene.lights_[i].transform_); // calc light radius and position light.position[i] = math::vec4(transform[12], transform[13], transform[14], transform[15]); float radius = scm::math::length(light.position[i] - transform * math::vec4(0.f, 0.f, 1.f, 1.f)); light.color_radius[i] = math::vec4(scene.lights_[i].color_.r(), scene.lights_[i].color_.g(), scene.lights_[i].color_.b(), radius); } **light_information_ = light; light_information_->end_manipulation(); ctx.render_context->bind_uniform_buffer( light_information_->block_buffer(), 0); } for (auto& core: scene.nodes_) { auto geometry = GeometryBase::instance()->get(core.geometry_); auto material = MaterialBase::instance()->get(core.material_); if (material && geometry) { material->use(ctx); if (float_uniforms_.find(core.material_) != float_uniforms_.end()) { for (auto val : float_uniforms_[core.material_]) material->get_shader()->set_float(ctx, val.first, val.second); } if (texture_uniforms_.find(core.material_) != texture_uniforms_.end()) { for (auto val : texture_uniforms_[core.material_]) material->get_shader()->set_sampler2D(ctx, val.first, *val.second); } material->get_shader()->set_mat4(ctx, "projection_matrix", projection); material->get_shader()->set_mat4(ctx, "view_matrix", view_matrix); material->get_shader()->set_mat4(ctx, "model_matrix", core.transform_); material->get_shader()->set_mat4(ctx, "normal_matrix", scm::math::transpose( scm::math::inverse(core.transform_))); geometry->draw(ctx); material->unuse(ctx); } else if (material) { WARNING("Cannot render geometry \"%s\": Undefined geometry " "name!", core.geometry_.c_str()); } else if (geometry) { WARNING("Cannot render geometry \"%s\": Undefined material " "name: \"%s\"!", core.geometry_.c_str(), core.material_.c_str()); } else { WARNING("Cannot render geometry \"%s\": Undefined geometry " "and material name: \"%s\"!", core.geometry_.c_str(), core.material_.c_str()); } } if (scene.lights_.size() > 0) { ctx.render_context->reset_uniform_buffers(); } } fbo->unbind(ctx); // draw fps on the screen if (draw_fps) { if (!text_renderer_) text_renderer_ = new TextRenderer(pipeline_->get_context()); if (mode == CENTER) { text_renderer_->render_fps(pipeline_->get_context(), center_eye_fbo_, pipeline_->get_application_fps(), pipeline_->get_rendering_fps()); } else if (mode == LEFT) { text_renderer_->render_fps(pipeline_->get_context(), left_eye_fbo_, pipeline_->get_application_fps(), pipeline_->get_rendering_fps()); } else { text_renderer_->render_fps(pipeline_->get_context(), right_eye_fbo_, pipeline_->get_application_fps(), pipeline_->get_rendering_fps()); } } // return the buffer and set the already-rendered-flag if (mode == CENTER) { rendererd_center_eye_ = true; return center_eye_buffers_[name]; } else if (mode == LEFT) { rendererd_left_eye_ = true; return left_eye_buffers_[name]; } else { rendererd_right_eye_ = true; return right_eye_buffers_[name]; } }
GLuint XunoGLSLFilter::frameTexture() const { //qDebug()<<"XunoGLSLFilter::frameTexture()"<<lastSuperscaleTexureId; return (lastSuperscaleTexureId>0) ? lastSuperscaleTexureId : fbo()->texture(); }