• Advertisement
Sign in to follow this  

OpenGL Qt and OpenGL

This topic is 1512 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone.

 

I have started porting our map editor from a MFC sdi application to a Qt application and i'm having issues with OpenGL. By the way i'm quite new to Qt. I'm nusing Qt 5.1.1 with Visual Studio 2012 toolchain and Qt Creator 2.8.1.

 

I have a QApplication with a main window derived from QMainWindow. The main window contains a few docking windows on the right, left and bottom docking area. For the main widget of the main window i subclassed QGLWidget for rendering. For some reason this widget is all black.

 

The QGLWidget subclass overrides only the initializeGL, resizeGL and painGL methods. The code for these methods is minimal :

/////////////////////////////////////////////////////////////////////////////////////////
/// One time initialization.
void SceneView::initializeGL()
{
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
}

/////////////////////////////////////////////////////////////////////////////////////////
/// Called when the widget is resized.
void SceneView::resizeGL(int w, int h)
{
    // Setup viewport, projection etc.
    glViewport(0, 0, (GLint)w, (GLint)h);
}

/////////////////////////////////////////////////////////////////////////////////////////
/// Called when the widget is redrawn.
void SceneView::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
}

Whatever the clear color i chose, the widget is always black.

 

I have tried creating the widget with and without parent, creating the widget alone (only window in the application) and it didn't change anything. I have tried to call swapBuffers (which, according to the documentation i shouln't do) and it didn't work.

 

Also, i have notices that, when resizing either one of the docking widget, there is some flickering (only when the widgets are docked). This doesn't appen if i replace the central widget by a QTextEdit for example.

 

Anyone have any idea what the problem could be ? Some of the examples used basically the same method and they work.

Edited by Laval B

Share this post


Link to post
Share on other sites
Advertisement

GL_COLOR_CLEAR_VALUE? I think you want to use GL_COLOR_BUFFER_BIT instead.

 

 

I'm sorry, wrong copy/past, GL_COLOR_BUFFER_BIT doesn't work.

Share this post


Link to post
Share on other sites

Have you tried using qglClearColor? Or calling glClearColor before clearing? Qt probably calls glClearColor by itself before going in the paintGL method.

Share this post


Link to post
Share on other sites
Check exactly which Qt version you have downloaded. The 5.x generation of Qt is so far available in two versions: one using real OpenGL and one using OpenGL ES via a DirectX emulator. If you are using the emulated OpenGL you need to make sure all your OpenGL is including the emulator headers (somewhere in Qt 3rdparty folder) and you cannot just link to the usual OpenGL libraries.

Share this post


Link to post
Share on other sites

I think I remember some members here having "problems" with Qt and OpenGL before, and I believe the problem was, in short, that Qt deactivated the rendering context at certain points. The solution was simply to reactivate it in the rendering function. Looking at the Qt tutorials and the documentation for the QGLWidget, it looks like you need to call the makeCurrent member on the QGLWidget as soon as you enter the rendering function.

 

I haven't used any of the OpenGL interfaces in Qt yet so I don't know if this is relevant, but take a look at it at least.

Share this post


Link to post
Share on other sites

Have you tried using qglClearColor? Or calling glClearColor before clearing? Qt probably calls glClearColor by itself before going in the paintGL method.

 

qglClearColor doesn't change anything. According to the documentation the only functions that are called by the framework are makeCurrent and swapBuffers. I have also tried calling makeCurrent in renderGL, initializeGL and resizeGL to make sure the right context was used and it didn't change anything. According to the documentation, you only need to call makeCurrent if you call gl functions outside of those functions (the overriden ones).

 

 

Check exactly which Qt version you have downloaded. The 5.x generation of Qt is so far available in two versions: one using real OpenGL and one using OpenGL ES via a DirectX emulator. If you are using the emulated OpenGL you need to make sure all your OpenGL is including the emulator headers (somewhere in Qt 3rdparty folder) and you cannot just link to the usual OpenGL libraries.

 

I'm using Qt 5.1.1 for Windows 64 bits VS2012. There is a version of Qt 5.1.1 for Windows 64 bits VS2012 OpenGL which is not the one i'm using. Is that what you are referring to ?

 

An emulated framework limited to OpenGL ES is definitely not what i need. The engine uses core profile 3.3 and above. 

Edited by Laval B

Share this post


Link to post
Share on other sites
I'm pretty sure you are using the OpenGL ES emulator version. To be sure check if there is a libEGL.dll and libGLESv2.dll in your bin directory with the rest of the Qt DLLs.

Share this post


Link to post
Share on other sites

I'm pretty sure you are using the OpenGL ES emulator version. To be sure check if there is a libEGL.dll and libGLESv2.dll in your bin directory with the rest of the Qt DLLs.

 

Yes, these dll are present. I have downloaded the OpenGL version. It works but now when i resize the docking windows, or the application for that matter, everything is flickering alot whether or not i am running in debug or in release. Before, there was only a small flicker in debug mode.

Share this post


Link to post
Share on other sites
I can think of two possible causes:
1) You are rendering in the update thread. At least when using QtQuick the thread that is doing all the rendering (and is the only one allowed to) is always a different thread from the normal update thread.
2) You are polluting the GL state. At least QtQuick is a bit picky about anyone changing the GL state. Make sure any buffers bound (especially vertex and index buffer) are restored to their orginal value when you are done rendering. Also, the cull mode (whether or not it is enabled and the cull face) need to be preserved. Saving these states allowed me to integrate the rather monolithic renderer I have to work with with Qt.

Share this post


Link to post
Share on other sites

You are rendering in the update thread. At least when using QtQuick the thread that is doing all the rendering (and is the only one allowed to) is always a different thread from the normal update thread.

 

The only place i'm calling opengl functions are in initializeGL, paintGL and resizeGL as recomended in the documentation.

 

 

 


You are polluting the GL state. At least QtQuick is a bit picky about anyone changing the GL state. Make sure any buffers bound (especially vertex and index buffer) are restored to their orginal value when you are done rendering. Also, the cull mode (whether or not it is enabled and the cull face) need to be preserved. Saving these states allowed me to integrate the rather monolithic renderer I have to work with with Qt.

 

I'm not sure when i need to save and restore these states. Everything is flickering when i'm resizing something, even the scrollbars of the docking windows. The problem is related to the OpenGL Widget though since it doesn't happen if i replace it with a standard widget like QTextEditor.

Edited by Laval B

Share this post


Link to post
Share on other sites
Unfortunately I don't think I can be of more help then. My experience is primarily with QtQuick, the application uses no widgets (just a top level window and the contained QtQuick UI). You might have better luck producing a minimum code sample that shows the problem and posting it on a Qt-dedicated forum like over at qt-project.org.

Share this post


Link to post
Share on other sites

Unfortunately I don't think I can be of more help then. My experience is primarily with QtQuick, the application uses no widgets (just a top level window and the contained QtQuick UI). You might have better luck producing a minimum code sample that shows the problem and posting it on a Qt-dedicated forum like over at qt-project.org.

 

Thank you very much for your help, it's appreciated.

 

As a complementary info : if i remove the docking windows to keep only the GLWidget, it is flickering when i resize the app. If i compile and run the examples, they are flickering too. They were not with the other Qt version.

 

I'll follow your advice and post the code on a Qt forum.

Edited by Laval B

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Now

  • Advertisement
  • Similar Content

    • By Balma Alparisi
      i got error 1282 in my code.
      sf::ContextSettings settings; settings.majorVersion = 4; settings.minorVersion = 5; settings.attributeFlags = settings.Core; sf::Window window; window.create(sf::VideoMode(1600, 900), "Texture Unit Rectangle", sf::Style::Close, settings); window.setActive(true); window.setVerticalSyncEnabled(true); glewInit(); GLuint shaderProgram = createShaderProgram("FX/Rectangle.vss", "FX/Rectangle.fss"); float vertex[] = { -0.5f,0.5f,0.0f, 0.0f,0.0f, -0.5f,-0.5f,0.0f, 0.0f,1.0f, 0.5f,0.5f,0.0f, 1.0f,0.0f, 0.5,-0.5f,0.0f, 1.0f,1.0f, }; GLuint indices[] = { 0,1,2, 1,2,3, }; GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(float) * 5, (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(float) * 5, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(1); GLuint texture[2]; glGenTextures(2, texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageOne = new sf::Image; bool isImageOneLoaded = imageOne->loadFromFile("Texture/container.jpg"); if (isImageOneLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageOne->getSize().x, imageOne->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageOne->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageOne; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); sf::Image* imageTwo = new sf::Image; bool isImageTwoLoaded = imageTwo->loadFromFile("Texture/awesomeface.png"); if (isImageTwoLoaded) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageTwo->getSize().x, imageTwo->getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageTwo->getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D); } delete imageTwo; glUniform1i(glGetUniformLocation(shaderProgram, "inTextureOne"), 0); glUniform1i(glGetUniformLocation(shaderProgram, "inTextureTwo"), 1); GLenum error = glGetError(); std::cout << error << std::endl; sf::Event event; bool isRunning = true; while (isRunning) { while (window.pollEvent(event)) { if (event.type == event.Closed) { isRunning = false; } } glClear(GL_COLOR_BUFFER_BIT); if (isImageOneLoaded && isImageTwoLoaded) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture[1]); glUseProgram(shaderProgram); } glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); window.display(); } glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteProgram(shaderProgram); glDeleteTextures(2,texture); return 0; } and this is the vertex shader
      #version 450 core layout(location=0) in vec3 inPos; layout(location=1) in vec2 inTexCoord; out vec2 TexCoord; void main() { gl_Position=vec4(inPos,1.0); TexCoord=inTexCoord; } and the fragment shader
      #version 450 core in vec2 TexCoord; uniform sampler2D inTextureOne; uniform sampler2D inTextureTwo; out vec4 FragmentColor; void main() { FragmentColor=mix(texture(inTextureOne,TexCoord),texture(inTextureTwo,TexCoord),0.2); } I was expecting awesomeface.png on top of container.jpg

    • By khawk
      We've just released all of the source code for the NeHe OpenGL lessons on our Github page at https://github.com/gamedev-net/nehe-opengl. code - 43 total platforms, configurations, and languages are included.
      Now operated by GameDev.net, NeHe is located at http://nehe.gamedev.net where it has been a valuable resource for developers wanting to learn OpenGL and graphics programming.

      View full story
    • By TheChubu
      The Khronos™ Group, an open consortium of leading hardware and software companies, announces from the SIGGRAPH 2017 Conference the immediate public availability of the OpenGL® 4.6 specification. OpenGL 4.6 integrates the functionality of numerous ARB and EXT extensions created by Khronos members AMD, Intel, and NVIDIA into core, including the capability to ingest SPIR-V™ shaders.
      SPIR-V is a Khronos-defined standard intermediate language for parallel compute and graphics, which enables content creators to simplify their shader authoring and management pipelines while providing significant source shading language flexibility. OpenGL 4.6 adds support for ingesting SPIR-V shaders to the core specification, guaranteeing that SPIR-V shaders will be widely supported by OpenGL implementations.
      OpenGL 4.6 adds the functionality of these ARB extensions to OpenGL’s core specification:
      GL_ARB_gl_spirv and GL_ARB_spirv_extensions to standardize SPIR-V support for OpenGL GL_ARB_indirect_parameters and GL_ARB_shader_draw_parameters for reducing the CPU overhead associated with rendering batches of geometry GL_ARB_pipeline_statistics_query and GL_ARB_transform_feedback_overflow_querystandardize OpenGL support for features available in Direct3D GL_ARB_texture_filter_anisotropic (based on GL_EXT_texture_filter_anisotropic) brings previously IP encumbered functionality into OpenGL to improve the visual quality of textured scenes GL_ARB_polygon_offset_clamp (based on GL_EXT_polygon_offset_clamp) suppresses a common visual artifact known as a “light leak” associated with rendering shadows GL_ARB_shader_atomic_counter_ops and GL_ARB_shader_group_vote add shader intrinsics supported by all desktop vendors to improve functionality and performance GL_KHR_no_error reduces driver overhead by allowing the application to indicate that it expects error-free operation so errors need not be generated In addition to the above features being added to OpenGL 4.6, the following are being released as extensions:
      GL_KHR_parallel_shader_compile allows applications to launch multiple shader compile threads to improve shader compile throughput WGL_ARB_create_context_no_error and GXL_ARB_create_context_no_error allow no error contexts to be created with WGL or GLX that support the GL_KHR_no_error extension “I’m proud to announce OpenGL 4.6 as the most feature-rich version of OpenGL yet. We've brought together the most popular, widely-supported extensions into a new core specification to give OpenGL developers and end users an improved baseline feature set. This includes resolving previous intellectual property roadblocks to bringing anisotropic texture filtering and polygon offset clamping into the core specification to enable widespread implementation and usage,” said Piers Daniell, chair of the OpenGL Working Group at Khronos. “The OpenGL working group will continue to respond to market needs and work with GPU vendors to ensure OpenGL remains a viable and evolving graphics API for all its customers and users across many vital industries.“
      The OpenGL 4.6 specification can be found at https://khronos.org/registry/OpenGL/index_gl.php. The GLSL to SPIR-V compiler glslang has been updated with GLSL 4.60 support, and can be found at https://github.com/KhronosGroup/glslang.
      Sophisticated graphics applications will also benefit from a set of newly released extensions for both OpenGL and OpenGL ES to enable interoperability with Vulkan and Direct3D. These extensions are named:
      GL_EXT_memory_object GL_EXT_memory_object_fd GL_EXT_memory_object_win32 GL_EXT_semaphore GL_EXT_semaphore_fd GL_EXT_semaphore_win32 GL_EXT_win32_keyed_mutex They can be found at: https://khronos.org/registry/OpenGL/index_gl.php
      Industry Support for OpenGL 4.6
      “With OpenGL 4.6 our customers have an improved set of core features available on our full range of OpenGL 4.x capable GPUs. These features provide improved rendering quality, performance and functionality. As the graphics industry’s most popular API, we fully support OpenGL and will continue to work closely with the Khronos Group on the development of new OpenGL specifications and extensions for our customers. NVIDIA has released beta OpenGL 4.6 drivers today at https://developer.nvidia.com/opengl-driver so developers can use these new features right away,” said Bob Pette, vice president, Professional Graphics at NVIDIA.
      "OpenGL 4.6 will be the first OpenGL release where conformant open source implementations based on the Mesa project will be deliverable in a reasonable timeframe after release. The open sourcing of the OpenGL conformance test suite and ongoing work between Khronos and X.org will also allow for non-vendor led open source implementations to achieve conformance in the near future," said David Airlie, senior principal engineer at Red Hat, and developer on Mesa/X.org projects.

      View full story
    • By _OskaR
      Hi,
      I have an OpenGL application but without possibility to wite own shaders.
      I need to perform small VS modification - is possible to do it in an alternative way? Do we have apps or driver modifictions which will catch the shader sent to GPU and override it?
    • By xhcao
      Does sync be needed to read texture content after access texture image in compute shader?
      My simple code is as below,
      glUseProgram(program.get());
      glBindImageTexture(0, texture[0], 0, GL_FALSE, 3, GL_READ_ONLY, GL_R32UI);
      glBindImageTexture(1, texture[1], 0, GL_FALSE, 4, GL_WRITE_ONLY, GL_R32UI);
      glDispatchCompute(1, 1, 1);
      // Does sync be needed here?
      glUseProgram(0);
      glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
      glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                     GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
      glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
       
      Compute shader is very simple, imageLoad content from texture[0], and imageStore content to texture[1]. Does need to sync after dispatchCompute?
  • Advertisement