Red et OpenGL
ldci16-Dec-2013/13:55:36+1:00
Bonjour à tous
Voici mon cadeau de Noël avant l'heure!
J'ai décidé de donner des ailes à Red
Vous trouverez ici https://www.wuala.com/fjouen/Code/GLFW/ le portage de la bibliothèque GLFW (http://www.glfw.org/)
Ceci permet de donner à Red une gestion des fenêtres graphiques, des événements clavier, souris, joystick, du son, du multi-threading et l'accès à OpenGL
Cette version est pour Mac OSX 10.9 mais elle est adaptable sans problème.
Je vais mettre des exemples dans les jours qui viennent, mais pour commencer une démo très simple:


<code>
Red/System [
   Title:       "GLFW Binding: test1"
   Author:      "François Jouen"
   Rights:      "Copyright (c) 2013 François Jouen. All rights reserved."
   License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


#include %../glfw.reds

print newline

Print ["Red is talking to GLFW and OpenGL" newline]

t: glfwInit
if t = 1 [print "GLFW Library successfully initialized" newline]
print newline
print ["Time elapsed since GLFW Library initialization : " glfwGetTime newline]
mj: declare pointer! [integer!] ; or declare int-ptr!
mn: declare pointer! [integer!]
re: declare pointer! [integer!]
glfwGetVersion mj mn re
print ["Version: "mj/value "." mn/value "." re/value newline]
print [glfwGetVersionString newline]
monitors: declare pointer! [integer!]
glfwGetMonitors monitors
print ["Number of monitors: " monitors/value newline]
monitor: glfwGetPrimaryMonitor
xpos: declare pointer! [integer!]
ypos: declare pointer! [integer!]
width: declare pointer! [integer!]
height: declare pointer! [integer!]
count: declare pointer! [integer!]
glfwGetMonitorPos monitor xpos ypos
glfwGetMonitorPhysicalSize monitor width height
print ["Default window position: " xpos/value " " ypos/value newline]
print ["Default window size: "width/value " " height/value newline]
print ["Main monitor name: " glfwGetMonitorName monitor newline]
mode: glfwGetVideoModes monitor count
print [count/value " possible modes" newline]
print ["First Mode : " mode/width " " mode/height " " mode/redBits " " mode/greenBits " " mode/blueBits " " mode/refreshRate newline]
currentMode: glfwGetVideoMode monitor
print ["Current Mode: " currentMode/width " " currentMode/height " " currentMode/redBits " " currentMode/greenBits " " currentMode/blueBits " " currentMode/refreshRate newline]
gamma: glfwGetGammaRamp monitor
print ["Current Gamma: " gamma/red " " gamma/green " " gamma/blue " "gamma/size newline]
print ["Time elapsed since GLFW Library initialization : " glfwGetTime newline]
glfwTerminate
</code>

et le résultat dans la console

Red is talking to GLFW and OpenGL
GLFW Library successfully initialized
Time elapsed since GLFW Library initialization : 0.025423469
Version: 3.0.3
3.0.3 Cocoa NSGL chdir menubar dynamic
Number of monitors: 2
Default window position: 0 0
Default window size: 596 335
Main monitor name: iMac
24 possible modes
First Mode : 640 480 5 5 5 0
Current Mode: 2560 1440 8 8 8 0
Current Gamma: 00851600 00853600 00853800 256
Time elapsed since GLFW Library initialization : 0.026012882

Allez bon code !
ldci16-Dec-2013/14:19:16+1:00
et voila comment créer et afficher une fenêtre graphique afin de gérer les événements

<code>

Red/System [
   Title:      "GLFW Binding: test2"
   Author:      "François Jouen"
   Rights:      "Copyright (c) 2013 François Jouen. All rights reserved."
   License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


#include %../glfw.reds

glfwInit
;Create a windowed mode window and its OpenGL context
window: glfwCreateWindow 640 480 "Hello World" NULL NULL

;Make the window's context current
glfwMakeContextCurrent window

;Loop until the user closes the window
while [(glfwWindowShouldClose window) = 0] [
;Render here
;Swap front and back buffers ;
glfwSwapBuffers window
;Poll for and process events
glfwPollEvents

]
glfwTerminate

</code>

et le résultat graphique ici : http://www.wuala.com/fjouen/Code/GLFW/images/
ldci16-Dec-2013/14:21:39+1:00
Désolé c'est mieux comme ça
Red/System [
	Title:		"GLFW Binding: test2"
	Author:		"François Jouen"
	Rights:		"Copyright (c) 2013 François Jouen. All rights reserved."
	License:        "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


#include %../glfw.reds

    glfwInit
    ;Create a windowed mode window and its OpenGL context
    window: glfwCreateWindow 640 480 "Hello World" NULL NULL
    
    ;Make the window's context current
    glfwMakeContextCurrent window
    
    ;Loop until the user closes the window
    while [(glfwWindowShouldClose window) = 0] [
        ;Render here 
        ;Swap front and back buffers ;
        glfwSwapBuffers window
        ;Poll for and process events 
        glfwPollEvents
        
    ]
    glfwTerminate
GreG16-Dec-2013/15:50:14+1:00
Merci, super cadeau
ldci18-Dec-2013/10:26+1:00
Merci Greg,
Bonne nouvelle, glwf marche parfaitement, mais comme cette lib s'interface avec OpenGL, j'ai commencé le portage d'OPenGL pour Red/System ...
Ca va être long, car il y a un paquet de fonction, mais ca marche déjà.

 glViewport: "glViewport" [
            x           [GLint]
            y           [GLint]
            width       [GLsizei]
            height      [GLsizei]
        ]


Affaire à suivre
ldci18-Dec-2013/19:58:07+1:00
Bien
Une petite démo: Red sait parler OpenGL maintenant



Red/System [
	Title:		"GLFW Binding: test3"
	Author:		"François Jouen"
	Rights:		"Copyright (c) 2013 François Jouen. All rights reserved."
	License:        "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


    #include %../glfw.reds
    glfwInit
    window: glfwCreateWindow 800 600 "A Simple OpenGL Triangle with Red" NULL NULL
    glfwMakeContextCurrent window
    
    while [(glfwWindowShouldClose window) = GL_FALSE] [   
        glClearColor 0.0 0.0 0.0 0.0
        glClear GL_COLOR_BUFFER_BIT    
        glBegin GL_TRIANGLES 
        glColor3ub 255 0 0    glVertex2d -0.75 -0.75
        glColor3ub 0 255 0    glVertex2d 0.0 0.75 
        glColor3ub 0 0 255    glVertex2d 0.75 -0.75
        glEnd
        glFlush
        glfwSwapBuffers window
        glfwPollEvents  
    ]

    glfwDestroyWindow window    
    glfwTerminate



et bien sûr l'image qui correspond

http://www.wuala.com/fjouen/Code/GLFW/images/simple1.jpg/
ldci19-Dec-2013/10:14:29+1:00
Bonjour à tous
Red peut utiliser les fonctions d'animation d'OpenGL
Un exemple aussi de la façon d'utiliser des pointeurs sur fonction avec Red/S (le callback)

Red/System [
	Title:		"GLFW Binding: Animated triangle"
	Author:		"François Jouen"
	Rights:		"Copyright (c) 2013 François Jouen. All rights reserved."
	License:        "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


    #include %../glfw.reds
    #include %../user.reds
    
    ratio: 0.0
    width: 0
    height: 0
    angle: 0.0
    
    &width: :width; pointer! 
    &height: :height ;pointer!
    
    error_callback: func [[cdecl] error [integer!] description [c-string!]] [
        print [ description " " stderr]
    ]
    
    key_callback: func [
        [cdecl]
        window [GLFWwindow]
        key [integer!]
        scancode [integer!]
        action [integer!]
        mods [integer!]] [
        if (key = GLFW_KEY_ESCAPE) and (action = GLFW_PRESS) [glfwSetWindowShouldClose window GL_TRUE ]
    ]
    
    
    
    if glfwInit = 0 [glfwTerminate] ; exit
    
    window: glfwCreateWindow 640 480 "Animated OpenGL Triangle with Red [ESC to Quit]" NULL NULL
    if window = null [glfwTerminate]
    glfwMakeContextCurrent window
    glfwSetErrorCallback :error_callback
    glfwSetKeyCallback window :key_callback
    
    while [(glfwWindowShouldClose window) = GL_FALSE] [
        glfwGetFramebufferSize window &width &height
        ratio:  (int-to-float width) /  (int-to-float height)
        glViewport 0 0 width height
        glClearColor 0.0 0.0 0.0 0.0
        glClear GL_COLOR_BUFFER_BIT
        glMatrixMode GL_PROJECTION
        glLoadIdentity
        glOrtho 0.0 - ratio ratio -1.0 1.0 1.0 -1.0
        glMatrixMode GL_MODELVIEW
        glLoadIdentity
        
        angle: glfwGetTime * 50.00
        glRotatef as float32! angle 0.0 0.0 1.0
        
        glBegin GL_TRIANGLES
            glColor3f 1.0 0.0 0.0    glVertex3f -0.6 -0.4 0.0  ;first point of triangle is red
            glColor3f 0.0 1.0 0.0    glVertex3f 0.6 -0.4 0.0   ;second point of triangle is green
            glColor3f 0.0 0.0 1.0    glVertex3f 0.0 0.6 0.0    ;third point of triangle is blue
        glEnd
        
        
        glfwSwapBuffers window
        glfwPollEvents  
    
    ]
    glfwDestroyWindow window    
    glfwTerminate
    
  



ldci19-Dec-2013/10:15:23+1:00
Bonjour à tous
Red peut utiliser les fonctions d'animation d'OpenGL
Un exemple aussi de la façon d'utiliser des pointeurs sur fonction avec Red/S (le callback)

Red/System [
	Title:		"GLFW Binding: Animated triangle"
	Author:		"François Jouen"
	Rights:		"Copyright (c) 2013 François Jouen. All rights reserved."
	License:        "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]


    #include %../glfw.reds
    #include %../user.reds
    
    ratio: 0.0
    width: 0
    height: 0
    angle: 0.0
    
    &width: :width; pointer! 
    &height: :height ;pointer!
    
    error_callback: func [[cdecl] error [integer!] description [c-string!]] [
        print [ description " " stderr]
    ]
    
    key_callback: func [
        [cdecl]
        window [GLFWwindow]
        key [integer!]
        scancode [integer!]
        action [integer!]
        mods [integer!]] [
        if (key = GLFW_KEY_ESCAPE) and (action = GLFW_PRESS) [glfwSetWindowShouldClose window GL_TRUE ]
    ]
    
    
    
    if glfwInit = 0 [glfwTerminate] ; exit
    
    window: glfwCreateWindow 640 480 "Animated OpenGL Triangle with Red [ESC to Quit]" NULL NULL
    if window = null [glfwTerminate]
    glfwMakeContextCurrent window
    glfwSetErrorCallback :error_callback
    glfwSetKeyCallback window :key_callback
    
    while [(glfwWindowShouldClose window) = GL_FALSE] [
        glfwGetFramebufferSize window &width &height
        ratio:  (int-to-float width) /  (int-to-float height)
        glViewport 0 0 width height
        glClearColor 0.0 0.0 0.0 0.0
        glClear GL_COLOR_BUFFER_BIT
        glMatrixMode GL_PROJECTION
        glLoadIdentity
        glOrtho 0.0 - ratio ratio -1.0 1.0 1.0 -1.0
        glMatrixMode GL_MODELVIEW
        glLoadIdentity
        
        angle: glfwGetTime * 50.00
        glRotatef as float32! angle 0.0 0.0 1.0
        
        glBegin GL_TRIANGLES
            glColor3f 1.0 0.0 0.0    glVertex3f -0.6 -0.4 0.0  ;first point of triangle is red
            glColor3f 0.0 1.0 0.0    glVertex3f 0.6 -0.4 0.0   ;second point of triangle is green
            glColor3f 0.0 0.0 1.0    glVertex3f 0.0 0.6 0.0    ;third point of triangle is blue
        glEnd
        
        
        glfwSwapBuffers window
        glfwPollEvents  
    
    ]
    glfwDestroyWindow window    
    glfwTerminate
    
  



ldci20-Dec-2013/17:26:13+1:00
Nenad est vraiment le meilleur !
Sur la base de la doc de Jocko et Pierre, voici comment intégrer aisément un portage de librairies externes (écrites en Red/System) à l'intérieur d'un code Red.
Bon j'attends avec impatience le support des flottants avec Red
Red [
	Title:		"GLFW Binding: Triangle"
	Author:		"Francois Jouen"
	Rights:		"Copyright (c) 2013 Francois Jouen. All rights reserved."
	License:        "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt"
]

; how to use Red/System code inside Red #system [library] to make import
; then func is replace by routine because we are using Red/S code inside dthe function
; Unfortunately Red does not support yet floating values ... 

#system [
	#include %../glfw.reds ; this lib includes opgl.reds	
	
	; for error callback code pointer
	error_callback: func [[cdecl] error [integer!] description [c-string!]] [
	print [ description " " stderr]
	]
]



initgl: routine [return: [integer!]] [
	if glfwInit = 0 [glfwTerminate]
	window: glfwCreateWindow 800 600 "A Simple OpenGL Triangle with Red" NULL NULL
	glfwMakeContextCurrent window
	glfwSetErrorCallback :error_callback
	return 1
]

closegl: routine [] [
	glfwDestroyWindow window    
	glfwTerminate
]

render: routine [ /local rep [integer!]] [
	rep: 0
	until [
		;glClearColor 0.0 0.0 0.0 0.0
		glClear GL_COLOR_BUFFER_BIT
		glBegin GL_TRIANGLES
			glColor3ub 255 0 0    ;glVertex2d -0.75 -0.75
			glColor3ub 0 255 0    ;glVertex2d 0.0 0.75 
			glColor3ub 0 0 255    ;glVertex2d 0.75 -0.75
		glEnd
		glFlush
		glfwSwapBuffers window
		glfwPollEvents  
		rep: glfwWindowShouldClose window
	rep = 1
	]
]


;Main program
initgl
render 
closegl
quit



Pour le fun, ce code en Red met
Compiling to native code...
...compilation time : 9973 ms
...linking time : 119 ms
...output file size : 208896 bytes

et en Red/System
Compiling to native code...
...compilation time : 1563 ms
...linking time : 10 ms
...output file size : 20480 bytes

Bon coding
PierreCh28-Dec-2013/0:07:35+1:00
Impressionnant. Bravo! Ça me rappelle vaguement une discussion qui avait eu lieu par ici, et où, de mémoire, il était question d'implémenter une interface graphique en openGL.
ldci28-Dec-2013/13:39:24+1:00
Quand je vous dis que Red est génial!
Voici comment implémenter des listes contenant des types différents avec red/s

La base (en c)


typedef struct
{
    int attrib;
    const char* ext;
    const char* name;
} AttribGL;


static AttribGL gl_attribs[] =
{
    { GL_RED_BITS, NULL, "red bits" },
    { GL_GREEN_BITS, NULL, "green bits" },
    { GL_BLUE_BITS, NULL, "blue bits" },
    { GL_ALPHA_BITS, NULL, "alpha bits" },
    { GL_DEPTH_BITS, NULL, "depth bits" },
    { GL_STENCIL_BITS, NULL, "stencil bits" },
    { GL_STEREO, NULL, "stereo" },
    { GL_SAMPLES_ARB, "GL_ARB_multisample", "FSAA samples" },
    { 0, NULL, NULL }
};



comment ce gérer avec Red/S
1°) créer un alias de structure

AttribGL!: alias struct! [
    attrib      [integer!]
    ext         [c-string!]
    name        [c-string!] 
]



2°) Créer une liste des alias via une structure


gl_attribs: declare struct! [
    gl1     [AttribGL!]
    gl2     [AttribGL!]
    gl3     [AttribGL!]
    gl4     [AttribGL!]
    gl5     [AttribGL!]
    gl6     [AttribGL!]
    gl7     [AttribGL!]
    gl8     [AttribGL!]
    gl9     [AttribGL!]
]


Bien maintenant comment utiliser tout ça


; on déclare les éléments de la liste et on reserve l'espace mémoire
gl_attribs/gl1: declare AttribGL!
gl_attribs/gl2: declare AttribGL!
gl_attribs/gl3: declare AttribGL!
gl_attribs/gl4: declare AttribGL!
gl_attribs/gl5: declare AttribGL!
gl_attribs/gl6: declare AttribGL!
gl_attribs/gl7: declare AttribGL!
gl_attribs/gl8: declare AttribGL!
gl_attribs/gl9: declare AttribGL!

; on affecte les valeurs aux éléments de la liste

gl_attribs/gl1/attrib: GL_RED_BITS
gl_attribs/gl1/ext: null
gl_attribs/gl1/name: "red bits"

gl_attribs/gl2/attrib: GL_GREEN_BITS
gl_attribs/gl2/ext: null
gl_attribs/gl2/name: "green bits"

gl_attribs/gl3/attrib: GL_BLUE_BITS
gl_attribs/gl3/ext: null
gl_attribs/gl3/name: "blue bits"

gl_attribs/gl4/attrib: GL_ALPHA_BITS
gl_attribs/gl4/ext: null
gl_attribs/gl4/name: "alpha bits"

gl_attribs/gl5/attrib: GL_DEPTH_BITS
gl_attribs/gl5/ext: null
gl_attribs/gl5/name: "depth bits"


gl_attribs/gl6/attrib: GL_STENCIL_BITS
gl_attribs/gl6/ext: null
gl_attribs/gl6/name: "stencil bits"

gl_attribs/gl7/attrib: GL_STEREO
gl_attribs/gl7/ext: null
gl_attribs/gl7/name: "stereo"

gl_attribs/gl8/attrib: 000080A9h;GL_SAMPLES_ARB
gl_attribs/gl8/ext: null
gl_attribs/gl8/name: "GL_ARB_multisample FSAA samples"

gl_attribs/gl9/attrib: 0
gl_attribs/gl9/ext: null
gl_attribs/gl9/name: " "

; pour accéder aux éléments  de la liste il nous faut un simple pointeur sur le premier élément de la liste

p: as int-ptr!  gl_attribs/gl1

; ensuite l'arithmétique des pointeurs de Nénad fait le reste :)

c: 1
until [
    print [ as integer! p ": " p/1 " "  p/2 " " as c-string! p/3 newline]

    p: p + 3
    c: c + 1
c = 10   
]



et voila le résultat

adresse de la structure: 12376
adresse des alias: 12440 12452 12464 12476 12488 12500 12512 12524
12440: 3410 0 red bits
12452: 3411 0 green bits
12464: 3412 0 blue bits
12476: 3413 0 alpha bits
12488: 3414 0 depth bits
12500: 3415 0 stencil bits
12512: 3123 0 stereo
12524: 32937 0 GL_ARB_multisample FSAA samples
12536: 0 0
ldci28-Dec-2013/13:45:35+1:00
Quand je vous dis que Red est génial!
Voici comment implémenter des listes contenant des types différents avec red/s

La base (en c)


typedef struct
{
    int attrib;
    const char* ext;
    const char* name;
} AttribGL;


static AttribGL gl_attribs[] =
{
    { GL_RED_BITS, NULL, "red bits" },
    { GL_GREEN_BITS, NULL, "green bits" },
    { GL_BLUE_BITS, NULL, "blue bits" },
    { GL_ALPHA_BITS, NULL, "alpha bits" },
    { GL_DEPTH_BITS, NULL, "depth bits" },
    { GL_STENCIL_BITS, NULL, "stencil bits" },
    { GL_STEREO, NULL, "stereo" },
    { GL_SAMPLES_ARB, "GL_ARB_multisample", "FSAA samples" },
    { 0, NULL, NULL }
};



comment ce gérer avec Red/S
1°) créer un alias de structure

AttribGL!: alias struct! [
    attrib      [integer!]
    ext         [c-string!]
    name        [c-string!] 
]



2°) Créer une liste des alias via une structure


gl_attribs: declare struct! [
    gl1     [AttribGL!]
    gl2     [AttribGL!]
    gl3     [AttribGL!]
    gl4     [AttribGL!]
    gl5     [AttribGL!]
    gl6     [AttribGL!]
    gl7     [AttribGL!]
    gl8     [AttribGL!]
    gl9     [AttribGL!]
]


Bien maintenant comment utiliser tout ça


; on déclare les éléments de la liste et on reserve l'espace mémoire
gl_attribs/gl1: declare AttribGL!
gl_attribs/gl2: declare AttribGL!
gl_attribs/gl3: declare AttribGL!
gl_attribs/gl4: declare AttribGL!
gl_attribs/gl5: declare AttribGL!
gl_attribs/gl6: declare AttribGL!
gl_attribs/gl7: declare AttribGL!
gl_attribs/gl8: declare AttribGL!
gl_attribs/gl9: declare AttribGL!

; on affecte les valeurs aux éléments de la liste

gl_attribs/gl1/attrib: GL_RED_BITS
gl_attribs/gl1/ext: null
gl_attribs/gl1/name: "red bits"

gl_attribs/gl2/attrib: GL_GREEN_BITS
gl_attribs/gl2/ext: null
gl_attribs/gl2/name: "green bits"

gl_attribs/gl3/attrib: GL_BLUE_BITS
gl_attribs/gl3/ext: null
gl_attribs/gl3/name: "blue bits"

gl_attribs/gl4/attrib: GL_ALPHA_BITS
gl_attribs/gl4/ext: null
gl_attribs/gl4/name: "alpha bits"

gl_attribs/gl5/attrib: GL_DEPTH_BITS
gl_attribs/gl5/ext: null
gl_attribs/gl5/name: "depth bits"


gl_attribs/gl6/attrib: GL_STENCIL_BITS
gl_attribs/gl6/ext: null
gl_attribs/gl6/name: "stencil bits"

gl_attribs/gl7/attrib: GL_STEREO
gl_attribs/gl7/ext: null
gl_attribs/gl7/name: "stereo"

gl_attribs/gl8/attrib: 000080A9h;GL_SAMPLES_ARB
gl_attribs/gl8/ext: null
gl_attribs/gl8/name: "GL_ARB_multisample FSAA samples"

gl_attribs/gl9/attrib: 0
gl_attribs/gl9/ext: null
gl_attribs/gl9/name: " "

; pour accéder aux éléments  de la liste il nous faut un simple pointeur sur le premier élément de la liste

p: as int-ptr!  gl_attribs/gl1

; ensuite l'arithmétique des pointeurs de Nénad fait le reste :)

c: 1
until [
    print [ as integer! p ": " p/1 " "  p/2 " " as c-string! p/3 newline]
    ; on incrémente le pointeur par le nombre d'éléments de l'alias (ici 3)
    p: p + 3
    c: c + 1
c = 10   
]



et voila le résultat

adresse de la structure: 12376
adresse des alias: 12440 12452 12464 12476 12488 12500 12512 12524
12440: 3410 0 red bits
12452: 3411 0 green bits
12464: 3412 0 blue bits
12476: 3413 0 alpha bits
12488: 3414 0 depth bits
12500: 3415 0 stencil bits
12512: 3123 0 stereo
12524: 32937 0 GL_ARB_multisample FSAA samples
12536: 0 0

Pas mal, non? On a les moyens avec les pointeurs de se promener dans la liste et de faire tout ce que l'on veut (lire, écrire, modifier ...) . Le principe est le même pour un array ou une liste d'objets.
Great Job DocKimbel
ldci30-Dec-2013/20:50:24+1:00
Salut à tous,
Le code GLFW est maintenant disponible sur github
https://github.com/ldci/gflw-red
Bonne Année à tous
ldci1-Jan-2014/19:50:41+1:00
Bonjour à tous
Le code GLFW sur github est maintenant compatible avec le OpenGL Utility Toolkit.
Amicalement

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2