1
I am new to QtOpengl, I am doing offscreen rendering and storing framebufferobject in QImage, this Qimage I am passing to QPainter to draw circle, but it is drawing 4 circles event for once drawImage qpainter call. 

1:请找到以下代码片段:如果我将 Qimage 传递给具有椭圆等创建形状的着色器,我是否应该将其他方式传递给着色器代码。请建议。

2:在下面,我在我的构造器中使用 Qpainter 创建了形状

3:然后调用 getImgResult 这是 opengl 调用来渲染我的图像

4:我将 fbo 缓冲区数据存储到 QImage

5:这个Qimage我正在使用内部绘制方法使用drawImage api绘制形状。

polygon::polygon(QQuickItem *parent)
    : QQuickPaintedItem(parent)

{
#ifdef FRAMEBUFFEROBJECT
  setRenderTarget(QQuickPaintedItem::FramebufferObject);
#else
  setRenderTarget(QQuickPaintedItem::Image);
#endif
  QImage image(100, 100, QImage::Format_ARGB32);
  image.fill(QColor(0, 0, 0, 0));
  QPainter mpainter;
  mpainter.begin(&image);
  QBrush myBrush;
  myBrush.setStyle(Qt::SolidPattern);
  QColor mycolor(QColor(255, 0, 0, 255));
  myBrush.setColor(mycolor);
  mpainter.setBrush(myBrush);
  mpainter.drawEllipse(0, 0, 100, 100);
  getResultImg(image, 1);
}
polygon::~polygon() {}

void polygon::paint(QPainter *painter) { painter = drawPolygon(painter); }

QPainter *polygon::drawPolygon(QPainter *painter) {
 
  painter->drawImage(QRectF(70, 70, m_matriximg.width(), m_matriximg.height()),
                     m_matriximg);    
 [![**enter image description here**][1]][1]
  return painter;
}

void polygon::getResultImg(QImage image, int num) {

  //   =======CONTEXT SETUP======
  //   Set OpenGL version to use
  QSurfaceFormat surfaceFormat;
  surfaceFormat.setMajorVersion(4);
  surfaceFormat.setMinorVersion(3);
  QOpenGLContext openGLContext;
  openGLContext.setFormat(surfaceFormat);
  openGLContext.create();
  if (!openGLContext.isValid())
    qDebug("Unable to create context");

  QOffscreenSurface surface;
  surface.setFormat(surfaceFormat);
  surface.create();
  if (!surface.isValid())
    qDebug("Unable to create the Offscreen surface");

  openGLContext.makeCurrent(&surface);

  //   Viewport size
  QSize vpSize = QSize(100, 100);

  QOpenGLFramebufferObjectFormat fboFormat;
  fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
  QOpenGLFramebufferObject fbo(vpSize, fboFormat);
  openGLContext.functions()->glViewport(0, 0, vpSize.width(), vpSize.height());
  fbo.bind();

  //    ========GEOMEETRY SETUP========

  static const float vertexPositions[] = {-1.0f, 1.0f,  1.0f,  1.0f,
                                          1.0f,  -1.0f, -1.0f, 1.0f,
                                          -1.0f, -1.0f, 1.0f,  -1.0f};

  static const float vertexColors[] = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
                                       0.0f, 0.0f, 0.0f, 1.0f};

  QOpenGLBuffer vertexPositionBuffer(QOpenGLBuffer::VertexBuffer);
  vertexPositionBuffer.create();
  vertexPositionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
  vertexPositionBuffer.bind();
  vertexPositionBuffer.allocate(vertexPositions, 12 * sizeof(float));

  QOpenGLBuffer vertexColorBuffer(QOpenGLBuffer::VertexBuffer);
  vertexColorBuffer.create();
  vertexColorBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
  vertexColorBuffer.bind();
  vertexColorBuffer.allocate(vertexColors, 9 * sizeof(float));

  QOpenGLShaderProgram program;
  QOpenGLTexture *m_texture = new QOpenGLTexture(image);
  uint texture_unit = 1;
  m_texture->bind(texture_unit);
  program.addShaderFromSourceCode(
      QOpenGLShader::Vertex, "#version 330\r\n"
                             "in vec2 position;\n"
                             "varying highp vec2 coords;\n"
                             "in vec4 color;\n"
                             "out vec4 fragColor;\n"
                             "void main() {\n"
                             "    fragColor = color;\n"
                             "    gl_Position = vec4(position, 0.0, 1.0);\n"
                             "coords=position.xy;\n"
                             "}\n");
  program.addShaderFromSourceCode(
      QOpenGLShader::Fragment,
      "#version 330\r\n"
      "in vec4 fragColor;\n"
      "in vec2 position;\n"
      "varying highp vec2 coords;\n"
      "out vec4 color;\n"
      "uniform sampler2D source;\n"
      "uniform mat4 m_view;"
      "uniform vec4 offset;"
      "uniform float dividervalue;"
      "void main() {\n"
      "mat4 "
      "float s=0.46;"
      "float angle=-175.0;"
      "vec4 image = texture2D(source,coords.xy);\n"
      "if(dividervalue == 1)"
      "color = image;\n"
      "}\n");
  program.link();
  program.bind();

  QOpenGLVertexArrayObject vao;
  vao.create();
  vao.bind();
  program.setUniformValue("source", texture_unit);
  vertexPositionBuffer.bind();
  program.enableAttributeArray("position");
  program.setAttributeBuffer("position", GL_FLOAT, 0, 2);

  vertexColorBuffer.bind();
  program.enableAttributeArray("color");
  program.setAttributeBuffer("color", GL_FLOAT, 0, 3);
  openGLContext.functions()->glUseProgram(1);
  float mat[4][4] = {0.20, 0.20, 0.45, 0.45, 0.33, 0.33, 0.45, 0.45,
                     0.0,  0.0,  0.0,  0.33, 0.0,  0.0,  0.0,  1.0};
  float vec[4] = {0.0, 0.0, 0.0, 0.0};

  GLint transformLocation =
      openGLContext.functions()->glGetUniformLocation(1, "m_view");
  openGLContext.functions()->glUniformMatrix4fv(transformLocation, 1, GL_FALSE,
                                                &mat[0][0]);

  openGLContext.functions()->glUniform4fv(
      openGLContext.functions()->glGetUniformLocation(1, "offset"), 1, &vec[0]);
  float dividervalue = num;
  program.setUniformValue("dividervalue", dividervalue);

  //    ==============DRAWING TO THE FBO============

  openGLContext.functions()->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  openGLContext.functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  openGLContext.functions()->glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
  program.disableAttributeArray("position");
  program.disableAttributeArray("color");
  program.release();
  fbo.release();

  //    ========SAVE IMAGE===========

  m_matriximg = fbo.toImage();
} 

当我使用 fbo 从 openg 上下文中取回 QImage 时,我附上了一个图像,这是我的实际结果。我期待 1 圈,但得到 4 圈。我不明白我哪里出错了。

4

0 回答 0