Author Topic: OpenGL Context Capture Demo  (Read 194 times)

Offline Ashish

  • The joy of coding is endless.
OpenGL Context Capture Demo
« on: June 18, 2018, 06:30:30 AM »
Hi everyone!
Now finally, it is possible to make OpenGL frame retain on screen.
The program code below does this -

Controls -  Press Space to capture OpenGL context and 'c' to clear software screen.


Code: [Select]
'OpenGL context capture example
'by Ashish Kushwaha

_TITLE "Hit *Space* to capture GL context and 'c' to clear software screen"
SCREEN _NEWIMAGE(600, 600, 32)

DIM SHARED glAllow AS _BYTE
DIM SHARED GL_Color_Buffer~%%(_WIDTH * _HEIGHT * 3)
DIM SHARED keyHit AS LONG

DIM SHARED GL_Context&, buffer_done
buffer_done = 0
'CLS
_GLRENDER _BEHIND
glAllow = -1
DO
    keyHit = _KEYHIT
    IF keyHit = ASC("c") THEN CLS , 1
    IF buffer_done THEN
        _CLEARCOLOR _RGB(0, 0, 0), GL_Context&
        _PUTIMAGE , GL_Context&
        _FREEIMAGE GL_Context&
        buffer_done = 0
    END IF
    _DISPLAY
    _LIMIT 30
LOOP


SUB _GL ()
    STATIC fps AS LONG
    IF NOT glAllow THEN EXIT SUB

    '_glDisable _GL_MULTISAMPLE <<<< uncomment this line if you are using latest (06/18/2018) build of QB64.

    _glViewport 0, 0, _WIDTH, _HEIGHT

    _glClearColor 0, 0, 0, 1
    _glClear _GL_COLOR_BUFFER_BIT

    _glMatrixMode _GL_MODELVIEW
    _glLoadIdentity

    _glRotatef fps, 0, 0, 1

    _glBegin _GL_TRIANGLES

    _glColor3f 1, 0, 0
    _glVertex2f 0, 1
    _glColor3f 0, 1, 0
    _glVertex2f -1, -1
    _glColor3f 0, 0, 1
    _glVertex2f 1, -1
    _glEnd

    IF keyHit = ASC(" ") AND NOT buffer_done THEN GL_Context& = getOpenGLContextImage: buffer_done = 1

    _glFlush

    fps = fps + 1
END SUB

FUNCTION getOpenGLContextImage& ()
    'storing GL Color Buffer in our  GL_Color_Buffer() array
    _glReadBuffer _GL_BACK
    _glPixelStorei _GL_UNPACK_ALIGNMENT, 1
    _glReadPixels 0, 0, _WIDTH, _HEIGHT, _GL_RGB, _GL_UNSIGNED_BYTE, _OFFSET(GL_Color_Buffer~%%())

    $CHECKING:OFF
    getOpenGLContextImage& = _NEWIMAGE(_WIDTH, _HEIGHT, 32) 'create an image handle
    DIM m AS _MEM
    m = _MEMIMAGE(getOpenGLContextImage&) 'store it in memory
    i& = 0
    FOR y = _HEIGHT(getOpenGLContextImage&) - 1 TO 0 STEP -1
        FOR x = 0 TO _WIDTH(getOpenGLContextImage&) - 1
            index& = 4 * (x + y * _WIDTH(getOpenGLContextImage&))
            _MEMPUT m, m.OFFSET + index&, GL_Color_Buffer~%%(i& + 2) AS _UNSIGNED _BYTE 'blue
            _MEMPUT m, m.OFFSET + index& + 1, GL_Color_Buffer~%%(i& + 1) AS _UNSIGNED _BYTE 'green
            _MEMPUT m, m.OFFSET + index& + 2, GL_Color_Buffer~%%(i&) AS _UNSIGNED _BYTE 'red
            _MEMPUT m, m.OFFSET + index& + 3, 255 AS _UNSIGNED _BYTE 'alpha
            i& = i& + 3
    NEXT x, y
    _MEMFREE m
    $CHECKING:ON
END FUNCTION

« Last Edit: June 18, 2018, 08:58:20 AM by Ashish »
if (Me.success) {Me.improve()} else {Me.tryAgain()}


