Something weird is going on.  If I make the viewport bigger when drawing to
the screen then I see the blue triangle:

; switch to screen framebuffer
  (glBindFramebuffer GL_DRAW_FRAMEBUFFER 0)
  (glViewport 0 0 1000 1000)  ; somehow this makes a difference?

If I make the viewport exactly match the window size, then as I make the
window bigger the blue triangle slowly fades in once it gets near to
fullscreen.  Do you see this as well?

On Sun, Apr 8, 2018 at 9:45 AM, Jens Axel Søgaard <[email protected]>
wrote:

> Hi David,
>
> Thanks for the viewport suggestion.
> I have made a version below that sets the viewport.
> Saving the logo+triangle shows that the blue triangle has been drawn on
> the frame buffer.
> It disappears (?!) when I try to copy contents from the framebuffer to
> screen though.
>
> #lang racket/gui
> (require opengl opengl/util ffi/vector)
>
> (define logo-texture #f)
> (define (load-logo-texture)
>   (unless logo-texture
>     (set! logo-texture (load-texture "plt-logo-red-gradient.png" #:repeat
> 'both)))
>   logo-texture)
>
> (define (clear r g b a)
>   (glClearColor r g b a)
>   (glClear (bitwise-ior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)))
>
> (define (set-color r g b)
>   (glColor3f r g b))
>
> (define (reset-color)
>   (set-color 1. 1. 1.))
>
> (define (draw-triangle x1 y1 x2 y2 x3 y3)
>   (glBegin GL_TRIANGLES)
>   (glVertex3d  x1 y1  0.)
>   (glVertex3d  x2 y2  0.)
>   (glVertex3d  x3 y3  0.)
>   (glEnd))
>
> (define sanity #f)
>
> (define snapshot? #f)
> (define bs (make-bytes (* 4 (* 256 256)) 0))
> (define (example)
>   ; make framebuffer
>   (define fbo-ids (glGenFramebuffers 1))
>   (define fbo     (u32vector-ref fbo-ids 0))
>   ; swith to the new framebuffer
>   (glBindFramebuffer GL_FRAMEBUFFER fbo)
>   ; load logo texture (it is cached, so only loaded once)
>   (load-logo-texture) (unless logo-texture (error))
>   ; use texture as color attachment 0
>   (glFramebufferTexture2D GL_FRAMEBUFFER GL_COLOR_ATTACHMENT0
> GL_TEXTURE_2D logo-texture 0)
>   (glBindTexture GL_TEXTURE_2D logo-texture)
>   (glDrawBuffer GL_COLOR_ATTACHMENT0)
>   ; we will now draw on the texture
>   (glViewport 0 0 256 256)   ; size of logo is 256x256
>   (set-color 0.0 0.0 1.0)    ; blue color
>   (draw-triangle 0.0 0.0  200.0 200.0  200.0 -200.)
>   (glFinish)
>   ; let's make a snapshot of what we have
>   (unless snapshot?
>     (set! snapshot? #t)
>     (glGetTexImage GL_TEXTURE_2D 0 GL_RGBA GL_UNSIGNED_BYTE bs)
>     (rgba->argb! bs))
>   ; Note: (bytes->bitmap bs 256 256) in the repl
>   ;       shows the logo with a blue triangle on top (as expected)
>
>   ;;; *** Now we want to transfer the logo+triangle to the screen
>
>   ; switch to screen framebuffer
>   (glBindFramebuffer GL_DRAW_FRAMEBUFFER 0)
>   ; draw something to the screen, so we can see that the switch works
>   ; red screen background
>   (clear     1.0 0.0 0.0 0.0)
>   ; green triangle
>   (set-color 0.0 1.0 0.0)
>   (draw-triangle 0.0 0.0  0.3 0.0  0.0 0.3)
>   ; we do see the green triangle in the result
>
>   ; reset color in order for the transparency blending to work
>   (reset-color)
>   ; read from the texture in the framebuffer
>   (glBindFramebuffer GL_READ_FRAMEBUFFER fbo)
>   (glEnable GL_TEXTURE_2D)
>   (glEnable GL_BLEND)
>   (glBlendFunc GL_ONE GL_ONE_MINUS_SRC_ALPHA) ; This is the correct
> setting for pre-multiplied alpha.
>   ; This is a square containing 2x2 copies of the logo
>   (define texcoord-array (s16vector  0    2     2    2   2    0     0
> 0))
>   ; This is a square in the middle of the screen
>   (define vertex-array   (f64vector -0.5 -0.5   0.5 -0.5 0.5  0.5  -0.5
> 0.5))
>   (let-values (((type cptr) (gl-vector->type/cpointer vertex-array)))
>     (glVertexPointer 2 type 0 cptr))
>   (let-values (((type cptr) (gl-vector->type/cpointer texcoord-array)))
>     (glTexCoordPointer 2 type 0 cptr))
>   (glEnableClientState GL_VERTEX_ARRAY)
>   (glEnableClientState GL_TEXTURE_COORD_ARRAY)
>   ; Now draw the square on screen using the prepared texture
>   (glDrawArrays GL_QUADS 0 4)
>   ; clean up
>   (glDisableClientState GL_TEXTURE_COORD_ARRAY)
>   (glDisableClientState GL_VERTEX_ARRAY)
>   (glDisable GL_TEXTURE_2D)
>   (void))
>
> ;;;
> ;;; MODEL
> ;;;
>
> (define frames-per-second 60.)
> (define milliseconds-per-frame (/ 1000. frames-per-second))
> (define time 0.)
>
> (define (on-tick)
>   (set! time (+ time 1.))
>   (send gl on-paint))
>
> ;;;
> ;;; GUI
> ;;;
>
> (define (resize w h)
>   (glViewport 0 0 w h))
>
> (define (example2)
>   (define v (* 2. pi (/ time 60)))
>   (define c (cos v))
>   (define s (sin v))
>
>   (glClearColor 0.0 0.0 0.0 0.0)
>   (glClear GL_COLOR_BUFFER_BIT)
>
>   (glBegin GL_TRIANGLES)
>   (glColor3f    c   0.   0.)
>   (glVertex3d   c   0    0)
>   (glColor3f    0.   s   0.)
>   (glVertex3d   0.   s   0.)
>   (glColor3f    0.   0.   1.)
>   (glVertex3d  -1.  -1.   0.)
>   (glEnd))
>
> (define my-canvas%
>   (class* canvas% ()
>     (inherit with-gl-context swap-gl-buffers)
>     (define/override (on-paint)             (with-gl-context (λ()
> (example) (swap-gl-buffers))))
>     (define/override (on-size width height) (with-gl-context (λ() (resize
> width height) (on-paint))))
>     (super-instantiate () (style '(gl)))))
>
> (define win (new frame% [label "Racket Rosetta Code OpenGL example"]
>                  [min-width 200] [min-height 200]))
> (define gl  (new my-canvas% [parent win]))
>
> (new timer%
>      [interval (exact-floor milliseconds-per-frame)] ; in milliseconds
>      [notify-callback on-tick])
>
> (send win show #t)
>
> (define (bytes->bitmap bs width height)
>   (define bm (make-bitmap width height))
>   (send bm set-argb-pixels 0 0 width height bs)
>   bm)
>
> (define (rgba->argb! pixels)
>   (for ((i (in-range (/ (bytes-length pixels) 4))))
>     (let* ((offset (* 4 i))
>            (  red (bytes-ref pixels (+ 0 offset)))
>            (green (bytes-ref pixels (+ 1 offset)))
>            ( blue (bytes-ref pixels (+ 2 offset)))
>            (alpha (bytes-ref pixels (+ 3 offset))))
>       (bytes-set! pixels (+ 0 offset) alpha)
>       (bytes-set! pixels (+ 1 offset) red)
>       (bytes-set! pixels (+ 2 offset) green)
>       (bytes-set! pixels (+ 3 offset) blue))))
>
>
>
>
> 2018-04-08 0:49 GMT+02:00 David Vanderson <[email protected]>:
>
>> I'm also learning, but I think in this case the viewport is not sized
>> correctly to draw to the texture.  I think you need something like this:
>>
>>   ; Draw a blue triangle  ***this is the part that isn't working***
>>   (glDrawBuffer GL_COLOR_ATTACHMENT0)   ; draw to color attachment 0
>>   (glDisable    GL_TEXTURE_2D)          ; do not use the texture when
>> drawing the triangle
>>   (glViewport 0 0 tw th)  ; set the viewport to the size of the texture
>> (get tw and th from the size of the png file bitmap)
>>   (clear     0.0 0.0 1.0 1.0)
>>   (set-color 0.0 1.0 0.0)
>>   (glDisable GL_BLEND)
>>   (draw-triangle -1.0 0.0  1.0 0.0  1.0 1.0)
>>
>>   ; switch to screen framebuffer
>>   (glBindFramebuffer GL_FRAMEBUFFER 0)
>>   (glViewport 0 0 W H)  ; set the viewport to the size of the framebuffer
>> (set W and H from resize handler)
>>
>> Does that help?
>>
>> Thanks,
>> Dave
>>
>> On Fri, Apr 6, 2018 at 2:05 PM, Jens Axel Søgaard <[email protected]>
>> wrote:
>>
>>> Hi All,
>>>
>>> I am looking into opengl and have so far learned to draw directly to the
>>> screen.
>>> However I'd like to do some offscreen rendering and have therefore tried
>>> to use a framebuffer.
>>> The program below does the following:
>>>
>>> 1. Makes a framebuffer
>>> 2. Adds a texture (a plt logo)
>>> 3. Draws a blue triangle on top of the logo
>>> 4. Switches to the screen
>>> 5. Draw a green triangle
>>> 6. Copies the logo with the blue triangle to the screen.
>>>
>>> My problem is that the blue triangle is missing in the result.
>>>
>>> The result:      https://imgur.com/NBJf2DG
>>> See program below.
>>>
>>> Ideas welcome.
>>>
>>> /Jens Axel
>>>
>>>
>>>
>>> #lang racket/gui
>>> (require opengl opengl/util ffi/vector)
>>>
>>> (define logo-texture #f)
>>> (define (load-logo-texture)
>>>   (unless logo-texture
>>>     (set! logo-texture (load-texture "plt-logo-red-gradient.png"
>>> #:repeat 'both)))
>>>   logo-texture)
>>>
>>> (define (clear r g b a)
>>>   (glClearColor r g b a)
>>>   (glClear (bitwise-ior GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)))
>>>
>>> (define (set-color r g b)
>>>   (glColor3f r g b))
>>>
>>> (define (reset-color)
>>>   (set-color 1. 1. 1.))
>>>
>>> (define (draw-triangle x1 y1 x2 y2 x3 y3)
>>>   (glBegin GL_TRIANGLES)
>>>   (glVertex3d  x1 y1  0.)
>>>   (glVertex3d  x2 y2  0.)
>>>   (glVertex3d  x3 y3  0.)
>>>   (glEnd))
>>>
>>> (define (example)
>>>   ; make framebuffer
>>>   (define fbo-ids (glGenFramebuffers 1))     ; this returns a vector of
>>> names
>>>   (define fbo     (u32vector-ref fbo-ids 0)) ; get the first framebuffer
>>>   ; swith to the new framebuffer
>>>   (glBindFramebuffer GL_FRAMEBUFFER fbo)  ; initialize framebuffer object
>>>   ; load logo texture if needed
>>>   (load-logo-texture) (unless logo-texture (error))
>>>   (glFramebufferTexture2D GL_FRAMEBUFFER GL_COLOR_ATTACHMENT0
>>> GL_TEXTURE_2D logo-texture 0)
>>>   (define status (glCheckFramebufferStatus GL_FRAMEBUFFER_EXT))
>>>   (define status-complete? (= status GL_FRAMEBUFFER_COMPLETE_EXT))
>>>
>>>   ; Draw a blue triangle  ***this is the part that isn't working***
>>>   (glDrawBuffer GL_COLOR_ATTACHMENT0)   ; draw to color attachment 0
>>>   (glDisable    GL_TEXTURE_2D)          ; do not use the texture when
>>> drawing the triangle
>>>   (clear     0.0 0.0 1.0 1.0)
>>>   (set-color 0.0 1.0 0.0)
>>>   (glDisable GL_BLEND)
>>>   (draw-triangle -1.0 0.0  1.0 0.0  1.0 1.0)
>>>
>>>   ; switch to screen framebuffer
>>>   (glBindFramebuffer GL_FRAMEBUFFER 0)
>>>   ; red background
>>>   (clear     1.0 0.0 0.0 0.0)
>>>   ; green triangle
>>>   (set-color 0.0 1.0 0.0) (draw-triangle 0.0 0.0  1.0 0.0  0.0 1.0)
>>>   ; Copy logo with blue triangle to screen
>>>   (reset-color)
>>>   (glEnable GL_TEXTURE_2D)
>>>   (glEnable GL_BLEND)
>>>   (glBlendFunc GL_ONE GL_ONE_MINUS_SRC_ALPHA) ; settings for
>>> pre-multiplied alpha.
>>>   (define vertex-array   (f64vector -0.5 -0.5   0.5 -0.5 0.5  0.5  -0.5
>>> 0.5))
>>>   (define texcoord-array (s16vector  0    2     2    2   2    0     0
>>> 0))
>>>   (let-values (((type cptr) (gl-vector->type/cpointer vertex-array)))
>>>     (glVertexPointer 2 type 0 cptr))
>>>   (let-values (((type cptr) (gl-vector->type/cpointer texcoord-array)))
>>>     (glTexCoordPointer 2 type 0 cptr))
>>>   (glEnableClientState GL_VERTEX_ARRAY)
>>>   (glEnableClientState GL_TEXTURE_COORD_ARRAY)
>>>
>>>   (glDrawArrays GL_QUADS 0 4)
>>>   (glDisableClientState GL_TEXTURE_COORD_ARRAY)
>>>   (glDisableClientState GL_VERTEX_ARRAY)
>>>   (glDisable GL_TEXTURE_2D)
>>>   (void))
>>>
>>> ;;;
>>> ;;; MODEL
>>> ;;;
>>>
>>> (define frames-per-second 60.)
>>> (define milliseconds-per-frame (/ 1000. frames-per-second))
>>> (define time 0.)
>>>
>>> (define (on-tick)
>>>   (set! time (+ time 1.))
>>>   (send gl on-paint))
>>>
>>> ;;;
>>> ;;; GUI
>>> ;;;
>>>
>>> (define (resize w h)
>>>   (glViewport 0 0 w h))
>>>
>>> (define (example2)
>>>   (define v (* 2. pi (/ time 60)))
>>>   (define c (cos v))
>>>   (define s (sin v))
>>>
>>>   (glClearColor 0.0 0.0 0.0 0.0)
>>>   (glClear GL_COLOR_BUFFER_BIT)
>>>
>>>   (glBegin GL_TRIANGLES)
>>>   (glColor3f    c   0.   0.)
>>>   (glVertex3d   c   0    0)
>>>   (glColor3f    0.   s   0.)
>>>   (glVertex3d   0.   s   0.)
>>>   (glColor3f    0.   0.   1.)
>>>   (glVertex3d  -1.  -1.   0.)
>>>   (glEnd))
>>>
>>> (define my-canvas%
>>>   (class* canvas% ()
>>>     (inherit with-gl-context swap-gl-buffers)
>>>     (define/override (on-paint)             (with-gl-context (λ()
>>> (example) (swap-gl-buffers))))
>>>     (define/override (on-size width height) (with-gl-context (λ()
>>> (resize width height) (on-paint))))
>>>     (super-instantiate () (style '(gl)))))
>>>
>>> (define win (new frame% [label "Racket Rosetta Code OpenGL example"]
>>>                  [min-width 200] [min-height 200]))
>>> (define gl  (new my-canvas% [parent win]))
>>>
>>> (new timer%
>>>      [interval (exact-floor milliseconds-per-frame)] ; in milliseconds
>>>      [notify-callback on-tick])
>>>
>>> (send win show #t)
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Racket Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> --
> --
> Jens Axel Søgaard
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to