Results 1 to 2 of 2

Thread: target buffer for glReadPixels

  1. #1
    Join Date
    Feb 2016
    Posts
    3
    Mentioned
    0 Post(s)
    Quoted
    5 Post(s)

    Default target buffer for glReadPixels

    I started writing botting library in C# based on image recognition. Was using gdi32 functions bitblt and getpixel, but this way i'm unable to read games rendered with openGl or directX if they are not visible on desktop. I assume my options to do so is either using specific openGl and directX functions or dwm thumbnails.

    I'm currently unable to figure out how to bind frame buffer for reading pixels in openGl game. Assuming i should use glBindBuffer how do i get glenum of current frame of specified client?

    I have read Brandon's opengl plugin tutorial and as far as i understand i could write my own opengl plugin and inject it into target process (i think it is what fraps do) to obtain desirable bitmaps, although i'm worried about detection and this method seems fairly complicated.

    Maybe i should rather focus on dwm thumbnails method, but i'm afraid it will be less flexible and use more resources?

    Or is there other better ways for obtaining bitmaps or pixels from openGl rendered game?

    All information on this topic is really appreciated.

  2. #2
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by iBleedBlack View Post
    I started writing botting library in C# based on image recognition. Was using gdi32 functions bitblt and getpixel, but this way i'm unable to read games rendered with openGl or directX if they are not visible on desktop. I assume my options to do so is either using specific openGl and directX functions or dwm thumbnails.

    I'm currently unable to figure out how to bind frame buffer for reading pixels in openGl game. Assuming i should use glBindBuffer how do i get glenum of current frame of specified client?

    I have read Brandon's opengl plugin tutorial and as far as i understand i could write my own opengl plugin and inject it into target process (i think it is what fraps do) to obtain desirable bitmaps, although i'm worried about detection and this method seems fairly complicated.

    Maybe i should rather focus on dwm thumbnails method, but i'm afraid it will be less flexible and use more resources?

    Or is there other better ways for obtaining bitmaps or pixels from openGl rendered game?

    All information on this topic is really appreciated.


    C++ Code:
    #include <new>
    #include <cstdint>
    #include <string>

    std::uint8_t* readBackBuffer()
    {
        //Get BackBuffer Dimensions..
        GLint ViewPort[4] = {0};
        glGetIntegerv(GL_VIEWPORT, ViewPort);

        //Set glReadBuffer to read the back-buffer instead of the front-buffer (Double Buffering)..
        glReadBuffer(GL_BACK);

        //Set the alignment to packed contains alpha channel..
        glPixelStorei(GL_PACK_ALIGNMENT, 4);


        //Allocate a buffer and read..
        std::uint8_t* buffer = new(std::nothrow) std::uint8_t[ViewPort[2] * ViewPort[3] * 4];

        if (buffer)
        {
            glReadPixels(0, 0, ViewPort[2], ViewPort[3], GL_BGRA, GL_UNSIGNED_BYTE, buffer); //Read in BGRA format..
            return buffer;
        }

        return nullptr;
    }


    static GLuint pbo[2] = {0};
    std::uint8_t* readBackBufferAsync()
    {
        static int readIndex = 0;
        static int writeIndex = 1;
        static bool initBuffers = false;

        //Get BackBuffer Dimensions..
        GLint ViewPort[4] = {0};
        glGetIntegerv(GL_VIEWPORT, ViewPort);

        //Create PBO's..
        if (!initBuffers)
        {
            initBuffers = true;
            glGenBuffers(2, &pbo[0]);
            glBindBuffer(GL_PIXEL_PACK_BUFFER, &pbo[0]);
            glBindBufferData(GL_PIXEL_BACK_BUFFER, ViewPort[2] * ViewPort[3] * 4, 0, GL_STREAM_READ);

            glBindBuffer(GL_PIXEL_PACK_BUFFER, &pbo[1]);
            glBindBufferData(GL_PIXEL_BACK_BUFFER, ViewPort[2] * ViewPort[3] * 4, 0, GL_STREAM_READ);
            glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
        }

        //Set glReadBuffer to read the back-buffer instead of the front-buffer (Double Buffering)..
        glReadBuffer(GL_BACK);

        //Swap Read and Write.
        writeIndex = (writeIndex + 1) % 2;
        readIndex = (writeindex + 1) % 2;

        //Bind the PBO and Read..
        glBindBuffer(GL_PIXEL_PACK_BUFFER, &pbo[writeIndex]);
        glReadPixels(0, 0, ViewPort[2], ViewPort[3], GL_BGRA, GL_UNSIGNED_BYTE, nullptr);

        //Map the PBO for copying..
        void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

        if (data)
        {
            //Copy the pixels from the PBO our buffer..
            std::uint8_t* buffer = new (std::nothrow) std::uint8_t[ViewPort[2] * ViewPort[3] * 4];
            std::memcpy(buffer, data, ViewPort[2] * ViewPort[3] * 4);

            //Unmap the PBO and Unbind it.
            glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
            glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
            data = nullptr;
            return buffer;
        }

        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
        return nullptr;
    }

    void FreePixels(std::uint8_t* &buffer)
    {
        if (buffer)
        {
            delete[] buffer;
            buffer = nullptr;
        }
    }

    void FreePBOBuffers()
    {
        glDeleteBuffers(2, &pbo[0]);
        std::memset(&pbo[0], 0, sizeof(pbo));
    }


    The async one is what I was planning on doing for Simba for NXT.. It would work with RS3 as well.. It works by creating an off-screen buffer so that when you call glReadPixels, it doesn't synchronize and "stall/wait".. This means you'd have a zero FPS drop reading the back buffer.. already tested it too.
    Last edited by Brandon; 06-22-2017 at 02:23 PM.
    I am Ggzz..
    Hackintosher

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •