3 /* -------------------------------------------------------------------------- */
8 /* -------------------------------------------------------------------------- */
13 #include <GLES2/gl2.h>
15 #define WINDOW_WIDTH 640
16 #define WINDOW_HEIGHT 480
19 #define NORMAL_ARRAY 1
20 #define TEXCOORD_ARRAY 2
24 /* -------------------------------------------------------------------------- */
26 EGLNativeDisplayType eglX11Display;
27 EGLNativeWindowType eglX11Window;
28 EGLDisplay eglDisplay = 0;
29 EGLConfig eglConfig = 0;
30 EGLSurface eglSurface = 0;
31 EGLContext eglContext = 0;
33 /* -------------------------------------------------------------------------- */
36 static GLfloat xco= 0;
37 static GLfloat yco= 1;
38 static GLfloat zco= -35;
39 static GLfloat view_rotx=0.0, view_roty=0.0, view_rotz=0.0;
42 /* -------------------------------------------------------------------------- */
44 static int handles_resource(char* name);
45 static void sync_resource(ni_resource* res);
46 static void init_gl(void);
47 static void reshape(int width, int height);
48 static void draw(void);
49 static void key(unsigned char k, int down);
51 static void destroyEGL();
52 static int getX11Display(int windowwidth, int windowheight);
53 static int setUpEGL();
54 static int useTheProgram();
55 static int setUpTnL();
56 static int drawStuff(int width, int height);
58 /* -------------------------------------------------------------------------- */
60 EXPORT int mid_module_loaded(void)
62 ni_register_driver("mid", handles_resource, sync_resource);
66 k_gl_register_reshape(reshape);
67 k_gl_register_draw(draw);
68 k_gl_register_key(key);
70 k_log_out("MID Driver initialised");
75 EXPORT int mid_module_event(void* data)
77 k_log_out("MID got event: %p", data);
83 /* -------------------------------------------------------------------------- */
85 int handles_resource(char* name)
90 void sync_resource(ni_resource* res)
94 /* -------------------------------------------------------------------------- */
98 if(!getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT)) destroyEGL();
99 if(!setUpEGL()) destroyEGL();
100 if(!useTheProgram()) destroyEGL();
101 if(!setUpTnL()) destroyEGL();
104 void reshape(int width, int height)
110 if(!drawStuff(WINDOW_WIDTH, WINDOW_HEIGHT)) destroyEGL();
114 void key(unsigned char k, int down)
117 if(event.xkey.keycode == 113) viewAngle += 0.1;
118 if(event.xkey.keycode == 114) viewAngle -= 0.1;
120 if(k==SHIFT && down){ shift=1; return; }
121 if(k==SHIFT && !down){ shift=0; return; }
124 if(shift) k-=('a'-'A');
129 xco-=speed*(float)sin((view_roty-90)*3.14/180);
130 zco+=speed*(float)cos((view_roty-90)*3.14/180);
131 if(xco< -35) xco= -35;
133 if(zco< -35) zco= -35;
137 xco+=speed*(float)sin((view_roty-90)*3.14/180);
138 zco-=speed*(float)cos((view_roty-90)*3.14/180);
139 if(xco< -35) xco= -35;
141 if(zco< -35) zco= -35;
145 xco-=speed*(float)sin(view_roty*3.14/180);
146 zco+=speed*(float)cos(view_roty*3.14/180);
147 if(xco< -35) xco= -35;
149 if(zco< -35) zco= -35;
153 xco+=speed*(float)sin(view_roty*3.14/180);
154 zco-=speed*(float)cos(view_roty*3.14/180);
155 if(xco< -35) xco= -35;
157 if(zco< -35) zco= -35;
162 if(yco< 0.2) yco= 0.2;
168 view_roty += speed*20;
171 view_roty -= speed*20;
191 /* -------------------------------------------------------------------------- */
193 /* need a callback to call this */
196 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
197 eglTerminate(eglDisplay);
200 /* ------------------------------------------------------------- */
202 int isEGLError(char* where)
204 EGLint err = eglGetError();
205 if(err != EGL_SUCCESS) {
206 printf("EGL failed at %s (%d).\n", where, err);
214 eglDisplay = eglGetDisplay(eglX11Display);
216 EGLint iMajorVersion, iMinorVersion;
217 if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
218 printf("Error: eglInitialize() failed.\n");
222 EGLint pi32ConfigAttribs[5];
223 pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
224 pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
225 pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
226 pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
227 pi32ConfigAttribs[4] = EGL_NONE;
229 EGLint pi32ContextAttribs[3];
230 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
231 pi32ContextAttribs[1] = 2;
232 pi32ContextAttribs[2] = EGL_NONE;
235 if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
236 printf("Error: eglChooseConfig() failed.\n");
240 eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglX11Window, NULL);
241 if(isEGLError("eglCreateWindowSurface")) return 0;
243 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
244 if(isEGLError("eglCreateContext")) return 0;
246 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
247 if(isEGLError("eglMakeCurrent")) return 0;
252 /* ------------------------------------------------------------- */
254 GLuint isShaderError(GLuint thing)
256 GLint isShader = glIsShader(thing);
260 glGetShaderiv(thing, GL_COMPILE_STATUS, &ok);
262 glGetProgramiv(thing, GL_LINK_STATUS, &ok);
268 glGetShaderiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
270 glGetProgramiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
273 char* infoLog = malloc(sizeof(char)*infoLen);
275 glGetShaderInfoLog(thing, infoLen, NULL, infoLog);
277 glGetProgramInfoLog(thing, infoLen, NULL, infoLog);
279 printf("%s: %s\n", isShader? "Shader compile": "Program link", infoLog);
285 char* file2string(const char *path)
291 if(!(fd=fopen(path, "r"))) {
292 fprintf(stderr, "Can't open file '%s' for reading\n", path);
296 fseek(fd, 0, SEEK_END);
298 fseek(fd, 0, SEEK_SET);
300 if(!(str=malloc(len*sizeof(char)))) {
301 fprintf(stderr, "Can't malloc space for '%s'\n", path);
305 r = fread(str, sizeof(char), len, fd);
314 /* ------------------------------------------------------------- */
319 unsigned int numberOfVertices;
320 unsigned int posStep;
321 unsigned int normStep;
325 float viewAngle = 0.0;
329 const char *vsSource = file2string("tnl.vert");
330 const char *fsSource = file2string("tnl.frag");
332 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
333 glShaderSource(vs, 1, &vsSource, NULL);
335 if(isShaderError(vs)) return 0;
337 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
338 glShaderSource(fs, 1, &fsSource, NULL);
340 if(isShaderError(fs)) return 0;
342 free((void*)vsSource);
343 free((void*)fsSource);
345 program = glCreateProgram();
346 glAttachShader(program, vs);
347 glAttachShader(program, fs);
349 glBindAttribLocation(program, POS_ARRAY, "vertPos");
350 glBindAttribLocation(program, NORMAL_ARRAY, "vertNormal");
351 /* vertNormal and vertTexCoord don't need to be bound here.. ? */
352 glBindAttribLocation(program, TEXCOORD_ARRAY, "vertTexCoord");
354 glLinkProgram(program);
355 if(isShaderError(program)) return 0;
357 glUseProgram(program);
359 glUniform3f(glGetUniformLocation(program, "frameLightDirection"), 1.0, 0.0, 1.0);
360 glUniform1i(glGetUniformLocation(program, "texture"), 0); /* 0 ?? */
367 glClearColor(1.0f, 1.0f, 0.0f, 0.0f);
369 glGenTextures(1, &texture);
370 glBindTexture(GL_TEXTURE_2D, texture);
372 GLuint* td = malloc(sizeof(GLuint)*TEX_SIZE*TEX_SIZE);
374 for(i=0; i<TEX_SIZE; i++)
375 for(j=0; j<TEX_SIZE; j++) {
376 GLuint col = (255L<<24) + ((255L-j*2)<<16) + ((255L-i)<<8) + (255L-i*2);
377 if ( ((i*j)/8) % 2 ) col = (GLuint) (255L<<24) + (255L<<16) + (0L<<8) + (255L);
378 td[j*TEX_SIZE+i] = col;
380 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, td);
381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
382 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
385 GLfloat trivertices[] = {
386 -0.4f,-0.4f,0.4f, // Pos
387 0.0f,0.0f,1.0f, // Normal
388 0.0f,0.0f, // TexCoord
390 0.4f,-0.0f,0.0f, // Pos
391 0.0f,0.0f,1.0f, // Normal
392 1.0f,0.0f, // TexCoord
394 0.0f,0.4f,0.4f, // Pos
395 0.5f,0.5f,0.5f, // Normal
396 0.5f,1.0f, // TexCoord
398 0.4f,0.0f,0.4f, // Pos
399 0.5f,0.5f,0.5f, // Normal
400 0.5f,0.0f, // TexCoord
402 0.4f,0.4f,0.4f, // Pos
403 0.0f,0.0f,1.0f, // Normal
404 0.0f,0.0f, // TexCoord
408 numberOfVertices = 4;
409 posStep = 3 * sizeof(GLfloat);
410 normStep = 3 * sizeof(GLfloat);
411 tcStep = 2 * sizeof(GLfloat);
412 stride = posStep + normStep + tcStep;
414 glGenBuffers(1, &vbo);
415 glBindBuffer(GL_ARRAY_BUFFER, vbo);
416 glBufferData(GL_ARRAY_BUFFER, numberOfVertices * stride, trivertices, GL_STATIC_DRAW);
417 glBindBuffer(GL_ARRAY_BUFFER, 0);
422 int drawStuff(int width, int height)
424 glViewport(0, 0, width, height);
425 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
427 float TransRotScaleVerticeMatrix[] = {
428 cos(angle), 0, sin(angle), 0,
430 -sin(angle), 0, cos(angle), 0,
434 float ModelViewProjectionMatrix[] = {
435 cos(viewAngle), 0, sin(viewAngle), 0,
437 -sin(viewAngle), 0, cos(viewAngle), 0,
441 float TransRotScaleNormalMatrix[] = {
442 cos(angle), 0, sin(angle),
444 -sin(angle), 0, cos(angle)
447 glUniformMatrix4fv(glGetUniformLocation(program, "frameTRSV"), 1, GL_FALSE, TransRotScaleVerticeMatrix);
448 glUniformMatrix4fv(glGetUniformLocation(program, "frameMVP"), 1, GL_FALSE, ModelViewProjectionMatrix);
449 glUniformMatrix3fv(glGetUniformLocation(program, "frameTRSN"), 1, GL_FALSE, TransRotScaleNormalMatrix);
452 glBindBuffer(GL_ARRAY_BUFFER, vbo);
454 glEnableVertexAttribArray(POS_ARRAY);
455 glVertexAttribPointer(POS_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, 0);
457 glEnableVertexAttribArray(NORMAL_ARRAY);
458 glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, (void*)posStep );
460 glEnableVertexAttribArray(TEXCOORD_ARRAY);
461 glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, stride, (void*)(posStep + normStep) );
463 glDrawArrays(GL_TRIANGLE_STRIP, 0, numberOfVertices);
465 glBindBuffer(GL_ARRAY_BUFFER, 0);
467 eglSwapBuffers(eglDisplay, eglSurface);
471 return !isEGLError("drawStuff");
475 glDeleteTextures(1, &texture);
476 glDeleteBuffers(1, &vbo);
477 glDeleteProgram(program);
482 /* ------------------------------------------------------------- */
484 #include "X11/Xutil.h"
486 Window x11Window = 0;
487 Display* x11Display = 0;
489 XVisualInfo* x11Visual = 0;
490 Colormap x11Colormap = 0;
492 int getX11Display(int windowwidth, int windowheight)
494 x11Display = XOpenDisplay(0);
497 printf("Error: Unable to open X display\n");
501 x11Screen = XDefaultScreen(x11Display);
502 Window rootWindow = RootWindow(x11Display, x11Screen);
503 int depth = DefaultDepth(x11Display, x11Screen);
504 x11Visual = malloc(sizeof(XVisualInfo));
505 XMatchVisualInfo(x11Display, x11Screen, depth, TrueColor, x11Visual);
508 printf("Error: Unable to acquire visual\n");
512 x11Colormap = XCreateColormap(x11Display, rootWindow, x11Visual->visual, AllocNone);
513 XSetWindowAttributes XSWA;
514 XSWA.colormap = x11Colormap;
515 XSWA.event_mask = StructureNotifyMask | ExposureMask |
516 ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
517 unsigned int cwmask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
519 x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
520 0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
521 XMapWindow(x11Display, x11Window);
524 eglX11Display = (EGLNativeDisplayType)x11Display;
525 eglX11Window = (EGLNativeWindowType) x11Window;
532 if(x11Window) XDestroyWindow(x11Display, x11Window);
533 if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
534 if(x11Display) XCloseDisplay( x11Display);
539 int nm = XPending(x11Display);
541 for(m=0; m< nm; m++) {
543 XNextEvent(x11Display, &event);
555 /* ------------------------------------------------------------- */