0

我偶尔会开发科学模拟软件,并希望在 2D 视图上可视化结果。

是否有任何现成的(最好是开源的)Win32 类创建一个绘图画布

  1. 飞涨,
  2. 快照和
  3. 可能是视频捕捉能力?

我需要有限的 API,包括快速像素绘制、从内存缓冲区绘制 bmp 和可能的文本。

4

1 回答 1

3

一起看 Qt 和 OpenGL。这是我经常使用的一些代码,可能对您有所帮助

//piview.h
#include <QGraphicsView>
#include <QGraphicsScene>


class PiView : public QGraphicsView{
    Q_OBJECT

  public:
    explicit PiView(QGraphicsScene * =0, QWidget *parent = 0);
    void enableSmoothRendering();
    void enableOpenGl();
    void fit();
    void renderToFile(QString const& path)const;


private:
    //void mouseMoveEvent(QMouseEvent *event);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void wheelEvent(QWheelEvent *event);
    virtual void resizeEvent(QResizeEvent * event );

  signals:
    void pointRightClicked(QPointF) const;
    void pointLeftClicked(QPointF) const;
};
PiView* createMyPiView(QGraphicsScene* pScene);

//piview.cpp
#include "piview.h"

#ifdef OPENGL
#include <QtOpenGL>
#include <QGLWidget>
#endif


#include <QMouseEvent>
#include <QWheelEvent>

#include <qdebug.h>

PiView::PiView(QGraphicsScene* scene, QWidget *parent) : QGraphicsView(scene , parent){
  this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  this->setDragMode(QGraphicsView::ScrollHandDrag);
}

void PiView::enableSmoothRendering(){
  this->setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
}

#ifdef OPENGL
void  PiView::enableOpenGl(){
  QGLFormat fmt = QGLFormat::defaultFormat();
  fmt.setSampleBuffers(true);
  fmt.setDoubleBuffer(true);
  //fmt.setSamples(256);
  fmt.setDirectRendering(true);
  //qDebug() << "SampleBuffers:" << fmt.sampleBuffers() << fmt.samples();
  this->setViewport(new QGLWidget(fmt));
  this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
  this->setCacheMode(QGraphicsView::CacheBackground);
  //this->scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
}
#else
void PiView::enableOpenGl(){
  qDebug() << "Opengl was not enabled, enable it using opengl as qmake parameter";
}
#endif


void PiView::mousePressEvent(QMouseEvent *event){
  if (event->button()==Qt::RightButton) {
    emit pointRightClicked(mapToScene(event->pos()));
  }
  else if (event->button()==Qt::LeftButton) {
    emit pointLeftClicked(mapToScene(event->pos()));
  }
  QGraphicsView::mousePressEvent(event);
}

//Zooming using the mousewheel
void PiView::wheelEvent(QWheelEvent *event){
  double scaleFactor = 1.15; //How fast we zoom
  if (event->orientation()==Qt::Vertical){
    if(event->delta() > 0) {
      //Zoom in
      scale(scaleFactor, scaleFactor);
    } else {
      //Zooming out
      scale(1.0 / scaleFactor, 1.0 / scaleFactor);
    }
  }
  else if (event->orientation()==Qt::Horizontal) {
    if(event->delta() > 0) {
      scroll(10,0);
    }
    else {
      scroll(-10,0);
    }
  }
}

void PiView::resizeEvent(QResizeEvent *event){
  this->fit();
  QGraphicsView::resizeEvent(event);
}

void PiView::fit(){
  this->fitInView(this->sceneRect(),Qt::KeepAspectRatio);
}

PiView* createMyPiView(QGraphicsScene* pScene){
  PiView* view = new PiView(pScene);
  view->enableOpenGl();
  view->enableSmoothRendering();
  return view;
}

对于快照,请查看以下内容:

void SceneInteractor::saveSelection(){
  if (mpScene->selectedItems().isEmpty()) return;
  QList<QGraphicsItem*> items(mpScene->selectedItems());
  QRect sourceRect;
  boostForeach(QGraphicsItem*  item, items) {
    sourceRect = sourceRect.united(item->sceneBoundingRect().toRect());
  }
  QImage img(sourceRect.size(),QImage::Format_ARGB32_Premultiplied);
  img.fill(Qt::transparent);
  QPainter p(&img);
  p.setRenderHint(QPainter::Antialiasing);
  QGraphicsView::CacheMode cache = mpView->cacheMode();
  mpView->setCacheMode(QGraphicsView::CacheNone);
  mpView->scene()->clearSelection();
  mpView->scene()->render(&p, QRectF(), sourceRect);
  p.end();
  QString path = QFileDialog::getSaveFileName(0,tr("Choose Image-File Destination"));
  img.save(path,"PNG",100);
  mpView->setCacheMode(cache);
}
于 2012-06-17T11:59:31.357 回答