The OpenD Programming Language

OpenGlWidget

Nests an opengl capable window inside this window as a widget.

You may also just want to create an additional SimpleWindow with OpenGlOptions.yes yourself.

An OpenGL widget cannot have child widgets. It will throw if you try.

static if(OpenGlEnabled)
class OpenGlWidget : NestedChildWindowWidget {}

Constructors

this
this(Widget parent)

Inherited Members

From NestedChildWindowWidget

focusableWindow
SimpleWindow focusableWindow()

Used on X to send focus to the appropriate child window when requested by the window manager.

dispose
void dispose()

Called upon the nested window being destroyed. Remember the window has already been destroyed at this point, so don't use the native handle for anything.

addChild
void addChild(Widget , int )

OpenGL widgets cannot have child widgets. Do not call this.

registerMovement
void registerMovement()

When an opengl widget is laid out, it will adjust the glViewport for you automatically. Keep in mind that events like mouse coordinates are still relative to your size.

Examples

This demo shows how to draw text in an opengl scene.

1 import arsd.minigui;
2 import arsd.ttf;
3 
4 void main() {
5 	auto window = new Window();
6 
7 	auto widget = new OpenGlWidget(window);
8 
9 	// old means non-shader code so compatible with glBegin etc.
10 	// tbh I haven't implemented new one in font yet...
11 	// anyway, declaring here, will construct soon.
12 	OpenGlLimitedFont!(OpenGlFontGLVersion.old) glfont;
13 
14 	// this is a little bit awkward, calling some methods through
15 	// the underlying SimpleWindow `win` method, and you can't do this
16 	// on a nanovega widget due to conflicts so I should probably fix
17 	// the api to be a bit easier. But here it will work.
18 	//
19 	// Alternatively, you could load the font on the first draw, inside
20 	// the redrawOpenGlScene, and keep a flag so you don't do it every
21 	// time. That'd be a bit easier since the lib sets up the context
22 	// by then guaranteed.
23 	//
24 	// But still, I wanna show this.
25 	widget.win.visibleForTheFirstTime = delegate {
26 		// must set the opengl context
27 		widget.win.setAsCurrentOpenGlContext();
28 
29 		// if you were doing a OpenGL 3+ shader, this
30 		// gets especially important to do in order. With
31 		// old-style opengl, I think you can even do it
32 		// in main(), but meh, let's show it more correctly.
33 
34 		// Anyway, now it is time to load the font from the
35 		// OS (you can alternatively load one from a .ttf file
36 		// you bundle with the application), then load the
37 		// font into texture for drawing.
38 
39 		auto osfont = new OperatingSystemFont("DejaVu Sans", 18);
40 
41 		assert(!osfont.isNull()); // make sure it actually loaded
42 
43 		// using typeof to avoid repeating the long name lol
44 		glfont = new typeof(glfont)(
45 			// get the raw data from the font for loading in here
46 			// since it doesn't use the OS function to draw the
47 			// text, we gotta treat it more as a file than as
48 			// a drawing api.
49 			osfont.getTtfBytes(),
50 			18, // need to respecify size since opengl world is different coordinate system
51 
52 			// these last two numbers are why it is called
53 			// "Limited" font. It only loads the characters
54 			// in the given range, since the texture atlas
55 			// it references is all a big image generated ahead
56 			// of time. You could maybe do the whole thing but
57 			// idk how much memory that is.
58 			//
59 			// But here, 0-128 represents the ASCII range, so
60 			// good enough for most English things, numeric labels,
61 			// etc.
62 			0,
63 			128
64 		);
65 	};
66 
67 	widget.redrawOpenGlScene = () {
68 		// now we can use the glfont's drawString function
69 
70 		// first some opengl setup. You can do this in one place
71 		// on window first visible too in many cases, just showing
72 		// here cuz it is easier for me.
73 
74 		// gonna need some alpha blending or it just looks awful
75 		glEnable(GL_BLEND);
76 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
77 		glClearColor(0,0,0,0);
78 		glDepthFunc(GL_LEQUAL);
79 
80 		// Also need to enable 2d textures, since it draws the
81 		// font characters as images baked in
82 		glMatrixMode(GL_MODELVIEW);
83 		glLoadIdentity();
84 		glDisable(GL_DEPTH_TEST);
85 		glEnable(GL_TEXTURE_2D);
86 
87 		// the orthographic matrix is best for 2d things like text
88 		// so let's set that up. This matrix makes the coordinates
89 		// in the opengl scene be one-to-one with the actual pixels
90 		// on screen. (Not necessarily best, you may wish to scale
91 		// things, but it does help keep fonts looking normal.)
92 		glMatrixMode(GL_PROJECTION);
93 		glLoadIdentity();
94 		glOrtho(0, widget.width, widget.height, 0, 0, 1);
95 
96 		// you can do other glScale, glRotate, glTranslate, etc
97 		// to the matrix here of course if you want.
98 
99 		// note the x,y coordinates here are for the text baseline
100 		// NOT the upper-left corner. The baseline is like the line
101 		// in the notebook you write on. Most the letters are actually
102 		// above it, but some, like p and q, dip a bit below it.
103 		//
104 		// So if you're used to the upper left coordinate like the
105 		// rest of simpledisplay/minigui usually do, do the
106 		// y + glfont.ascent to bring it down a little. So this
107 		// example puts the string in the upper left of the window.
108 		glfont.drawString(0, 0 + glfont.ascent, "Hello!!", Color.green);
109 
110 		// re color btw: the function sets a solid color internally,
111 		// but you actually COULD do your own thing for rainbow effects
112 		// and the sort if you wanted too, by pulling its guts out.
113 		// Just view its source for an idea of how it actually draws:
114 		// http://arsd-official.dpldocs.info/source/arsd.ttf.d.html#L332
115 
116 		// it gets a bit complicated with the character positioning,
117 		// but the opengl parts are fairly simple: bind a texture,
118 		// set the color, draw a quad for each letter.
119 
120 
121 		// the last optional argument there btw is a bounding box
122 		// it will/ use to word wrap and return an object you can
123 		// use to implement scrolling or pagination; it tells how
124 		// much of the string didn't fit in the box. But for simple
125 		// labels we can just ignore that.
126 
127 
128 		// I'd suggest drawing text as the last step, after you
129 		// do your other drawing. You might use the push/pop matrix
130 		// stuff to keep your place. You, in theory, should be able
131 		// to do text in a 3d space but I've never actually tried
132 		// that....
133 	};
134 
135 	window.loop();
136 }

Meta