WINGs: Better presentation for example code in the tutorial
[whome.git] / WINGs_tutorial / glframe.c
blobc298b2d1cfe45ccf9153d47ea439b99aa4edaa67
1 #include <X11/keysym.h>
2 #include <GL/gl.h>
3 #include <GL/glx.h>
5 #include <WINGs/WINGs.h>
6 #include <WINGs/WINGsP.h>
7 #include <stdio.h>
9 #define CONTENTH 300
10 #define CONTENTW 300
11 #define CONTENTMARGIN 30
14 struct couple {
15 WMWindow *window;
16 WMFrame *frame;
17 } datacouple;
20 float red = 252.0/256, green = 88.0/256, blue = 16.0/256;
21 float redb = 252.0/256, greenb = 242.0/256, blueb = 80.0/256;
23 int Attr[] = {
24 GLX_RGBA,
25 GLX_RED_SIZE, 8,
26 GLX_GREEN_SIZE, 8,
27 GLX_BLUE_SIZE, 8,
28 GLX_DEPTH_SIZE, 16,
29 GLX_DOUBLEBUFFER,
30 None
32 Display *display;
33 float alpha = 0;
35 void init(void)
37 GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
38 GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
39 GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
40 GLfloat position[] = { 2.0f, -0.1f, 2.0f, 1.0f };
41 GLfloat position2[] = { -2.0f, -0.26f, -4.0f, 1.0f };
43 glClearColor(256.0/256, 256.0/256, 256.0/256, 0.0);
44 glPolygonMode(GL_FRONT, GL_FILL);
45 glPolygonMode(GL_BACK, GL_FILL);
46 glEnable(GL_DEPTH_TEST);
47 glShadeModel(GL_SMOOTH);
49 glEnable(GL_LIGHTING);
50 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
51 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
52 //glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
53 glMateriali(GL_FRONT, GL_SHININESS, 98);
54 glLightfv(GL_LIGHT0, GL_POSITION, position2);
55 //glLightfv(GL_LIGHT1, GL_POSITION, position2);
57 glEnable(GL_LIGHT0);
58 //glEnable(GL_LIGHT1);
59 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
60 //glColorMaterial(GL_FRONT, GL_SPECULAR);
61 glEnable(GL_COLOR_MATERIAL);
62 glShadeModel(GL_SMOOTH);
63 glCullFace(GL_BACK);
64 glEnable(GL_CULL_FACE);
66 glEnable(GL_POLYGON_SMOOTH);
67 /*glEnable(GL_BLEND);
68 glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
69 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
70 glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);*/
73 void normvector(float a, float aa, float aaa,
74 float b, float bb, float bbb,
75 float c, float cc, float ccc,
76 float *result)
78 float v1[3], v2[3], tmp;
80 v1[0] = (b-a); v1[1] = (bb-aa); v1[2] = (bbb-aaa);
81 v2[0] = (b-c); v2[1] = (bb-cc); v2[2] = (bbb-ccc);
83 result[0] = (v1[1] * v2[2] - v1[2] * v2[1]);
84 result[1] = (v1[2] * v2[0] - v1[0] * v2[2]);
85 result[2] = (v1[0] * v2[1] - v1[1] * v2[0]);
87 tmp = sqrt(result[0] * result[0] + result[1] * result[1] + result[2] * result[2]);
88 result[0] /= tmp;
89 result[1] /= tmp;
90 result[2] /= tmp;
94 void redraw(XEvent * v, void *xw)
96 Window win;
97 float z[3];
99 win = *(Window *)xw;
101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102 glPushMatrix();
103 glShadeModel(GL_SMOOTH);
105 glRotatef(alpha, 0, 1, 0);
107 glBegin(GL_TRIANGLES);
109 glColor3f(redb, greenb, blueb);
110 normvector(-0.85f, 0.0f, 0.0f, 0.0f, 0.0f, 0.85f, 0.0f, 0.6f, 0.0f, z);
111 glNormal3fv(z);
112 glVertex3f(-0.85f, 0.0f, 0.0f);
113 glVertex3f(0.0f, 0.0f, 0.85f);
114 glVertex3f(0.0f, 0.6f, 0.0f);
116 normvector(0.0f, 0.0f,0.85f, 0.85f, 0.0f, 0.0f, 0.0f, 0.60f,0.0f, z);
117 glNormal3fv(z);
118 glVertex3f(0.0f, 0.0f, 0.85f);
119 glVertex3f(0.85f, 0.0f, 0.0f);
120 glVertex3f(0.0f, 0.6f, 0.0f);
122 glColor3f(red, green, blue);
123 normvector(0.85f, 0.0f, 0.0f, 0.0f, 0.0f, -0.85f, 0.0f, 0.6f, 0.0f, z);
124 glNormal3fv(z);
125 glVertex3f(0.85f, 0.0f, 0.0f);
126 glVertex3f(0.0f, 0.0f, -0.85f);
127 glVertex3f(0.0f, 0.6f, 0.0f);
129 normvector(0.0f, 0.0f, -0.85f, -0.85f, 0.0f, 0.0f, 0.0f, 0.6f, 0.0f, z);
130 glNormal3fv(z);
131 glVertex3f(0.0f, 0.0f, -0.85f);
132 glVertex3f(-0.85f, 0.0f, 0.0f);
133 glVertex3f(0.0f, 0.6f, 0.0f);
135 glColor3f(redb, greenb, blueb);
136 normvector(-0.85f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.85f, z);
137 glNormal3fv(z);
138 glVertex3f(-0.85f, 0.0f, 0.0f);
139 glVertex3f(0.0f, -1.0f, 0.0f);
140 glVertex3f(0.0f, 0.0f, 0.85f);
142 normvector(0.0f, 0.0f, 0.85f, 0.0f, -1.0f, 0.0f,0.85f, 0.0f, 0.0f, z);
143 glNormal3fv(z);
144 glVertex3f(0.0f, 0.0f, 0.85f);
145 glVertex3f(0.0f, -1.0f, 0.0f);
146 glVertex3f(0.85f, 0.0f, 0.0f);
148 glColor3f(red, green, blue);
149 normvector(0.85f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0, -0.85f, z);
150 glNormal3fv(z);
151 glVertex3f(0.85f, 0.0f, 0.0f);
152 glVertex3f(0.0f,-1.0f, 0.0f);
153 glVertex3f(0.0f, 0.0f, -0.85f);
155 normvector(0.0f, 0.0f, -0.85f, 0.0f, -1.0f, 0.0f, -0.85f, 0.0f, 0.0f, z);
156 glNormal3fv(z);
157 glVertex3f(0.0f, 0.0f, -0.85f);
158 glVertex3f(0.0f, -1.0f, 0.0f);
159 glVertex3f(-0.85f, 0.0f, 0.0f);
161 glEnd();
163 glPopMatrix();
164 glXSwapBuffers(display, win);
167 setsize(unsigned int width, unsigned int height)
169 glViewport(0, 0, width, height);
170 glMatrixMode(GL_PROJECTION);
171 glLoadIdentity();
172 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
173 glMatrixMode(GL_MODELVIEW);
176 void DoRotate(void *self, void *xwindow)
178 XEvent event;
179 int i = 0;
181 alpha += 15;
182 if (alpha > 360) alpha = alpha - 360;
184 redraw(NULL, (Window *)xwindow);
187 void redo(XEvent * event, void *xw)
189 switch (event->type) {
190 case Expose:
191 if (event->xexpose.count != 0) break;
192 redraw(event, &event->xexpose.window);
193 break;
195 case ConfigureNotify:
196 setsize(event->xconfigure.width, event->xconfigure.height); // assuming there will be an expose afterwards
197 break;
201 void closeAll(WMWidget *self, void *data)
203 WMDestroyWidget(self);
204 exit(0);
207 static void resizeHandler(void *data, WMNotification *notif)
209 struct couple *tmp;
210 WMSize size;
212 tmp = (struct couple *) data;
213 size = WMGetViewSize(WMWidgetView(tmp->window));
214 WMResizeWidget(tmp->frame, size.width - 2*CONTENTMARGIN, size.height - 2*CONTENTMARGIN);
217 void getargs(int argc, char **argv)
219 if (argc > 3) {
220 redb = red = (float)atoi(argv[1]) / 256;
221 greenb = green = (float)atoi(argv[2]) / 256;
222 blueb = blue = (float)atoi(argv[3]) / 256;
224 if (argc > 6) {
225 redb = (float)atoi(argv[4]) / 256;
226 greenb = (float)atoi(argv[5]) / 256;
227 blueb = (float)atoi(argv[6]) / 256;
231 int main(int argc, char **argv)
233 WMFrame *glframe;
234 WMScreen *screen;
235 WMWindow *window;
236 WMButton *Button;
238 /* Xlib and glX variables */
239 Window win;
240 XVisualInfo *xvVisualInfo;
241 Colormap cmColorMap;
242 XSetWindowAttributes winAttr;
243 GLXContext glXContext;
245 getargs(argc, argv);
246 WMInitializeApplication("GLWindow", &argc, argv);
247 display = XOpenDisplay("");
248 screen = WMCreateScreen(display, DefaultScreen(display));
250 if(!glXQueryExtension(display, NULL, NULL)) {
251 werror("X server does not have GLX\n");
252 return 0;
255 window = WMCreateWindow(screen, "Main");
256 WMResizeWidget(window, CONTENTW + 2*CONTENTMARGIN, CONTENTH + 2*CONTENTMARGIN*CONTENTH/CONTENTW);
257 WMSetWindowAspectRatio(window, CONTENTW, CONTENTH, CONTENTW, CONTENTH);
258 WMSetWindowCloseAction(window, closeAll, NULL);
259 WMSetWindowTitle(window, "GL Frame");
260 WMRealizeWidget(window);
261 datacouple.window = window;
262 WMSetViewNotifySizeChanges(WMWidgetView(window), True);
263 WMAddNotificationObserver(resizeHandler, &datacouple, WMViewSizeDidChangeNotification, WMWidgetView(window));
265 glframe = WMCreateFrame(window);
266 datacouple.frame = glframe;
267 WMResizeWidget(glframe, CONTENTW, CONTENTH);
268 WMMoveWidget(glframe, CONTENTMARGIN, CONTENTMARGIN);
269 WMRealizeWidget(glframe);
271 Button = WMCreateButton(window, WBTMomentaryPush);
272 WMSetButtonAction(Button, DoRotate, &win);
273 WMSetButtonText(Button, "Turn");
274 WMMoveWidget(Button, CONTENTMARGIN, 2);
275 WMRealizeWidget(Button);
276 WMMapWidget(Button);
278 /* get the frame's X window value */
279 win = W_VIEW_DRAWABLE(WMWidgetView(glframe));
280 WMCreateEventHandler(WMWidgetView(glframe), ExposureMask | StructureNotifyMask, redo, &win);
282 xvVisualInfo = glXChooseVisual(display, DefaultScreen(display), Attr);
283 if (xvVisualInfo == NULL) {
284 werror("glX could not find a suitable visual\n");
285 return 0;
288 cmColorMap = XCreateColormap(display, RootWindow(display, DefaultScreen(display)), xvVisualInfo->visual, AllocNone);
290 winAttr.colormap = cmColorMap;
291 winAttr.border_pixel = 0;
292 winAttr.background_pixel = 0;
293 winAttr.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask | KeyPressMask;
295 XChangeWindowAttributes(display, win, CWBorderPixel | CWColormap | CWEventMask, &winAttr);
296 glXContext = glXCreateContext(display, xvVisualInfo, None, True);
297 if(!glXContext) {
298 werror("glX cannot create rendering context\n");
299 return 0;
302 glXMakeCurrent(display, win, glXContext);
304 WMMapWidget(glframe);
305 init();
306 setsize(CONTENTW, CONTENTH);
307 WMMapWidget(window);
309 WMScreenMainLoop(screen);
311 return 0;