85
|
1 module doodle.gtk.opengl_canvas;
|
|
2
|
|
3 public {
|
|
4 import doodle.dia.icanvas;
|
|
5 import doodle.gtk.events;
|
|
6 }
|
|
7
|
|
8 private {
|
|
9 import doodle.core.logging;
|
|
10 import doodle.tk.screen_model;
|
|
11 import doodle.dia.layer_stack;
|
|
12 import doodle.gtk.cairo_renderer;
|
|
13
|
|
14 import cairo.Surface;
|
|
15 import cairo.Context;
|
|
16
|
|
17 import gtk.Widget;
|
|
18 import gtk.Toolbar;
|
|
19 import gtk.Table;
|
|
20 import gtk.HRuler;
|
|
21 import gtk.VRuler;
|
|
22 import gtk.Range;
|
|
23 import gtk.HScrollbar;
|
|
24 import gtk.VScrollbar;
|
|
25 import gtk.DrawingArea;
|
|
26 import gtk.Adjustment;
|
|
27
|
|
28 import gdk.Drawable;
|
|
29
|
|
30 import gtkc.gtk;
|
|
31 import gtkc.gtktypes;
|
|
32 //import gtkc.gdktypes;
|
|
33
|
|
34 import std.math;
|
|
35 import std.stdio;
|
|
36 }
|
|
37
|
86
|
38 private {
|
|
39 import gtk.DrawingArea;
|
|
40 import glgtk.GLCapability;
|
|
41 import glgdk.GLDrawable;
|
|
42 import glgdk.GLConfig;
|
|
43 import glgdk.GLContext;
|
|
44 import gtkglc.glgdktypes;
|
|
45
|
|
46 import gtkglc.gl;
|
|
47 import gtkglc.glu;
|
|
48
|
|
49 import gdk.Event;
|
|
50
|
|
51 import gtk.Widget;
|
|
52
|
|
53 import gtk.Main;
|
|
54 import gtk.MainWindow;
|
|
55 }
|
|
56
|
|
57
|
85
|
58 final class OpenGLCanvas : Table, private IViewport {
|
|
59 this(in Layer[] layers, IEventHandler eventHandler, IGrid grid, in double pixelsPerMillimetre) {
|
|
60 super(3, 3, 0);
|
|
61
|
|
62 _damageScreen = Rectangle.DEFAULT;
|
|
63
|
|
64 _eventHandler = eventHandler;
|
|
65 _grid = grid;
|
|
66 _pixelsPerMillimetre = pixelsPerMillimetre;
|
|
67
|
|
68 _layerStack = new LayerStack(layers);
|
|
69
|
|
70 // Create our child widgets and register callbacks
|
|
71
|
|
72 _hRuler = new HRuler;
|
|
73 attach(_hRuler,
|
|
74 1, 2,
|
|
75 0, 1,
|
|
76 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.SHRINK,
|
|
77 0, 0);
|
|
78 _hRuler.setMetric(MetricType.PIXELS);
|
|
79
|
|
80 _vRuler = new VRuler;
|
|
81 attach(_vRuler,
|
|
82 0, 1,
|
|
83 1, 2,
|
|
84 AttachOptions.SHRINK, AttachOptions.FILL | AttachOptions.EXPAND,
|
|
85 0, 0);
|
|
86 _vRuler.setMetric(MetricType.PIXELS);
|
|
87
|
|
88 _drawingArea = new GLDrawingArea;
|
|
89 _drawingArea.addOnRealize(&onRealize);
|
|
90 _drawingArea.addOnConfigure(&onConfigure);
|
|
91 _drawingArea.addOnExpose(&onExpose);
|
|
92 _drawingArea.addOnButtonPress(&onButtonPress);
|
|
93 _drawingArea.addOnButtonRelease(&onButtonRelease);
|
|
94 _drawingArea.addOnKeyPress(&onKeyPressEvent);
|
|
95 _drawingArea.addOnKeyRelease(&onKeyReleaseEvent);
|
|
96 _drawingArea.addOnMotionNotify(&onMotionNotify);
|
|
97 _drawingArea.addOnScroll(&onScroll);
|
|
98 _drawingArea.addOnEnterNotify(&onEnterNotify);
|
|
99 _drawingArea.addOnLeaveNotify(&onLeaveNotify);
|
|
100
|
|
101 _drawingArea.addOnFocusIn(&onFocusIn);
|
|
102 _drawingArea.addOnFocusOut(&onFocusOut);
|
|
103 _drawingArea.addOnMoveFocus(&onMoveFocus);
|
|
104 _drawingArea.addOnGrabBroken(&onGrabBroken);
|
|
105 _drawingArea.addOnGrabFocus(&onGrabFocus);
|
|
106 _drawingArea.addOnGrabNotify(&onGrabNotify);
|
|
107 // addOnPopupMenu
|
|
108 // addOnQueryTooltip
|
|
109 // addOnSelection*
|
|
110 _drawingArea.setEvents(EventMask.EXPOSURE_MASK |
|
|
111 EventMask.POINTER_MOTION_MASK |
|
|
112 EventMask.POINTER_MOTION_HINT_MASK |
|
|
113 EventMask.BUTTON_MOTION_MASK |
|
|
114 EventMask.BUTTON_PRESS_MASK |
|
|
115 EventMask.BUTTON_RELEASE_MASK |
|
|
116 EventMask.KEY_PRESS_MASK |
|
|
117 EventMask.KEY_RELEASE_MASK |
|
|
118 EventMask.ENTER_NOTIFY_MASK |
|
|
119 EventMask.LEAVE_NOTIFY_MASK |
|
|
120 EventMask.FOCUS_CHANGE_MASK |
|
|
121 EventMask.SCROLL_MASK);
|
|
122
|
|
123 _drawingArea.setCanFocus(true);
|
|
124
|
|
125 attach(_drawingArea,
|
|
126 1, 2,
|
|
127 1, 2,
|
|
128 AttachOptions.FILL | AttachOptions.EXPAND, AttachOptions.FILL | AttachOptions.EXPAND,
|
|
129 0, 0);
|
|
130
|
|
131 // value, lower, upper, step-inc, page-inc, page-size
|
|
132 // Give the adjustments dummy values until we receive a configure
|
|
133 _hAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
|
|
134 _hAdjustment.addOnValueChanged(&onAdjustmentValueChanged);
|
|
135 _hScrollbar = new HScrollbar(_hAdjustment);
|
|
136 _hScrollbar.setInverted(false);
|
|
137 attach(_hScrollbar,
|
|
138 1, 2,
|
|
139 2, 3,
|
|
140 AttachOptions.FILL | AttachOptions.EXPAND,
|
|
141 AttachOptions.SHRINK,
|
|
142 0, 0);
|
|
143
|
|
144 _vAdjustment = new Adjustment(0.0, 0.0, 1.0, 0.2, 0.5, 0.5);
|
|
145 _vAdjustment.addOnValueChanged(&onAdjustmentValueChanged);
|
|
146 _vScrollbar = new VScrollbar(_vAdjustment);
|
|
147 _vScrollbar.setInverted(true);
|
|
148 attach(_vScrollbar,
|
|
149 2, 3,
|
|
150 1, 2,
|
|
151 AttachOptions.SHRINK,
|
|
152 AttachOptions.FILL | AttachOptions.EXPAND,
|
|
153 0, 0);
|
|
154
|
|
155 _cursors = [
|
|
156 Cursor.DEFAULT : CursorType.ARROW,
|
|
157 Cursor.HAND : CursorType.HAND1,
|
|
158 Cursor.CROSSHAIR : CursorType.CROSSHAIR,
|
|
159 Cursor.PENCIL : CursorType.PENCIL
|
86
|
160 ];
|
85
|
161 }
|
|
162
|
|
163 protected { // XXX the compiler complains about unimplemented methods if this is private
|
|
164
|
|
165 // IViewport overrides:
|
|
166
|
|
167 void zoomRelative(in Point screenDatum, in double factor) {
|
|
168 _screenModel.zoomRelative(factor, screenDatum);
|
|
169 consolidateBounds;
|
|
170 updateAdjustments;
|
|
171 updateRulers;
|
|
172 _grid.zoomChanged(_screenModel.zoom);
|
|
173 queueDraw;
|
|
174 }
|
|
175
|
|
176 void panRelative(in Vector screenDisplacement) {
|
|
177 _screenModel.panRelativeScreen(screenDisplacement);
|
|
178 consolidateBounds;
|
|
179 updateAdjustments;
|
|
180 updateRulers;
|
|
181 queueDraw;
|
|
182 }
|
|
183
|
|
184 void setCursor(in Cursor cursor) {
|
|
185 _drawingArea.setCursor(new gdk.Cursor.Cursor(_cursors[cursor]));
|
|
186 }
|
|
187
|
|
188 void damageModel(in Rectangle area) {
|
|
189 _damageScreen = _damageScreen | _screenModel.modelToScreen(area);
|
|
190 }
|
|
191
|
|
192 void damageScreen(in Rectangle area) {
|
|
193 _damageScreen = _damageScreen | area;
|
|
194 }
|
|
195 }
|
|
196
|
|
197 private {
|
|
198
|
|
199 void initialiseBounds(in Rectangle viewBoundsScreen) {
|
|
200 Rectangle layerBounds = _layerStack.bounds;
|
|
201 Rectangle paddedLayerBounds = growCentre(layerBounds, 2 * layerBounds.size);
|
|
202 _screenModel = new ScreenModel(0.25 * _pixelsPerMillimetre, paddedLayerBounds, viewBoundsScreen);
|
|
203 _grid.zoomChanged(_screenModel.zoom);
|
|
204
|
|
205 updateAdjustments;
|
|
206 updateRulers;
|
|
207 }
|
|
208
|
|
209 void consolidateBounds() {
|
|
210 Rectangle layerBounds = _layerStack.bounds;
|
|
211 Rectangle paddedLayerBounds = growCentre(layerBounds, 2 * layerBounds.size);
|
|
212 _screenModel.consolidateCanvasBounds(paddedLayerBounds);
|
|
213
|
|
214 updateAdjustments;
|
|
215 updateRulers;
|
|
216 }
|
|
217
|
|
218 bool onConfigure(GdkEventConfigure * event, Widget widget) {
|
|
219 assert(widget is _drawingArea);
|
|
220 assert(event);
|
|
221
|
|
222 trace("onConfigure %sx%s", event.width, event.height);
|
|
223
|
|
224 Rectangle viewBoundsScreen = Rectangle(Point(0.0, 0.0), Vector(cast(double)event.width, cast(double)event.height));
|
|
225 if (_screenModel is null) { initialiseBounds(viewBoundsScreen); }
|
|
226 else { consolidateBounds; }
|
|
227
|
|
228 return true;
|
|
229 }
|
|
230
|
|
231 bool onExpose(GdkEventExpose * event, Widget widget) {
|
|
232 assert(widget is _drawingArea);
|
|
233 assert(event);
|
|
234
|
|
235 trace("onExpose %sx%s", event.area.width, event.area.height);
|
|
236
|
|
237 /+
|
86
|
238 Drawable dr = _drawingArea.getWindow;
|
85
|
239
|
|
240 int width, height;
|
|
241 dr.getSize(width, height);
|
|
242 //trace("Got expose %dx%d\n", width, height);
|
|
243
|
|
244 scope modelCr = new Context(dr);
|
|
245 scope screenCr = new Context(dr);
|
|
246
|
|
247 Rectangle screenDamage =
|
|
248 event is null ? _screenModel.viewBoundsScreen :
|
|
249 Rectangle(_screenModel.viewBoundsScreen.position + Vector(cast(double)event.area.x, _screenModel.viewBoundsScreen.h - cast(double)(event.area.y + event.area.height)),
|
|
250 Vector(cast(double)event.area.width, cast(double)event.area.height));
|
|
251
|
|
252 Rectangle modelDamage = _screenModel.screenToModel(screenDamage);
|
|
253
|
|
254 modelCr.save; screenCr.save; {
|
|
255 {
|
|
256 // Setup model context and clip
|
|
257 modelCr.translate(0.0, _screenModel.viewBoundsScreen.h);
|
|
258 modelCr.scale(_screenModel.zoom, -_screenModel.zoom);
|
|
259
|
|
260 immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
|
|
261 modelCr.translate(-viewLeftBottom.x, -viewLeftBottom.y);
|
|
262
|
|
263 modelCr.rectangle(modelDamage.x0, modelDamage.y0, modelDamage.w, modelDamage.h);
|
|
264 modelCr.clip;
|
|
265 }
|
|
266
|
|
267 {
|
|
268 // Setup screen context and clip
|
|
269 screenCr.translate(0.0, _screenModel.viewBoundsScreen.h);
|
|
270 screenCr.scale(1.0, -1.0);
|
|
271
|
|
272 screenCr.rectangle(screenDamage.x0, screenDamage.y0, screenDamage.w, screenDamage.h);
|
|
273 screenCr.clip;
|
|
274 }
|
|
275
|
|
276 screenCr.save; {
|
|
277 // Fill the background with light grey
|
|
278 screenCr.setSourceRgba(0.9, 0.9, 0.9, 1.0);
|
|
279 screenCr.rectangle(screenDamage.x0, screenDamage.y0, screenDamage.w, screenDamage.h);
|
|
280 screenCr.fill;
|
|
281 } screenCr.restore;
|
|
282
|
|
283 _layerStack.draw(screenDamage, new CairoRenderer(screenCr),
|
|
284 modelDamage, new CairoRenderer(modelCr));
|
|
285 } screenCr.restore; modelCr.restore;
|
|
286
|
|
287 return true;
|
|
288 +/
|
|
289
|
86
|
290 return false;
|
85
|
291 }
|
|
292
|
|
293 bool onButtonPress(GdkEventButton * event, Widget widget) {
|
|
294 assert(widget is _drawingArea);
|
|
295 _eventHandler.handleButtonPress(this, makeButtonEvent(event, _screenModel));
|
|
296 fixDamage;
|
|
297 return true;
|
|
298 }
|
|
299
|
|
300 bool onButtonRelease(GdkEventButton * event, Widget widget) {
|
|
301 assert(widget is _drawingArea);
|
|
302 _eventHandler.handleButtonRelease(this, makeButtonEvent(event, _screenModel));
|
|
303 fixDamage;
|
|
304 return true;
|
|
305 }
|
|
306
|
|
307 bool onKeyPressEvent(GdkEventKey * event, Widget widget) {
|
|
308 assert(widget is _drawingArea);
|
|
309 _eventHandler.handleKeyPress(this, makeKeyEvent(event, _screenModel));
|
|
310 fixDamage;
|
|
311 return true;
|
|
312 }
|
|
313
|
|
314 bool onKeyReleaseEvent(GdkEventKey * event, Widget widget) {
|
|
315 assert(widget is _drawingArea);
|
|
316 _eventHandler.handleKeyRelease(this, makeKeyEvent(event, _screenModel));
|
|
317 fixDamage;
|
|
318 return true;
|
|
319 }
|
|
320
|
|
321 bool onMotionNotify(GdkEventMotion * event, Widget widget) {
|
|
322 assert(widget is _drawingArea);
|
|
323
|
|
324 // Pass the events on to the rulers so that they update
|
|
325 gtk_widget_event(_hRuler.getWidgetStruct(), cast(GdkEvent *)event);
|
|
326 gtk_widget_event(_vRuler.getWidgetStruct(), cast(GdkEvent *)event);
|
|
327
|
|
328 _eventHandler.handleMotion(this, makeMotionEvent(event, _screenModel));
|
|
329 fixDamage;
|
|
330 return true;
|
|
331 }
|
|
332
|
|
333 bool onScroll(GdkEventScroll * event, Widget widget) {
|
|
334 assert(widget is _drawingArea);
|
|
335 _eventHandler.handleScroll(this, makeScrollEvent(event, _screenModel));
|
|
336 fixDamage;
|
|
337 return true;
|
|
338 }
|
|
339
|
|
340 bool onEnterNotify(GdkEventCrossing * event, Widget widget) {
|
|
341 trace("1");
|
|
342 assert(widget is _drawingArea);
|
|
343 trace("2");
|
|
344 _eventHandler.handleEnter(this, makeCrossingEvent(event, _screenModel));
|
|
345 trace("3");
|
|
346 fixDamage;
|
|
347 trace("4");
|
|
348 return true;
|
|
349 }
|
|
350
|
|
351 bool onLeaveNotify(GdkEventCrossing * event, Widget widget) {
|
|
352 assert(widget is _drawingArea);
|
|
353 _eventHandler.handleLeave(this, makeCrossingEvent(event, _screenModel));
|
|
354 fixDamage;
|
|
355 return true;
|
|
356 }
|
|
357
|
|
358 bool onFocusIn(GdkEventFocus * event, Widget widget) {
|
|
359 trace("onFocusIn");
|
|
360 return true;
|
|
361 }
|
|
362
|
|
363 bool onFocusOut(GdkEventFocus * event, Widget widget) {
|
|
364 trace("onFocusOut");
|
|
365 return true;
|
|
366 }
|
|
367
|
|
368 void onMoveFocus(GtkDirectionType direction, Widget widget) {
|
|
369 trace("onMoveFocus");
|
|
370 }
|
|
371
|
|
372 bool onGrabBroken(gdk.Event.Event event, Widget widget) {
|
|
373 trace("onGrabBroken");
|
|
374 return true;
|
|
375 }
|
|
376
|
|
377 void onGrabFocus(Widget widget) {
|
|
378 //trace("onGrabFocus");
|
|
379 }
|
|
380
|
|
381 void onGrabNotify(gboolean what, Widget widget){
|
|
382 trace("onGrabNotify");
|
|
383 }
|
|
384
|
|
385 void onAdjustmentValueChanged(Adjustment adjustment) {
|
|
386 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
|
|
387 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
|
|
388
|
|
389 Point oldViewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
|
|
390 Point newViewLeftBottom = Point(gtk_adjustment_get_value(hGtkAdjustment),
|
|
391 gtk_adjustment_get_value(vGtkAdjustment));
|
|
392
|
|
393 _screenModel.panRelativeModel(newViewLeftBottom - oldViewLeftBottom);
|
|
394
|
|
395 updateRulers;
|
|
396 queueDraw;
|
|
397 }
|
|
398
|
|
399 void updateRulers() {
|
|
400 immutable Point viewLeftBottom = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner0);
|
|
401 immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
|
|
402
|
|
403 // Define these just to obtain the position
|
|
404 // below so we can preserve it
|
|
405 double lower, upper, position, maxSize;
|
|
406
|
|
407 _hRuler.getRange(lower, upper, position, maxSize);
|
|
408 _hRuler.setRange(viewLeftBottom.x,
|
|
409 viewRightTop.x,
|
|
410 position,
|
|
411 _screenModel.zoom * 50.0);
|
|
412
|
|
413 _vRuler.getRange(lower, upper, position, maxSize);
|
|
414 _vRuler.setRange(viewRightTop.y,
|
|
415 viewLeftBottom.y,
|
|
416 position,
|
|
417 _screenModel.zoom * 50.0);
|
|
418 }
|
|
419
|
|
420 void updateAdjustments() {
|
|
421 immutable Point viewLeftBottom = _screenModel.screenToModel(Point(0.0, 0.0));
|
|
422 immutable Point viewRightTop = _screenModel.screenToModel(_screenModel.viewBoundsScreen.corner1);
|
|
423
|
|
424 // Adjust the canvas size if necessary
|
|
425 _screenModel.canvasAccommodate(Rectangle(viewLeftBottom, viewRightTop));
|
|
426
|
|
427 Rectangle viewBoundsModel = _screenModel.viewBoundsModel;
|
|
428
|
|
429 // Update the adjustments
|
|
430
|
|
431 GtkAdjustment * hGtkAdjustment = _hAdjustment.getAdjustmentStruct;
|
|
432 GtkAdjustment * vGtkAdjustment = _vAdjustment.getAdjustmentStruct;
|
|
433
|
|
434 gtk_adjustment_set_lower(hGtkAdjustment, _screenModel.canvasBoundsModel.x0);
|
|
435 gtk_adjustment_set_upper(hGtkAdjustment, _screenModel.canvasBoundsModel.x1);
|
|
436 gtk_adjustment_set_value(hGtkAdjustment, viewLeftBottom.x);
|
|
437 gtk_adjustment_set_step_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 16.0);
|
|
438 gtk_adjustment_set_page_increment(hGtkAdjustment, _screenModel.canvasBoundsModel.w / 4.0);
|
|
439 gtk_adjustment_set_page_size(hGtkAdjustment, viewBoundsModel.w);
|
|
440
|
|
441 gtk_adjustment_set_lower(vGtkAdjustment, _screenModel.canvasBoundsModel.y0);
|
|
442 gtk_adjustment_set_upper(vGtkAdjustment, _screenModel.canvasBoundsModel.y1);
|
|
443 gtk_adjustment_set_value(vGtkAdjustment, viewLeftBottom.y);
|
|
444 gtk_adjustment_set_step_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 16.0);
|
|
445 gtk_adjustment_set_page_increment(vGtkAdjustment, _screenModel.canvasBoundsModel.h / 4.0);
|
|
446 gtk_adjustment_set_page_size(vGtkAdjustment, viewBoundsModel.h);
|
|
447
|
|
448 _hAdjustment.changed;
|
|
449 _hAdjustment.valueChanged;
|
|
450 _vAdjustment.changed;
|
|
451 _vAdjustment.valueChanged;
|
|
452 }
|
|
453
|
|
454 void fixDamage() {
|
|
455 if (_damageScreen.valid) {
|
|
456 int x, y, w, h;
|
|
457 _damageScreen.getQuantised(x, y, w, h);
|
|
458 _drawingArea.queueDrawArea(x, cast(int)_screenModel.viewBoundsScreen.h - (y + h), w, h);
|
|
459 _damageScreen = Rectangle.DEFAULT;
|
|
460 }
|
|
461 }
|
|
462
|
|
463 void onRealize(Widget widget) {
|
|
464 assert(widget is _drawingArea);
|
|
465 _drawingArea.grabFocus();
|
|
466 }
|
|
467
|
|
468 IEventHandler _eventHandler;
|
|
469 IGrid _grid;
|
|
470 double _pixelsPerMillimetre;
|
|
471 LayerStack _layerStack;
|
|
472
|
|
473 // Child widgets:
|
|
474 HRuler _hRuler;
|
|
475 VRuler _vRuler;
|
|
476 DrawingArea _drawingArea;
|
|
477 Adjustment _hAdjustment;
|
|
478 HScrollbar _hScrollbar;
|
|
479 Adjustment _vAdjustment;
|
|
480 VScrollbar _vScrollbar;
|
|
481
|
|
482 Rectangle _damageScreen;
|
|
483 ScreenModel _screenModel;
|
|
484
|
|
485 immutable CursorType[Cursor] _cursors;
|
|
486 }
|
|
487
|
86
|
488 private {
|
|
489 class GLDrawingArea : DrawingArea {
|
|
490 GLfloat width;
|
|
491 GLfloat height;
|
85
|
492
|
86
|
493 /** need to include the mixin to add GL capabilities to this widget */
|
|
494 mixin GLCapability;
|
85
|
495
|
86
|
496 /**
|
|
497 * Construct a simple DrawingArea and sets the GLCapabilities
|
|
498 */
|
|
499 this() {
|
|
500 setGLCapability(); // set the GL capabilities for this widget
|
|
501 }
|
85
|
502
|
86
|
503 /**
|
|
504 * put any gl initializations here
|
|
505 * returns true to consume the event
|
|
506 */
|
|
507 bool initGL() {
|
|
508 trace("initGL");
|
85
|
509
|
86
|
510 //resizeGL(null);
|
|
511 return false;
|
|
512 }
|
85
|
513
|
86
|
514 /**
|
|
515 * This method is called every time the window must be paint or repaint
|
|
516 * This is where you put the OpenGL call to draw something.
|
|
517 * This method call be called directly by the application without an event object
|
|
518 * to force redrawing of the scene.
|
|
519 * returns true to consume the event
|
|
520 */
|
|
521 bool drawGL(GdkEventExpose* event = null) {
|
|
522 trace("drawGL");
|
85
|
523
|
86
|
524 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
525 glLoadIdentity ();
|
85
|
526
|
86
|
527 gluLookAt(0, 0, 10, 0, 0, 0, 0, 1,0); //Set the camera position
|
85
|
528
|
86
|
529 //Just Draw a tri-colored triangle
|
|
530 glBegin(GL_TRIANGLES);
|
|
531 glColor3f(1.0f,0.0f,0.0f);
|
|
532 glVertex3f( 0.0f, 1.0f, 0.0f);
|
|
533 glColor3f(0.0f,1.0f,0.0f);
|
|
534 glVertex3f(-1.0f,-1.0f, 0.0f);
|
|
535 glColor3f(0.0f,0.0f,1.0f);
|
|
536 glVertex3f( 1.0f,-1.0f, 0.0f);
|
|
537 glEnd();
|
85
|
538
|
86
|
539 return false;
|
|
540 }
|
85
|
541
|
86
|
542 /**
|
|
543 * This method is called when the window is resized
|
|
544 * returns true to consume the event
|
|
545 */
|
|
546 bool resizeGL(GdkEventConfigure* event = null) {
|
|
547 trace("resizeGL");
|
|
548 assert(event);
|
85
|
549
|
86
|
550 if (event == null) {
|
|
551 width = getWidth();
|
|
552 height = getHeight();
|
|
553 }
|
|
554 else {
|
|
555 width = event.width;
|
|
556 height = event.height;
|
|
557 }
|
|
558
|
|
559 trace("Size %sx%s", width, height);
|
85
|
560
|
86
|
561 glViewport(0, 0, cast(int)width, cast(int)height); //Adjust the viewport according to new window dimensions
|
|
562
|
|
563 /*
|
|
564 * Update the projection Matrix accoding to the new dimension
|
|
565 * and reset the OpenGL state to MODELVIEW
|
|
566 */
|
|
567 glMatrixMode(GL_PROJECTION);
|
|
568 glLoadIdentity();
|
|
569 gluPerspective(20, width/height, 0.1, 10);
|
|
570 glMatrixMode(GL_MODELVIEW);
|
|
571
|
|
572 return false;
|
|
573 }
|
85
|
574 }
|
|
575 }
|
|
576 }
|