aKFrameWork - http://bit.ly/aKFrameWork
Menu System - http://bit.ly/guiMenuBar
p5.js in QB64 - http://bit.ly/p5jsbas

@KingOfCoders

Offline Petr

  • I am instructed.
Re: OpenGL Context Capture Demo
« Reply #1 on: June 18, 2018, 05:13:39 PM »
Thanks for sharing. This is very useful, knowing how to do it.

Offline Ashish

  • The joy of coding is endless.
Re: OpenGL Context Capture Demo
« Reply #2 on: June 19, 2018, 04:43:03 AM »
Thanks for sharing. This is very useful, knowing how to do it.
I'm glad that it is useful to you. :)
if (Me.success) {Me.improve()} else {Me.tryAgain()}


aKFrameWork - http://bit.ly/aKFrameWork
Menu System - http://bit.ly/guiMenuBar
p5.js in QB64 - http://bit.ly/p5jsbas

@KingOfCoders

Offline Ashish

  • The joy of coding is endless.
Re: OpenGL Context Capture Demo
« Reply #3 on: June 23, 2018, 12:47:53 PM »
Here's a fading effect achieved by software screen -
Code: [Select]
'OpenGL context capture example
'by Ashish Kushwaha

_TITLE "Rendering OpenGL to software screen"
SCREEN _NEWIMAGE(600, 600, 32)

DIM SHARED glAllow AS _BYTE
DIM SHARED GL_Color_Buffer~%%((_WIDTH * _HEIGHT * 4) - 1)
DIM SHARED keyHit AS LONG

DIM SHARED GL_Context&, buffer_done

buffer_done = 0
'CLS
_GLRENDER _BEHIND
glAllow = -1
DO
    keyHit = _KEYHIT

    IF buffer_done THEN
        _CLEARCOLOR _RGB(0, 0, 0), GL_Context&
        _PUTIMAGE (0, _HEIGHT - 1)-(_WIDTH - 1, 0), GL_Context& 'flip again the image (opengl returns a vertically fliped image)
        _FREEIMAGE GL_Context&
        buffer_done = 0
    END IF
    LINE (0, 0)-(600, 600), _RGBA(0, 0, 0, 10), BF
    _DISPLAY
    _LIMIT 60
LOOP UNTIL INKEY$ <> ""


SUB _GL ()
    STATIC fps AS LONG, tt#
    IF NOT glAllow THEN EXIT SUB
    IF fps = 0 THEN tt# = TIMER

    _glViewport 0, 0, _WIDTH, _HEIGHT

    _glMatrixMode _GL_MODELVIEW
    _glLoadIdentity

    _glRotatef fps, 0, 0, 1

    _glBegin _GL_TRIANGLES

    _glColor3f 1, 0, 0
    _glVertex2f 0, 1
    _glColor3f 0, 1, 0
    _glVertex2f -1, -1
    _glColor3f 0, 0, 1
    _glVertex2f 1, -1
    _glEnd


    IF NOT buffer_done THEN GL_Context& = getOpenGLContextImage: buffer_done = 1

    _glFlush

    fps = fps + 1
END SUB

FUNCTION getOpenGLContextImage& ()
    'storing GL Color Buffer in our  GL_Color_Buffer() array
    _glReadBuffer _GL_BACK
    _glPixelStorei _GL_UNPACK_ALIGNMENT, 1
    _glReadPixels 0, 0, _WIDTH, _HEIGHT, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, _OFFSET(GL_Color_Buffer~%%())

    $CHECKING:OFF

    ' the below one will store vertically flip image
    getOpenGLContextImage& = _NEWIMAGE(_WIDTH, _HEIGHT, 32) 'create an image handle
    DIM m AS _MEM, m2 AS _MEM

    m = _MEMIMAGE(getOpenGLContextImage&) 'store it in memory
    m2 = _MEM(GL_Color_Buffer~%%())

    _MEMCOPY m2, m2.OFFSET, m2.SIZE TO m, m.OFFSET 'using _MEMCOPY instead of nested loop
    _MEMFREE m
    _MEMFREE m2

    $CHECKING:ON
END FUNCTION

if (Me.success) {Me.improve()} else {Me.tryAgain()}


aKFrameWork - http://bit.ly/aKFrameWork
Menu System - http://bit.ly/guiMenuBar
p5.js in QB64 - http://bit.ly/p5jsbas

@KingOfCoders