Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. OpenGL Pixel Drawing
Forum Updated to NodeBB v4.3 + New Features

OpenGL Pixel Drawing

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 4.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    focusgfx
    wrote on last edited by
    #1

    Hi guys, I'm writing a nes emulator using Qt and C++, and now I'm writing the NES PPU (picture processing unit)
    and I want to use opengl, I already read the opengl window example, but I don't think this is what I need for this project, as it seems that this example is aimed toward drawing a whole frame more than drawing individual pixels, and I guess it would be too slow for this project as I need to call painter.setPen() everytime I need to draw a new pixel with different color.
    also I guess it would be slow because I need to access the on screen pixels around 90000 times in each frame and I need to acheive at least 60 FPS.
    the size of the window is 256*240, someone may thing that this is small enough to be fast even when using a rasterizer, but it can be slow when you draw it pixel by pixel.
    any help would be appreciated.

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,
      You shouldn't try to send painting commands to the OpenGL pixel by pixel. This will have terrible performance. Instead draw a single quad that fills the window and use a texture with desired dimensions for it .
      This will also scale up nicely as the filtered scaling is basically free on today's hardware.
      You can then "stream" the texture updates (computed on the CPU) by mapping it to the client memory space via PBO. If that still doesn't perform good enough you can switch two PBOs to create sorta double buffering.
      Here's a nice article about it. Take a look at the "Streaming Texture Uploads":http://www.songho.ca/opengl/gl_pbo.html#unpack example

      Mind though that while this will secure a good drawing performance on the GPU side, your actual pixel operations done on the CPU should be optimized as much as possible (possibly in multiple threads?).

      1 Reply Last reply
      0
      • F Offline
        F Offline
        focusgfx
        wrote on last edited by
        #3

        thanks Chris Kawa,
        what I did was sending the drawing commands pixel by pixel and you're right it gave my a very slow performance, so I modified my code to create a QImage and fill it's pixels one by one like this:
        @QImage* frameBuffer;
        QOpenGLPaintDevice* device;
        QPainter* screenPainter;
        void WndNESScreen::PutPixel(unsigned int x, unsigned int y, unsigned char red, unsigned char green, unsigned char blue)
        {
        frameBuffer->bits()[y2563 + x3] = red;
        frameBuffer->bits()[y
        2563 + x3 + 1] = green;
        frameBuffer->bits()[y2563 + x*3 + 2] = blue;
        }@
        and when all the pixels are filled I use a QPainter::DrawImage() to draw the image scaled to the window size like this:

        @void WndNESScreen::FlushFrameBuffer()
        {
        device->setSize(size());//set device size to window size
        screenPainter->begin(device);//lock the device to the painter
        screenPainter->drawImage(0,0,frameBuffer->scaled(size()));//draw the QImage scaled to window size
        screenPainter->end();//release the device
        context->swapBuffers(this);//then swap the buffers to draw the image on screen
        }@

        and this gives me a good performance, is this right or am I doing something wrong ?

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          What I suggested was conceptually the same, but more low level, using core OpenGL functions instead of Qt wrappers. Also somewhat more complex.

          This will not get you the best that you could get. For example the scaled() method copies the image(not sure what the underlying method for that is) where i was talking about the hardware accelerated texture stretching.

          But if it's good it's good :) No reason to complicate things if the simple solution performs good enough.

          1 Reply Last reply
          0
          • F Offline
            F Offline
            focusgfx
            wrote on last edited by
            #5

            ok then, I guess I will use my current method for this project.
            thanks again for your help.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved