[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!