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 圈。我不明白我哪里出错了。