[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Simple gl-canvas% prototype
Well folks,
I implemented a simple gl-canvas% class for MrEd.
Befor anyone gets excited, it is *very* simple.
It has four methods beyond what a normal canvas does:
gl-init:
glShadeModel(GL_SMOOTH);
// Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //
Black Background
glClearDepth(1.0f);
// Depth Buffer Setup
glEnable(GL_DEPTH_TEST);
// Enables Depth Testing
glDepthFunc(GL_LEQUAL);
// The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really
Nice Perspective Calculations
gl-swap-buffers --- swaps buffers for double buffering
gl-draw-scene:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear
Screen And Depth Buffer
glLoadIdentity();
// Reset The Current Modelview Matrix
glTranslatef(-1.5f,0.0f,-6.0f);
// Move Left 1.5 Units And Into The Screen 6.0
glBegin(GL_TRIANGLES);
// Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f);
// Top
glVertex3f(-1.0f,-1.0f, 0.0f);
// Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f);
// Bottom Right
glEnd();
// Finished Drawing The Triangle
glTranslatef(3.0f,0.0f,0.0f);
// Move Right 3 Units
glBegin(GL_QUADS);
// Draw A Quad
glVertex3f(-1.0f, 1.0f, 0.0f);
// Top Left
glVertex3f( 1.0f, 1.0f, 0.0f);
// Top Right
glVertex3f( 1.0f,-1.0f, 0.0f);
// Bottom Right
glVertex3f(-1.0f,-1.0f, 0.0f);
// Bottom Left
glEnd();
// Done Drawing The Quad
gl-resize:
glViewport(0,0,width,height); //
Reset The Current Viewport
glMatrixMode(GL_PROJECTION);
// Select The Projection Matrix
glLoadIdentity();
// Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
// Select The Modelview Matrix
glLoadIdentity();
// Reset The Modelview Matrix
The point of writing this was to test the feasibility of rendering to a MrEd
window. I can say now, yes it is
feasible. The new gl-canvas% works like a regular canvas% as far as geometry
management goes. So you can have
buttons, scrollbars and other widgets that coexist peacfully in the same
frame as a gl-canvas%
Here is an example test program:
(define test-canvas%
(class gl-canvas% (pf . args)
(inherit gl-init gl-swap-buffers gl-draw-scene gl-resize)
(sequence
(apply super-init (cons pf args))
(gl-init))
(rename [super-on-paint on-paint]
[super-on-size on-size]
[super-on-event on-event])
(override
[on-paint
(lambda ()
(gl-draw-scene)
(gl-swap-buffers)
(super-on-paint))]
[on-size
(lambda (w h)
(gl-resize w h)
(super-on-size w h))]
[on-char
(lambda (ch)
(display (send ch get-key-code)))]
[on-event
(lambda (evt)
(printf "~n~n~n-----mouse-----~a~a~a~a~a"
(format "~nenter: ~a" (send evt entering?))
(format "~nleave: ~a" (send evt leaving?))
(format "~nleft-down: ~a" (send evt get-left-down))
(format "~nright-down: ~a" (send evt get-right-down))
(format "~nmotion: ~a~n" (send evt moving?)))
(if (send evt moving?)
(printf "x: ~a y: ~a~n" (send evt get-x) (send evt get-y)))
(super-on-event evt))])))
(define my-frame (make-object frame% "My Frame" #f 300 300))
(define h-panel (make-object horizontal-panel% my-frame))
(define my-canvas (make-object test-canvas% h-panel '(border vscroll
hscroll)))
(send my-frame show #t)
(make-object button% "dummy button" my-frame (lambda x (void)))
(make-object button% "dummy button" h-panel (lambda x (void)))
When exectuted, it puts a white triangle next to a white square on a black
background.
When you resize the window, the OpenGL scene is resized as expected. The
buttons, scrollbars
and border don't seem to interfere with the gl-canvas%. Events still come in
as expected.
I'm on the verge of having a lot of fun with this.
Cheers!