3 /* -------------------------------------------------------------------------- */
10 /* ------------------------------------------------------------- */
16 #include "X11/Xutil.h"
19 #include <GLES2/gl2.h>
21 #define WINDOW_WIDTH 640
22 #define WINDOW_HEIGHT 480
25 #define NORMAL_ARRAY 1
26 #define TEXCOORD_ARRAY 2
30 /* ------------------------------------------------------------- */
33 Display* x11Display = 0;
35 XVisualInfo* x11Visual = 0;
36 Colormap x11Colormap = 0;
38 EGLDisplay eglDisplay = 0;
39 EGLConfig eglConfig = 0;
40 EGLSurface eglSurface = 0;
41 EGLContext eglContext = 0;
43 /* ------------------------------------------------------------- */
45 /* -------------------------------------------------------------------------- */
48 static GLfloat xco= 0;
49 static GLfloat yco= 1;
50 static GLfloat zco= -35;
51 static GLfloat view_rotx=0.0, view_roty=0.0, view_rotz=0.0;
54 /* -------------------------------------------------------------------------- */
56 static int handles_resource(char* name);
57 static void sync_resource(ni_resource* res);
58 static void init_gl(void);
59 static void make_world(void);
60 static void reshape(int width, int height);
61 static void draw(void);
62 static void key(unsigned char k, int down);
63 static void plane(void* n);
64 static void double_cube(void* s);
65 static void cube(GLfloat size, int outside);
66 static int set_object(char* n,
67 GLfloat x, GLfloat y, GLfloat z, GLfloat angle,
68 void (*listFn)(void*),
71 /* -------------------------------------------------------------------------- */
73 EXPORT int mid_module_loaded(void)
75 ni_register_driver("mid", handles_resource, sync_resource);
80 k_gl_register_reshape(reshape);
81 k_gl_register_draw(draw);
82 k_gl_register_key(key);
84 k_log_out("MID Driver initialised");
91 EXPORT int mid_module_event(void* data)
93 k_log_out("MID got event: %p", data);
99 /* -------------------------------------------------------------------------- */
101 int handles_resource(char* name)
106 void sync_resource(ni_resource* res)
110 /* -------------------------------------------------------------------------- */
116 void make_world(void)
120 void reshape(int width, int height)
129 void key(unsigned char k, int down)
131 if(k==SHIFT && down){ shift=1; return; }
132 if(k==SHIFT && !down){ shift=0; return; }
135 if(shift) k-=('a'-'A');
140 xco-=speed*(float)sin((view_roty-90)*3.14/180);
141 zco+=speed*(float)cos((view_roty-90)*3.14/180);
142 if(xco< -35) xco= -35;
144 if(zco< -35) zco= -35;
148 xco+=speed*(float)sin((view_roty-90)*3.14/180);
149 zco-=speed*(float)cos((view_roty-90)*3.14/180);
150 if(xco< -35) xco= -35;
152 if(zco< -35) zco= -35;
156 xco-=speed*(float)sin(view_roty*3.14/180);
157 zco+=speed*(float)cos(view_roty*3.14/180);
158 if(xco< -35) xco= -35;
160 if(zco< -35) zco= -35;
164 xco+=speed*(float)sin(view_roty*3.14/180);
165 zco-=speed*(float)cos(view_roty*3.14/180);
166 if(xco< -35) xco= -35;
168 if(zco< -35) zco= -35;
173 if(yco< 0.2) yco= 0.2;
179 view_roty += speed*20;
182 view_roty -= speed*20;
204 /* -------------------------------------------------------------------------- */
205 /* ------------------------------------------------------------- */
207 void cleanupAndExit(int code)
209 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
210 eglTerminate(eglDisplay);
212 if(x11Window) XDestroyWindow(x11Display, x11Window);
213 if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
214 if(x11Display) XCloseDisplay( x11Display);
219 /* ------------------------------------------------------------- */
221 void getX11Display(int windowwidth, int windowheight)
223 x11Display = XOpenDisplay(0);
226 printf("Error: Unable to open X display\n");
230 x11Screen = XDefaultScreen(x11Display);
231 Window rootWindow = RootWindow(x11Display, x11Screen);
232 int depth = DefaultDepth(x11Display, x11Screen);
233 x11Visual = malloc(sizeof(XVisualInfo));
234 XMatchVisualInfo(x11Display, x11Screen, depth, TrueColor, x11Visual);
237 printf("Error: Unable to acquire visual\n");
241 x11Colormap = XCreateColormap(x11Display, rootWindow, x11Visual->visual, AllocNone);
242 XSetWindowAttributes XSWA;
243 XSWA.colormap = x11Colormap;
244 XSWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
245 unsigned int cwmask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
247 x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
248 0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
249 XMapWindow(x11Display, x11Window);
253 int isEGLError(char* where)
255 EGLint err = eglGetError();
256 if(err != EGL_SUCCESS) {
257 printf("EGL failed at %s (%d).\n", where, err);
265 eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display);
267 EGLint iMajorVersion, iMinorVersion;
268 if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
269 printf("Error: eglInitialize() failed.\n");
273 EGLint pi32ConfigAttribs[5];
274 pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
275 pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
276 pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
277 pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
278 pi32ConfigAttribs[4] = EGL_NONE;
280 EGLint pi32ContextAttribs[3];
281 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
282 pi32ContextAttribs[1] = 2;
283 pi32ContextAttribs[2] = EGL_NONE;
286 if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
287 printf("Error: eglChooseConfig() failed.\n");
291 eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)x11Window, NULL);
293 if(isEGLError("eglCreateWindowSurface")) cleanupAndExit( -1);
295 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
297 if(isEGLError("eglCreateContext")) cleanupAndExit( -1);
299 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
301 if(isEGLError("eglMakeCurrent")) cleanupAndExit( -1);
304 /* ------------------------------------------------------------- */
306 GLuint isShaderError(GLuint thing)
308 GLint isShader = glIsShader(thing);
312 glGetShaderiv(thing, GL_COMPILE_STATUS, &ok);
314 glGetProgramiv(thing, GL_LINK_STATUS, &ok);
320 glGetShaderiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
322 glGetProgramiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
325 char* infoLog = malloc(sizeof(char)*infoLen);
327 glGetShaderInfoLog(thing, infoLen, NULL, infoLog);
329 glGetProgramInfoLog(thing, infoLen, NULL, infoLog);
331 printf("%s: %s\n", isShader? "Shader compile": "Program link", infoLog);
337 char* file2string(const char *path)
343 if(!(fd=fopen(path, "r"))) {
344 fprintf(stderr, "Can't open file '%s' for reading\n", path);
348 fseek(fd, 0, SEEK_END);
350 fseek(fd, 0, SEEK_SET);
352 if(!(str=malloc(len*sizeof(char)))) {
353 fprintf(stderr, "Can't malloc space for '%s'\n", path);
357 r = fread(str, sizeof(char), len, fd);
366 /* ------------------------------------------------------------- */
371 unsigned int numberOfVertices;
372 unsigned int posStep;
373 unsigned int normStep;
377 float viewAngle = 0.0;
379 GLuint useTheProgram()
381 const char *vsSource = file2string("tnl.vert");
382 const char *fsSource = file2string("tnl.frag");
384 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
385 glShaderSource(vs, 1, &vsSource, NULL);
387 if(isShaderError(vs)) return 0;
389 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
390 glShaderSource(fs, 1, &fsSource, NULL);
392 if(isShaderError(fs)) return 0;
394 free((void*)vsSource);
395 free((void*)fsSource);
397 program = glCreateProgram();
398 glAttachShader(program, vs);
399 glAttachShader(program, fs);
401 glBindAttribLocation(program, POS_ARRAY, "vertPos");
402 glBindAttribLocation(program, NORMAL_ARRAY, "vertNormal"); /* vertNormal and vertTexCoord don't need to be bound here.. ? */
403 glBindAttribLocation(program, TEXCOORD_ARRAY, "vertTexCoord");
405 glLinkProgram(program);
406 if(isShaderError(program)) return 0;
408 glUseProgram(program);
410 glUniform3f(glGetUniformLocation(program, "frameLightDirection"), 1.0, 0.0, 1.0);
411 glUniform1i(glGetUniformLocation(program, "texture"), 0); /* 0 ?? */
418 glGenTextures(1, &texture);
419 glBindTexture(GL_TEXTURE_2D, texture);
421 GLuint* td = malloc(sizeof(GLuint)*TEX_SIZE*TEX_SIZE);
423 for(i=0; i<TEX_SIZE; i++)
424 for(j=0; j<TEX_SIZE; j++) {
425 GLuint col = (255L<<24) + ((255L-j*2)<<16) + ((255L-i)<<8) + (255L-i*2);
426 if ( ((i*j)/8) % 2 ) col = (GLuint) (255L<<24) + (255L<<16) + (0L<<8) + (255L);
427 td[j*TEX_SIZE+i] = col;
429 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, td);
430 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
431 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
434 GLfloat trivertices[] = {
435 -0.4f,-0.4f,0.4f, // Pos
436 0.0f,0.0f,1.0f, // Normal
437 0.0f,0.0f, // TexCoord
439 0.4f,-0.0f,0.0f, // Pos
440 0.0f,0.0f,1.0f, // Normal
441 1.0f,0.0f, // TexCoord
443 0.0f,0.4f,0.4f, // Pos
444 0.5f,0.5f,0.5f, // Normal
445 0.5f,1.0f, // TexCoord
447 0.4f,0.0f,0.4f, // Pos
448 0.5f,0.5f,0.5f, // Normal
449 0.5f,0.0f, // TexCoord
451 0.4f,0.4f,0.4f, // Pos
452 0.0f,0.0f,1.0f, // Normal
453 0.0f,0.0f, // TexCoord
457 numberOfVertices = 4;
458 posStep = 3 * sizeof(GLfloat);
459 normStep = 3 * sizeof(GLfloat);
460 tcStep = 2 * sizeof(GLfloat);
461 stride = posStep + normStep + tcStep;
463 glGenBuffers(1, &vbo);
464 glBindBuffer(GL_ARRAY_BUFFER, vbo);
465 glBufferData(GL_ARRAY_BUFFER, numberOfVertices * stride, trivertices, GL_STATIC_DRAW);
466 glBindBuffer(GL_ARRAY_BUFFER, 0);
469 int drawStuff(int width, int height)
471 glViewport(0, 0, width, height);
472 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
474 float TransRotScaleVerticeMatrix[] = {
475 cos(angle), 0, sin(angle), 0,
477 -sin(angle), 0, cos(angle), 0,
481 float ModelViewProjectionMatrix[] = {
482 cos(viewAngle), 0, sin(viewAngle), 0,
484 -sin(viewAngle), 0, cos(viewAngle), 0,
488 float TransRotScaleNormalMatrix[] = {
489 cos(angle), 0, sin(angle),
491 -sin(angle), 0, cos(angle)
494 glUniformMatrix4fv(glGetUniformLocation(program, "frameTRSV"), 1, GL_FALSE, TransRotScaleVerticeMatrix);
495 glUniformMatrix4fv(glGetUniformLocation(program, "frameMVP"), 1, GL_FALSE, ModelViewProjectionMatrix);
496 glUniformMatrix3fv(glGetUniformLocation(program, "frameTRSN"), 1, GL_FALSE, TransRotScaleNormalMatrix);
499 glBindBuffer(GL_ARRAY_BUFFER, vbo);
501 glEnableVertexAttribArray(POS_ARRAY);
502 glVertexAttribPointer(POS_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, 0);
504 glEnableVertexAttribArray(NORMAL_ARRAY);
505 glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, (void*)posStep );
507 glEnableVertexAttribArray(TEXCOORD_ARRAY);
508 glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, stride, (void*)(posStep + normStep) );
510 glDrawArrays(GL_TRIANGLE_STRIP, 0, numberOfVertices);
512 glBindBuffer(GL_ARRAY_BUFFER, 0);
514 eglSwapBuffers(eglDisplay, eglSurface);
518 return !isEGLError("drawStuff");
522 glDeleteTextures(1, &texture);
523 glDeleteBuffers(1, &vbo);
524 glDeleteProgram(program);
529 /* ------------------------------------------------------------- */
533 printf("Test OpenGL ES 2.0\n---------------------------\n");
535 getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT);
539 glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
541 if(!useTheProgram()) cleanupAndExit(-1);
547 if(!drawStuff(WINDOW_WIDTH, WINDOW_HEIGHT)) cleanupAndExit(-1);
549 int nm = XPending(x11Display);
551 for(m=0; m< nm; m++) {
554 XNextEvent(x11Display, &event);
560 if(event.xkey.keycode == 113) viewAngle += 0.1;
561 if(event.xkey.keycode == 114) viewAngle -= 0.1;
571 /* ------------------------------------------------------------- */