Results 1 to 5 of 5

Thread: Do offscreen render(openGL) with Qt5

  1. #1
    Join Date
    Jan 2011
    Posts
    127
    Thanks
    42
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Do offscreen render(openGL) with Qt5

    I want to do offscreen rendering, but have no luck
    These are the codes, I have no any idea why the FBO(frame buffer object)
    always give me a blank image

    What I want to do is, the texture after render will write to the FBO
    after that, I could transfer the data of fbo into QImage by toImage()

    .hpp
    Qt Code:
    1. #ifndef OFFSCREENEXP_HPP
    2. #define OFFSCREENEXP_HPP
    3.  
    4. #include <QOpenGLFunctions>
    5. #include <QWindow>
    6.  
    7. class QImage;
    8. class QOpenGLContext;
    9.  
    10. class offScreenExp : public QWindow, protected QOpenGLFunctions
    11. {
    12. public:
    13. explicit offScreenExp(QWindow *parent = 0);
    14.  
    15. QImage render();
    16.  
    17. private:
    18. QOpenGLContext *context_;
    19. };
    20.  
    21. #endif // OFFSCREENEXP_HPP
    To copy to clipboard, switch view to plain text mode 

    .cpp
    Qt Code:
    1. #include <QImage>
    2. #include <QOpenGLBuffer>
    3. #include <QOpenGLContext>
    4. #include <QOpenGLFramebufferObject>
    5. #include <QOpenGLShaderProgram>
    6. #include <QString>
    7. #include <QWidget>
    8.  
    9. #include <QDebug>
    10.  
    11. #include "offScreenExp.hpp"
    12.  
    13. offScreenExp::offScreenExp(QWindow *parent) :
    14. QWindow(parent),
    15. context_(nullptr)
    16. {
    17. setSurfaceType(QWindow::OpenGLSurface);
    18. setFormat(QSurfaceFormat());
    19. create();
    20. }
    21.  
    22. QImage offScreenExp::render()
    23. {
    24. //create the context
    25. if (!context_) {
    26. context_ = new QOpenGLContext(this);
    27. QSurfaceFormat format;
    28. context_->setFormat(format);
    29.  
    30. if (!context_->create())
    31. qFatal("Cannot create the requested OpenGL context!");
    32. }
    33.  
    34. context_->makeCurrent(this);
    35. initializeOpenGLFunctions();
    36.  
    37. //load image
    38. QString const prefix("/Users/Qt/program/experiment_apps_and_libs/openGLTest/simpleGPGPU/");
    39. QImage img(prefix + "images/emili.jpg");
    40. if(img.isNull()){
    41. qFatal("image is null");
    42. }
    43.  
    44. //if(glCheckFramebufferStatus(fbo.handle()) != GL_FRAMEBUFFER_COMPLETE){
    45. // qDebug()<<"frame buffer error";
    46. //}
    47. qDebug()<<"has opengl fbo : "<<QOpenGLFramebufferObject::hasOpenGLFramebufferObjects();
    48.  
    49. //use two triangles two cover whole screen
    50. std::vector<GLfloat> const vertex{
    51. -1.0f, 1.0f, 0.0f, 1.0f,
    52. 1.0f, 1.0f, 0.0f, 1.0f,
    53. -1.0f, -1.0f, 0.0f, 1.0f,
    54. 1.0f, 1.0f, 0.0f, 1.0f,
    55. 1.0f, -1.0f, 0.0f, 1.0f,
    56. -1.0f, -1.0f, 0.0f, 1.0f,
    57. };
    58.  
    59. //initialize vbo
    60. QOpenGLBuffer buffer(QOpenGLBuffer::VertexBuffer);
    61. buffer.create();
    62. buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    63. buffer.bind();
    64. buffer.allocate(&vertex[0], vertex.size() * sizeof(GLfloat) );
    65. buffer.release();
    66.  
    67. //create texture
    68. GLuint rendered_texture;
    69. glGenTextures(1, &rendered_texture);
    70.  
    71. // "Bind" the newly created texture : all future texture functions will modify this texture
    72. glBindTexture(GL_TEXTURE_2D, rendered_texture);
    73.  
    74. //naive solution, better encapsulate the format in a function
    75. if(img.format() == QImage::Format_Indexed8){
    76. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, img.width(), img.height(), 0, GL_RED, GL_UNSIGNED_BYTE, img.scanLine(0));
    77. }else if(img.format() == QImage::Format_RGB888){
    78. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, img.scanLine(0));
    79. }else{
    80. QImage temp = img.convertToFormat(QImage::Format_RGB888);
    81. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, temp.scanLine(0));
    82. }
    83.  
    84. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    85. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    86. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    87. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    88.  
    89. glBindTexture(GL_TEXTURE_2D, 0);
    90.  
    91. //compile and link program
    92. QOpenGLShaderProgram program;
    93. if(!program.addShaderFromSourceCode(QOpenGLShader::Vertex,
    94. "attribute highp vec4 qt_Vertex;"
    95. "varying highp vec2 qt_TexCoord0;"
    96.  
    97. "void main(void)"
    98. "{"
    99. " gl_Position = qt_Vertex;"
    100. " qt_TexCoord0 = (qt_Vertex.xy + vec2(1.0)) * 0.5;"
    101. "}")){
    102. qDebug()<<"QOpenGLShader::Vertex error : " + program.log();
    103. }
    104.  
    105. // Compile fragment shader
    106. if (!program.addShaderFromSourceCode(QOpenGLShader::Fragment,
    107. "uniform sampler2D source;"
    108. "varying highp vec2 qt_TexCoord0;"
    109.  
    110. "vec3 toGray(vec3 rgb)"
    111. "{"
    112. " return vec3(rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114);"
    113. "}"
    114.  
    115. "void main(void)"
    116. "{"
    117. "vec3 gray = toGray(texture2D(source, qt_TexCoord0).rgb);"
    118. "gl_FragColor = vec4(gray, 0.0);"
    119. "}"
    120. )){
    121. qDebug()<<"QOpenGLShader::Fragment error : " + program.log();
    122. }
    123.  
    124. // Link shader pipeline
    125. if (!program.link()){
    126. qDebug()<<"link error : " + program.log();
    127. }
    128.  
    129. //render the texture as usual
    130. glClearColor(0, 0, 0, 1);
    131. glClear(GL_COLOR_BUFFER_BIT);
    132. glViewport(0, 0, img.width(), img.height());
    133.  
    134. program.bind();
    135. buffer.bind();
    136. program.enableAttributeArray("qt_Vertex");
    137. program.setAttributeBuffer( "qt_Vertex", GL_FLOAT, 0, 4);
    138.  
    139. glActiveTexture(GL_TEXTURE0);
    140. glBindTexture(GL_TEXTURE_2D, rendered_texture);
    141.  
    142. //bind and create fbo
    143. QOpenGLFramebufferObject fbo(img.size());
    144. qDebug()<<"bind success? : "<<fbo.bind();
    145.  
    146. glDrawArrays(GL_TRIANGLES, 0, buffer.size());
    147.  
    148. program.disableAttributeArray("qt_Vertex");
    149. program.release();
    150. glActiveTexture(0);
    151. glBindTexture(GL_TEXTURE_2D, 0);
    152. buffer.release();
    153.  
    154. QImage result = fbo.toImage();
    155. fbo.release();
    156. context_->doneCurrent();
    157.  
    158. return result;
    159. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2012
    Location
    Armenia/Yerevan
    Posts
    400
    Thanks
    15
    Thanked 16 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Do offscreen render(openGL) with Qt5

    your fbo implementation is correct. But, may I ask why you are using 0 here:
    glBindTexture(GL_TEXTURE_2D, 0);

  3. The following user says thank you to saman_artorious for this useful post:

    stereoMatching (25th June 2013)

  4. #3
    Join Date
    Jan 2011
    Posts
    127
    Thanks
    42
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Do offscreen render(openGL) with Qt5

    Thanks for your reply, I unbind the texture too early.

    Qt Code:
    1. //render the texture as usual
    2. glClearColor(0, 0, 0, 1);
    3. glClear(GL_COLOR_BUFFER_BIT);
    4. glViewport(0, 0, img.width(), img.height());
    5.  
    6. program.bind();
    7. buffer.bind();
    8. program.enableAttributeArray("qt_Vertex");
    9. program.setAttributeBuffer( "qt_Vertex", GL_FLOAT, 0, 4);
    10.  
    11. glActiveTexture(GL_TEXTURE0);
    12. glBindTexture(GL_TEXTURE_2D, rendered_texture);
    13.  
    14. //bind and create fbo
    15. QOpenGLFramebufferObject fbo(img.size());
    16. qDebug()<<"bind success? : "<<fbo.bind();
    17.  
    18. glDrawArrays(GL_TRIANGLES, 0, buffer.size());
    19. QImage result = fbo.toImage();
    20.  
    21. program.disableAttributeArray("qt_Vertex");
    22. program.release();
    23. buffer.release();
    24.  
    25. fbo.release();
    26. glActiveTexture(0);
    27. glBindTexture(GL_TEXTURE_2D, 0);
    28. context_->doneCurrent();
    To copy to clipboard, switch view to plain text mode 

    I change the order of the line(the original can't edit), but I still get a blank image
    Last edited by stereoMatching; 23rd June 2013 at 22:01.

  5. #4
    Join Date
    Feb 2012
    Location
    Armenia/Yerevan
    Posts
    400
    Thanks
    15
    Thanked 16 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Do offscreen render(openGL) with Qt5

    can't you test your fbo instructions separately in another program? You may also have a look at my own fbo implementation sample (ignore the lighting part of the program):

    Qt Code:
    1. void GlWidget::paintGL()
    2. {
    3. BakeDynamicTexture();
    4.  
    5. // RenderShapes();
    6.  
    7. glClearColor(0, 0, 0.0f, 1.0f);
    8. // //! [2]
    9. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    10. glViewport(0, 0, width(),height());
    11.  
    12. QMatrix4x4 mMatrix;
    13. QMatrix4x4 vMatrix;
    14.  
    15. QMatrix4x4 cameraTransformation;
    16. cameraTransformation.rotate(alpha, 0, 1, 0);
    17. cameraTransformation.rotate(beta, 1, 0, 0);
    18.  
    19. QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance);
    20. QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
    21. vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);
    22.  
    23. QMatrix4x4 mvMatrix;
    24. mMatrix.setToIdentity();
    25.  
    26. mvMatrix = vMatrix * mMatrix;
    27.  
    28. QMatrix3x3 normalMatrix;
    29. normalMatrix = mvMatrix.normalMatrix();
    30.  
    31. QMatrix4x4 lightTransformation;
    32. lightTransformation.rotate(lightAngle, 0, 1, 0);
    33.  
    34. QVector3D lightPosition = lightTransformation * QVector3D(0, 1, 1);
    35.  
    36. //! [3]
    37. //##########################
    38. // lightingShaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
    39. // shpFill->RenderCube (&lightingShaderProgram, dynamicTexture);
    40. // lightingShaderProgram.release();
    41. //##########################
    42.  
    43. //! [5]
    44. lightingShaderProgram.bind();
    45.  
    46. lightingShaderProgram.setUniformValue("mvpMatrix", pMatrix * mvMatrix);
    47. lightingShaderProgram.setUniformValue("mvMatrix", mvMatrix);
    48. lightingShaderProgram.setUniformValue("normalMatrix", normalMatrix);
    49. lightingShaderProgram.setUniformValue("lightPosition", vMatrix * lightPosition);
    50.  
    51. shpFill->RenderLightingCube(&lightingShaderProgram, dynamicTexture);
    52.  
    53. mMatrix.setToIdentity();
    54. mMatrix.translate(lightPosition);
    55. mMatrix.rotate(lightAngle, 0, 1, 0);
    56. mMatrix.rotate(45, 1, 0, 0);
    57. mMatrix.scale(0.1);
    58.  
    59. coloringShaderProgram.bind();
    60. coloringShaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
    61.  
    62. shpFill->colorLightingCube(&coloringShaderProgram);
    63. }
    To copy to clipboard, switch view to plain text mode 


    Baking part:
    Qt Code:
    1. void GlWidget::BakeDynamicTexture()
    2. {
    3. fbo->bind();
    4.  
    5. RenderShapes();
    6.  
    7. fbo->release();
    8.  
    9. dynamicTexture = fbo->texture();
    10. }
    To copy to clipboard, switch view to plain text mode 

    RenderShapes (instead of drawing a shape file here, simply draw something else, check if it draws successfully)
    Qt Code:
    1. void GlWidget::RenderShapes()
    2. {
    3. QMatrix4x4 sMatrix;
    4.  
    5. glClearColor(0.1f, 0.5f, 0.0f, 1.0f);
    6. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    7. glViewport(0, 0, 256,256);
    8.  
    9. shaderProgram.bind();
    10.  
    11. sMatrix.setToIdentity();
    12.  
    13. shaderProgram.setUniformValue("mvpMatrix", sMatrix);
    14.  
    15. shpFill->Render(&shaderProgram);
    16.  
    17. shaderProgram.release();
    18. }
    To copy to clipboard, switch view to plain text mode 

    RenderLightingCube:
    Qt Code:
    1. void FillShape::RenderLightingCube(QGLShaderProgram* lightingShaderProgram, GLuint cubeTexture)
    2. {
    3. lightingShaderProgram->setUniformValue("ambientColor", QColor(32, 32, 32));
    4. lightingShaderProgram->setUniformValue("diffuseColor", QColor(128, 128, 128));
    5. lightingShaderProgram->setUniformValue("specularColor", QColor(255, 255, 255));
    6. lightingShaderProgram->setUniformValue("ambientReflection", (GLfloat) 1.0);
    7. lightingShaderProgram->setUniformValue("diffuseReflection", (GLfloat) 1.0);
    8. lightingShaderProgram->setUniformValue("specularReflection", (GLfloat) 1.0);
    9. lightingShaderProgram->setUniformValue("shininess", (GLfloat) 100.0);
    10. lightingShaderProgram->setUniformValue("texture", 0);
    11.  
    12. glActiveTexture(GL_TEXTURE0);
    13. glBindTexture(GL_TEXTURE_2D, cubeTexture);
    14. glActiveTexture(0);
    15.  
    16. lightingShaderProgram->setAttributeArray("vertex", cubeVertices.constData());
    17. lightingShaderProgram->enableAttributeArray("vertex");
    18. lightingShaderProgram->setAttributeArray("normal", cubeNormals.constData());
    19. lightingShaderProgram->enableAttributeArray("normal");
    20. lightingShaderProgram->setAttributeArray("textureCoordinate", cubeTextureCoordinates.constData());
    21. lightingShaderProgram->enableAttributeArray("textureCoordinate");
    22.  
    23. glDrawArrays(GL_TRIANGLES, 0, cubeVertices.size());
    24.  
    25. lightingShaderProgram->disableAttributeArray("vertex");
    26. lightingShaderProgram->disableAttributeArray("normal");
    27. lightingShaderProgram->disableAttributeArray("textureCoordinate");
    28.  
    29. lightingShaderProgram->release();
    30. }
    To copy to clipboard, switch view to plain text mode 

  6. The following user says thank you to saman_artorious for this useful post:

    stereoMatching (25th June 2013)

  7. #5
    Join Date
    Jan 2011
    Posts
    127
    Thanks
    42
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Do offscreen render(openGL) with Qt5

    can't you test your fbo instructions separately in another program?
    Sorry but I don't get it, do you mean test it with different shader codes?

Similar Threads

  1. Render image on QLabel using openGl
    By vinodpaul in forum Newbie
    Replies: 2
    Last Post: 14th August 2012, 18:57
  2. QGLWidget render or QGraphicsView with GL viewport render
    By QTInfinity in forum Qt Programming
    Replies: 2
    Last Post: 28th November 2011, 12:34
  3. OpenGL render to texture
    By Nicuvëo in forum Qt Programming
    Replies: 2
    Last Post: 26th March 2011, 13:07
  4. Replies: 1
    Last Post: 7th May 2010, 18:20
  5. Drawing to an offscreen buffer
    By Dutch112 in forum Qt Programming
    Replies: 5
    Last Post: 6th May 2009, 17:49

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.