Actual source code: openglops.c
petsc-3.6.1 2015-08-06
2: /*
3: Defines the operations for the OpenGL PetscDraw implementation.
5: The eventual plan is to have a window system independent portion (that only uses gl...() routines) plus
6: several implementations for different Window interfaces:
7: -- glut (implmented)
8: -- Apple IOS EAGLContext https://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithOpenGLESContexts/WorkingwithOpenGLESContexts.html#//apple_ref/doc/uid/TP40008793-CH2-SW1
9: -- Apple NSOpenGLView http://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/OpenGL-MacProgGuide/opengl_pg_concepts/opengl_pg_concepts.html#//apple_ref/doc/uid/TP40001987-CH208-SW1
10: -- Apple CGLContextObj http://developer.apple.com/library/mac/#documentation/graphicsimaging/Reference/CGL_OpenGL/Reference/reference.html#//apple_ref/doc/uid/TP40001186
11: */
13: #include <petsc/private/drawimpl.h> /*I "petscsys.h" I*/
14: #if defined(PETSC_HAVE_OPENGLES)
15: #import <UIKit/UIKit.h>
16: #import <GLKit/GLKit.h>
17: #import <OpenGLES/EAGLDrawable.h>
18: #import <OpenGLES/ES2/gl.h>
19: #elif defined(PETSC_HAVE_GLUT)
20: #if defined(__APPLE__) || defined(MACOSX)
21: #include <AvailabilityMacros.h>
22: #include <OpenGL/gl.h>
23: #include <OpenGL/glu.h>
24: #else
25: #include <GL/gl.h>
26: #include <GL/glu.h>
27: #endif
28: #endif
31: /*
32: These macros transform from the users coordinates to the OpenGL coordinates of -1,-1 to 1,1.
33: */
34: #define XTRANS(draw,x) (-1.0 + 2.0*((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
35: #define YTRANS(draw,y) (-1.0 + 2.0*((draw)->port_yl + (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
37: /*
38: These macros transform from the users coordinates to pixel coordinates.
39: */
40: #define XPTRANS(draw,win,x) (int)(((win)->w)*((draw)->port_xl + (((x - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl))))
41: #define YPTRANS(draw,win,y) (int)(((win)->h)*(1.0-(draw)->port_yl - (((y - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl))))
43: static unsigned char rcolor[256],gcolor[256],bcolor[256];
46: static PetscErrorCode InitializeColors(void)
47: {
51: rcolor[PETSC_DRAW_WHITE] = 255;
52: gcolor[PETSC_DRAW_WHITE] = 255;
53: bcolor[PETSC_DRAW_WHITE] = 255;
54: rcolor[PETSC_DRAW_BLACK] = 0;
55: gcolor[PETSC_DRAW_BLACK] = 0;
56: bcolor[PETSC_DRAW_BLACK] = 0;
57: rcolor[PETSC_DRAW_RED] = 255;
58: gcolor[PETSC_DRAW_RED] = 0;
59: bcolor[PETSC_DRAW_RED] = 0;
60: rcolor[PETSC_DRAW_GREEN] = 0;
61: gcolor[PETSC_DRAW_GREEN] = 128;
62: bcolor[PETSC_DRAW_GREEN] = 0;
63: rcolor[PETSC_DRAW_CYAN] = 0;
64: gcolor[PETSC_DRAW_CYAN] = 139;
65: bcolor[PETSC_DRAW_CYAN] = 139;
66: rcolor[PETSC_DRAW_BLUE] = 0;
67: gcolor[PETSC_DRAW_BLUE] = 0;
68: bcolor[PETSC_DRAW_BLUE] = 255;
69: rcolor[PETSC_DRAW_MAGENTA] = 255;
70: gcolor[PETSC_DRAW_MAGENTA] = 0;
71: bcolor[PETSC_DRAW_MAGENTA] = 255;
72: rcolor[PETSC_DRAW_AQUAMARINE] = 127;
73: gcolor[PETSC_DRAW_AQUAMARINE] = 255;
74: bcolor[PETSC_DRAW_AQUAMARINE] = 212;
75: rcolor[PETSC_DRAW_FORESTGREEN] = 34;
76: gcolor[PETSC_DRAW_FORESTGREEN] = 139;
77: bcolor[PETSC_DRAW_FORESTGREEN] = 34;
78: rcolor[PETSC_DRAW_ORANGE] = 255;
79: gcolor[PETSC_DRAW_ORANGE] = 165;
80: bcolor[PETSC_DRAW_ORANGE] = 0;
81: rcolor[PETSC_DRAW_VIOLET] = 238;
82: gcolor[PETSC_DRAW_VIOLET] = 130;
83: bcolor[PETSC_DRAW_VIOLET] = 238;
84: rcolor[PETSC_DRAW_BROWN] = 165;
85: gcolor[PETSC_DRAW_BROWN] = 42;
86: bcolor[PETSC_DRAW_BROWN] = 42;
87: rcolor[PETSC_DRAW_PINK] = 255;
88: gcolor[PETSC_DRAW_PINK] = 192;
89: bcolor[PETSC_DRAW_PINK] = 203;
90: rcolor[PETSC_DRAW_CORAL] = 255;
91: gcolor[PETSC_DRAW_CORAL] = 127;
92: bcolor[PETSC_DRAW_CORAL] = 80;
93: rcolor[PETSC_DRAW_GRAY] = 128;
94: gcolor[PETSC_DRAW_GRAY] = 128;
95: bcolor[PETSC_DRAW_GRAY] = 128;
96: rcolor[PETSC_DRAW_YELLOW] = 255;
97: gcolor[PETSC_DRAW_YELLOW] = 255;
98: bcolor[PETSC_DRAW_YELLOW] = 0;
99: rcolor[PETSC_DRAW_GOLD] = 255;
100: gcolor[PETSC_DRAW_GOLD] = 215;
101: bcolor[PETSC_DRAW_GOLD] = 0;
102: rcolor[PETSC_DRAW_LIGHTPINK] = 255;
103: gcolor[PETSC_DRAW_LIGHTPINK] = 182;
104: bcolor[PETSC_DRAW_LIGHTPINK] = 193;
105: rcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 72;
106: gcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 209;
107: bcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 204;
108: rcolor[PETSC_DRAW_KHAKI] = 240;
109: gcolor[PETSC_DRAW_KHAKI] = 230;
110: bcolor[PETSC_DRAW_KHAKI] = 140;
111: rcolor[PETSC_DRAW_DIMGRAY] = 105;
112: gcolor[PETSC_DRAW_DIMGRAY] = 105;
113: bcolor[PETSC_DRAW_DIMGRAY] = 105;
114: rcolor[PETSC_DRAW_YELLOWGREEN] = 54;
115: gcolor[PETSC_DRAW_YELLOWGREEN] = 205;
116: bcolor[PETSC_DRAW_YELLOWGREEN] = 50;
117: rcolor[PETSC_DRAW_SKYBLUE] = 135;
118: gcolor[PETSC_DRAW_SKYBLUE] = 206;
119: bcolor[PETSC_DRAW_SKYBLUE] = 235;
120: rcolor[PETSC_DRAW_DARKGREEN] = 0;
121: gcolor[PETSC_DRAW_DARKGREEN] = 100;
122: bcolor[PETSC_DRAW_DARKGREEN] = 0;
123: rcolor[PETSC_DRAW_NAVYBLUE] = 0;
124: gcolor[PETSC_DRAW_NAVYBLUE] = 0;
125: bcolor[PETSC_DRAW_NAVYBLUE] = 128;
126: rcolor[PETSC_DRAW_SANDYBROWN] = 244;
127: gcolor[PETSC_DRAW_SANDYBROWN] = 164;
128: bcolor[PETSC_DRAW_SANDYBROWN] = 96;
129: rcolor[PETSC_DRAW_CADETBLUE] = 95;
130: gcolor[PETSC_DRAW_CADETBLUE] = 158;
131: bcolor[PETSC_DRAW_CADETBLUE] = 160;
132: rcolor[PETSC_DRAW_POWDERBLUE] = 176;
133: gcolor[PETSC_DRAW_POWDERBLUE] = 224;
134: bcolor[PETSC_DRAW_POWDERBLUE] = 230;
135: rcolor[PETSC_DRAW_DEEPPINK] = 255;
136: gcolor[PETSC_DRAW_DEEPPINK] = 20;
137: bcolor[PETSC_DRAW_DEEPPINK] = 147;
138: rcolor[PETSC_DRAW_THISTLE] = 216;
139: gcolor[PETSC_DRAW_THISTLE] = 191;
140: bcolor[PETSC_DRAW_THISTLE] = 216;
141: rcolor[PETSC_DRAW_LIMEGREEN] = 50;
142: gcolor[PETSC_DRAW_LIMEGREEN] = 205;
143: bcolor[PETSC_DRAW_LIMEGREEN] = 50;
144: rcolor[PETSC_DRAW_LAVENDERBLUSH] = 255;
145: gcolor[PETSC_DRAW_LAVENDERBLUSH] = 240;
146: bcolor[PETSC_DRAW_LAVENDERBLUSH] = 245;
147: rcolor[PETSC_DRAW_PLUM] = 221;
148: gcolor[PETSC_DRAW_PLUM] = 160;
149: bcolor[PETSC_DRAW_PLUM] = 221;
151: PetscDrawUtilitySetCmapHue(rcolor+PETSC_DRAW_BASIC_COLORS,gcolor+PETSC_DRAW_BASIC_COLORS,bcolor+PETSC_DRAW_BASIC_COLORS,256-PETSC_DRAW_BASIC_COLORS);
152: return(0);
153: }
155: static GLuint vertexshader,fragmentshader,shaderprogram;
158: static PetscErrorCode InitializeShader(void)
159: {
160: const char *vertexsource = "attribute vec2 position;\
161: attribute vec3 color; \
162: varying vec4 vColor;\
163: void main(void)\
164: {\
165: vColor = vec4(color,0.50);\
166: gl_Position = vec4(position,0.0,1.0);\
167: }\n";
168: #if defined(PETSC_HAVE_GLUT)
169: const char *fragmentsource = "varying vec4 vColor;\
170: void main (void)\
171: {\
172: gl_FragColor = vColor; \
173: }\n";
174: #else
175: const char *fragmentsource = "precision mediump float;\
176: varying vec4 vColor;\
177: void main (void)\
178: {\
179: gl_FragColor = vColor; \
180: }\n";
181: #endif
182: int isCompiled_VS, isCompiled_FS;
183: int isLinked;
184: GLenum err;
187: /* http://www.opengl.org/wiki/OpenGL_Shading_Language */
188: /* Create an empty vertex shader handle */
189: vertexshader = glCreateShader(GL_VERTEX_SHADER);
191: /* Send the vertex shader source code to GL */
192: /* Note that the source code is NULL character terminated. */
193: /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
194: glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
196: /* Compile the vertex shader */
197: glCompileShader(vertexshader);
198: glGetShaderiv(vertexshader, GL_COMPILE_STATUS, &isCompiled_VS);
199: if (isCompiled_VS == GL_FALSE) {
201: int maxLength;
202: char *vertexInfoLog;
203: glGetShaderiv(vertexshader, GL_INFO_LOG_LENGTH, &maxLength);
204: PetscMalloc1(maxLength,&vertexInfoLog);
205: glGetShaderInfoLog(vertexshader, maxLength, &maxLength, vertexInfoLog);
206: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile vertex shader %s",vertexInfoLog);
207: }
209: /* Create an empty fragment shader handle */
210: fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
212: /* Send the fragment shader source code to GL */
213: /* Note that the source code is NULL character terminated. */
214: /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
215: glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);
217: /* Compile the fragment shader */
218: glCompileShader(fragmentshader);
219: glGetShaderiv(fragmentshader, GL_COMPILE_STATUS, &isCompiled_FS);
220: if (isCompiled_FS == GL_FALSE) {
222: int maxLength;
223: char *fragmentInfoLog;
224: glGetShaderiv(fragmentshader, GL_INFO_LOG_LENGTH, &maxLength);
225: PetscMalloc1(maxLength,&fragmentInfoLog);
226: glGetShaderInfoLog(fragmentshader, maxLength, &maxLength, fragmentInfoLog);
227: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile fragment shader %s",fragmentInfoLog);
228: }
230: /* If we reached this point it means the vertex and fragment shaders compiled and are syntax error free. */
231: /* We must link them together to make a GL shader program */
232: /* GL shader programs are monolithic. It is a single piece made of 1 vertex shader and 1 fragment shader. */
233: /* Assign our program handle a "name" */
234: shaderprogram = glCreateProgram();
236: /* Attach our shaders to our program */
237: glAttachShader(shaderprogram, vertexshader);
238: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
239: glAttachShader(shaderprogram, fragmentshader);
240: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
242: glBindAttribLocation(shaderprogram,0,"position");
243: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
244: glBindAttribLocation(shaderprogram,1,"color");
245: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
247: /* Link our program */
248: /* At this stage, the vertex and fragment programs are inspected, optimized and a binary code is generated for the shader. */
249: /* The binary code is uploaded to the GPU, if there is no error. */
250: glLinkProgram(shaderprogram);
252: /* Again, we must check and make sure that it linked. If it fails, it would mean either there is a mismatch between the vertex */
253: /* and fragment shaders. It might be that you have surpassed your GPU's abilities. Perhaps too many ALU operations or */
254: /* too many texel fetch instructions or too many interpolators or dynamic loops. */
256: glGetProgramiv(shaderprogram, GL_LINK_STATUS, &isLinked);
257: if (isLinked == GL_FALSE) {
258: /*
259: char *shaderProgramInfoLog;
260: glGetProgramiv(shaderprogram, GL_INFO_LOG_LENGTH, &maxLength);
261: shaderProgramInfoLog = new char[maxLength];
262: glGetProgramInfoLog(shaderprogram, maxLength, &maxLength, shaderProgramInfoLog);
263: free(shaderProgramInfoLog);
264: */
265: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile fragment shader");
266: }
268: /* In your rendering code, you just need to call glUseProgram, call the various glUniform** to update your uniforms */
269: /* and then render. */
270: /* Load the shader into the rendering pipeline */
271: glUseProgram(shaderprogram);
272: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
273: return(0);
274: }
278: /*
279: This is currently all wrong, there is actually a separate shader for each window
280: so they cannot be stored as global
281: */
282: static PetscErrorCode FinalizeShader(void)
283: {
285: /* When the user shuts down your program, you should deallocate all your GL resources. */
286: /* Unbind your shader. */
287: glUseProgram(0);
288: /* Let's detach */
289: glDetachShader(shaderprogram, vertexshader);
290: glDetachShader(shaderprogram, fragmentshader);
291: /* Delete the shaders */
292: glDeleteShader(vertexshader);
293: glDeleteShader(fragmentshader);
294: /* Delete the shader object */
295: glDeleteProgram(shaderprogram);
296: return(0);
297: }
299: extern PetscErrorCode PetscDrawClear_OpenGL_Base(PetscDraw);
301: #if defined(PETSC_HAVE_GLUT)
302: #include <GLUT/glut.h>
303: typedef struct {
304: int win; /* OpenGL GLUT window identifier */
305: int x,y,w,h; /* Size and location of window */
306: } PetscDraw_OpenGL;
308: static int currentwindow = -1;
309: PETSC_STATIC_INLINE PetscErrorCode OpenGLWindow(PetscDraw_OpenGL *win)
310: {
311: if (win->win == currentwindow) return 0;
312: currentwindow = win->win;
313: glutSetWindow(win->win);
314: return 0;
315: }
317: PETSC_STATIC_INLINE PetscErrorCode OpenGLString(float x,float y, const char *str,size_t len,int icolor)
318: {
319: PetscInt i;
321: glColor3ub(rcolor[icolor],gcolor[icolor],bcolor[icolor]);
322: glRasterPos2f(x, y);
323: for (i = 0; i < len; i++) glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str[i]);
324: return 0;
325: }
329: PetscErrorCode PetscDrawClear_OpenGL(PetscDraw draw)
330: {
334: PetscDrawClear_OpenGL_Base(draw);
335: return(0);
336: }
340: static PetscErrorCode PetscDrawGetPopup_OpenGL(PetscDraw draw,PetscDraw *popup)
341: {
345: PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,popup);
346: PetscDrawSetType(*popup,((PetscObject)draw)->type_name);
348: draw->popup = *popup;
349: return(0);
350: }
354: static PetscErrorCode PetscDrawStringVertical_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
355: {
356: PetscErrorCode ierr;
357: float xx,yy;
358: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
359: PetscReal tw,th;
360: size_t i,n;
363: OpenGLWindow(win);
364: PetscStrlen(chrs,&n);
365: PetscDrawStringGetSize(draw,&tw,&th);
366: xx = XTRANS(draw,x);
367: for (i=0; i<n; i++) {
368: yy = YTRANS(draw,y-th*i);
369: OpenGLString(xx,yy,chrs+i,1,c);
370: }
371: return(0);
372: }
376: static PetscErrorCode PetscDrawString_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
377: {
378: PetscErrorCode ierr;
379: float xx,yy;
380: size_t len;
381: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
382: char *substr;
383: PetscToken token;
386: xx = XTRANS(draw,x);
387: yy = YTRANS(draw,y);
388: OpenGLWindow(win);
390: PetscTokenCreate(chrs,'\n',&token);
391: PetscTokenFind(token,&substr);
392: PetscStrlen(substr,&len);
393: OpenGLString(xx,yy,substr,len,c);
394: PetscTokenFind(token,&substr);
395: while (substr) {
396: yy += 16;
397: PetscStrlen(substr,&len);
398: OpenGLString(xx,yy,substr,len,c);
399: PetscTokenFind(token,&substr);
400: }
401: PetscTokenDestroy(&token);
402: return(0);
403: }
407: static PetscErrorCode PetscDrawSetTitle_OpenGL(PetscDraw draw,const char title[])
408: {
409: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
410: PetscErrorCode ierr;
413: OpenGLWindow(win);
414: glutSetWindowTitle(title);
415: return(0);
416: }
420: static PetscErrorCode PetscDrawDestroy_OpenGL(PetscDraw draw)
421: {
422: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
423: PetscErrorCode ierr;
426: PetscDrawSynchronizedClear(draw);
427: PetscDrawDestroy(&draw->popup);
428: glutDestroyWindow(win->win);
429: PetscFree(draw->data);
430: return(0);
431: }
435: static PetscErrorCode PetscDrawFlush_OpenGL(PetscDraw draw)
436: {
437: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
438: PetscErrorCode ierr;
441: OpenGLWindow(win);
442: glutCheckLoop();
443: glFinish();
444: return(0);
445: }
449: static PetscErrorCode PetscDrawStringGetSize_OpenGL(PetscDraw draw,PetscReal *x,PetscReal *y)
450: {
451: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
452: PetscInt w;
453: PetscErrorCode ierr;
456: OpenGLWindow(win);
457: w = glutBitmapWidth(GLUT_BITMAP_8_BY_13,'W');
458: if (x) *x = w*(draw->coor_xr - draw->coor_xl)/((win->w)*(draw->port_xr - draw->port_xl));
459: if (y) *y = (13./8.0)*w*(draw->coor_yr - draw->coor_yl)/((win->h)*(draw->port_yr - draw->port_yl));
460: return(0);
461: }
465: static PetscErrorCode PetscDrawResizeWindow_OpenGL(PetscDraw draw,int w,int h)
466: {
467: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
468: PetscErrorCode ierr;
471: OpenGLWindow(win);
472: glutReshapeWindow(w,h);
473: PetscDrawFlush(draw);
474: PetscDrawCheckResizedWindow(draw);
475: return(0);
476: }
478: static PetscBool resized = PETSC_FALSE;
482: static PetscErrorCode PetscDrawCheckResizedWindow_OpenGL(PetscDraw draw)
483: {
487: if (!resized) return(0);
488: resized = PETSC_FALSE;
489: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
490: PetscDrawClear(draw);
491: return(0);
492: }
494: typedef struct {
495: int button,x,y;
496: } OpenGLButton;
497: static OpenGLButton Mouse;
501: static PetscErrorCode PetscDrawGetMouseButton_OpenGL(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
502: {
503: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
504: int px,py;
507: while (Mouse.button == -1) glutCheckLoop();
509: *button = (PetscDrawButton)(Mouse.button + 1);
510: px = Mouse.x;
511: py = Mouse.y;
512: Mouse.button = -1;
514: if (x_phys) *x_phys = ((double)px)/((double)win->w);
515: if (y_phys) *y_phys = 1.0 - ((double)py)/((double)win->h);
517: if (x_user) *x_user = draw->coor_xl + ((((double)px)/((double)win->w)-draw->port_xl))*(draw->coor_xr - draw->coor_xl)/(draw->port_xr - draw->port_xl);
518: if (y_user) *y_user = draw->coor_yl + ((1.0 - ((double)py)/((double)win->h)-draw->port_yl))*(draw->coor_yr - draw->coor_yl)/(draw->port_yr - draw->port_yl);
519: return(0);
520: }
521: #elif defined(PETSC_HAVE_OPENGLES)
522: typedef struct {
523: GLint win; /* not currently used */
524: int w,h; /* width and height in pixels */
525: int view;
526: } PetscDraw_OpenGL;
528: static GLKView *globalGLKView[10] = {0,0,0,0,0,0,0,0,0,0};
529: static int globalGLKViewUsed[10] = {0,0,0,0,0,0,0,0,0,0};
530: PETSC_STATIC_INLINE PetscErrorCode OpenGLWindow(PetscDraw_OpenGL *win)
531: {
532: return 0;
533: }
537: static PetscErrorCode PetscDrawClear_OpenGL(PetscDraw draw)
538: {
539: PetscErrorCode ierr;
540: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
543: /* remove all UIText added to window */
544: for (UIView *view in [globalGLKView[win->view] subviews]) {[view removeFromSuperview];}
545: PetscDrawClear_OpenGL_Base(draw);
546: return(0);
547: }
551: static PetscErrorCode PetscDrawGetPopup_OpenGL(PetscDraw draw,PetscDraw *popup)
552: {
556: *popup = NULL;
557: return(0);
558: }
562: static PetscErrorCode PetscDrawString_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
563: {
564: PetscErrorCode ierr;
565: float xx,yy;
566: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
567: UILabel *yourLabel;
570: OpenGLWindow(win);
571: xx = XPTRANS(draw,win,x);
572: yy = YPTRANS(draw,win,y);
573: NSLog(@"Draw string start");
574: yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(xx, yy, 300, 20)];
575: [yourLabel setTextColor:[UIColor colorWithRed:rcolor[c]/255.0 green:gcolor[c]/255.0 blue:rcolor[c]/255.0 alpha:1.0]];
576: [yourLabel setText: [[NSString alloc] initWithCString:chrs encoding:NSMacOSRomanStringEncoding]];
577: [yourLabel setBackgroundColor:[UIColor clearColor]];
578: /* [yourLabel setFont:[UIFont fontWithName: @"Trebuchet MS" size: 14.0f]]; */
579: [globalGLKView[win->view] addSubview:yourLabel];
580: NSLog(@"Draw string end");
581: return(0);
582: }
584: /*
585: I don't understand the rotation. It seems to maybe rotate from the middle of the width?
587: It would be nice if the frame could be made to match the text length automatically
589: This makes src/sys/draw/examples/tests/ex3.c look good but may be terrible for other locations
590: */
593: static PetscErrorCode PetscDrawStringVertical_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
594: {
595: PetscErrorCode ierr;
596: float xx,yy, w = 100,h = 20;
597: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
598: UILabel *yourLabel;
601: OpenGLWindow(win);
602: xx = XPTRANS(draw,win,x);
603: yy = YPTRANS(draw,win,y);
604: NSLog(@"Draw string vertical start");
605: yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, w, h)];
606: [yourLabel setTextColor:[UIColor colorWithRed:rcolor[c]/255.0 green:gcolor[c]/255.0 blue:rcolor[c]/255.0 alpha:1.0]];
607: [yourLabel setText: [[NSString alloc] initWithCString:chrs encoding:NSMacOSRomanStringEncoding]];
608: [yourLabel setBackgroundColor:[UIColor clearColor]];
609: [yourLabel setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(-PETSC_PI / 2),-w/2.0-yy,-h+xx)];
610: /* [yourLabel setFont:[UIFont fontWithName: @"Trebuchet MS" size: 14.0f]]; */
611: [globalGLKView[win->view] addSubview:yourLabel];
612: NSLog(@"Draw string vertical end");
613: return(0);
614: }
618: static PetscErrorCode PetscDrawSetTitle_OpenGL(PetscDraw draw,const char title[])
619: {
620: return 0;
621: }
624: static PetscErrorCode PetscDrawDestroy_OpenGL(PetscDraw draw)
625: {
626: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
627: PetscErrorCode ierr;
628: PetscInt i;
631: globalGLKViewUsed[win->view] = 0;
632: PetscFree(draw->data);
633: return(0);
634: return(0);
635: }
638: static PetscErrorCode PetscDrawFlush_OpenGL(PetscDraw draw)
639: {
640: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
642: GLenum err;
643: glFlush();
644: err = glGetError();
645: if (err != GL_NO_ERROR) {
646: NSLog(@"GL error detected glFlush()");
647: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to flush OpenGL Error Code %d",err);
648: }
649: [globalGLKView[win->view] display];
650: NSLog(@"Completed display in PetscDrawFlush()");
651: return 0;
652: }
655: static PetscErrorCode PetscDrawStringGetSize_OpenGL(PetscDraw draw,PetscReal *x,PetscReal *y)
656: {
657: float w = .02;
658: if (x) *x = w*(draw->coor_xr - draw->coor_xl)/(draw->port_xr - draw->port_xl);
659: if (y) *y = (13./8.0)*w*(draw->coor_yr - draw->coor_yl)/(draw->port_yr - draw->port_yl);
660: return 0;
661: }
664: static PetscErrorCode PetscDrawResizeWindow_OpenGL(PetscDraw draw,int w,int h)
665: {
666: return 0;
667: }
670: static PetscErrorCode PetscDrawCheckResizedWindow_OpenGL(PetscDraw draw)
671: {
672: return 0;
673: }
676: static PetscErrorCode PetscDrawGetMouseButton_OpenGL(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
677: {
678: return 0;
679: }
680: #endif
682: /* -----------------------------------------------------------------------*/
685: static PetscErrorCode PetscDrawSynchronizedFlush_OpenGL(PetscDraw draw)
686: {
690: /* currently on sequential support */
691: PetscDrawFlush(draw);
692: return(0);
693: }
697: PetscErrorCode PetscDrawClear_OpenGL_Base(PetscDraw draw)
698: {
699: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
700: PetscErrorCode ierr;
701: float xl,yl,xr,yr;
702: GLfloat vertices[12];
703: GLfloat colors[18];
704: GLuint positionBufferObject;
705: GLuint colorBufferObject;
706: GLenum err;
709: OpenGLWindow(win);
710: xl = -1.0 + 2.0*((draw)->port_xl);
711: xr = -1.0 + 2.0*((draw)->port_xr);
712: yl = -1.0 + 2.0*((draw)->port_yl);
713: yr = -1.0 + 2.0*((draw)->port_yr);
715: vertices[0] = xl;
716: vertices[1] = yl;
717: vertices[2] = xr;
718: vertices[3] = yl;
719: vertices[4] = xl;
720: vertices[5] = yr;
722: vertices[6] = xl;
723: vertices[7] = yr;
724: vertices[8] = xr;
725: vertices[9] = yr;
726: vertices[10] = xr;
727: vertices[11] = yl;
729: colors[0] = 1.0; colors[1] = 1.0; colors[2] = 1.0;
730: colors[3] = 1.0; colors[4] = 1.0; colors[5] = 1.0;
731: colors[6] = 1.0; colors[7] = 1.0; colors[8] = 1.0;
733: colors[9] = 1.0; colors[10] = 1.0; colors[11] = 1.0;
734: colors[12] = 1.0; colors[13] = 1.0; colors[14] = 1.0;
735: colors[15] = 1.0; colors[16] = 1.0; colors[17] = 1.0;
737: glGenBuffers(1, &positionBufferObject);
738: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
739: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
740: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
741: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
742: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
743: glEnableVertexAttribArray(0);
744: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
745: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
746: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
748: glGenBuffers(1, &colorBufferObject);
749: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
750: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
751: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
752: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
753: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
754: glEnableVertexAttribArray(1);
755: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
756: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
757: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
759: glDrawArrays(GL_TRIANGLES, 0, 6);
760: glDisableVertexAttribArray(0);
761: glDisableVertexAttribArray(1);
762: glDeleteBuffers(1, &positionBufferObject);
763: glDeleteBuffers(1, &colorBufferObject);
764: PetscDrawFlush(draw);
765: return(0);
766: }
770: static PetscErrorCode PetscDrawSynchronizedClear_OpenGL(PetscDraw draw)
771: {
775: /* currently only sequential support */
776: PetscDrawClear(draw);
777: return(0);
778: }
782: static PetscErrorCode PetscDrawPoint_OpenGL(PetscDraw draw,PetscReal xl,PetscReal yl,int cl)
783: {
784: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
785: GLfloat vertices[2],colors[3];
786: PetscErrorCode ierr;
787: GLuint positionBufferObject;
788: GLuint colorBufferObject;
789: GLenum err;
792: vertices[0] = XTRANS(draw,xl);
793: vertices[1] = YTRANS(draw,yl);
794: colors[0] = rcolor[cl]/255.0; colors[1] = gcolor[cl]/255.0; colors[2] = bcolor[cl]/255.0;
796: OpenGLWindow(win);
797: glGenBuffers(1, &positionBufferObject);
798: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
799: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
800: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
801: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
802: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
803: glEnableVertexAttribArray(0);
804: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
805: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
806: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
808: glGenBuffers(1, &colorBufferObject);
809: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
810: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
811: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
812: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
813: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
814: glEnableVertexAttribArray(1);
815: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
816: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
817: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
819: glDrawArrays(GL_POINTS, 0, 2);
820: glDisableVertexAttribArray(0);
821: glDisableVertexAttribArray(1);
822: glDeleteBuffers(1, &positionBufferObject);
823: glDeleteBuffers(1, &colorBufferObject);
824: return(0);
825: }
829: static PetscErrorCode PetscDrawLine_OpenGL(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
830: {
831: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
832: GLfloat linevertices[4],colors[6];
833: PetscErrorCode ierr;
834: GLenum err;
835: GLuint positionBufferObject;
836: GLuint colorBufferObject;
840: linevertices[0] = XTRANS(draw,xl);
841: linevertices[2] = XTRANS(draw,xr);
842: linevertices[1] = YTRANS(draw,yl);
843: linevertices[3] = YTRANS(draw,yr);
844: if (linevertices[0] == linevertices[2] && linevertices[1] == linevertices[3]) return(0);
845: colors[0] = rcolor[cl]/255.0; colors[1] = gcolor[cl]/255.0; colors[2] = bcolor[cl]/255.0;
846: colors[3] = rcolor[cl]/255.0; colors[4] = gcolor[cl]/255.0; colors[5] = bcolor[cl]/255.0;
848: OpenGLWindow(win);
849: /* http://arcsynthesis.org/gltut/Basics/Tutorial%2001.html */
850: glGenBuffers(1, &positionBufferObject);
851: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
852: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
853: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
854: glBufferData(GL_ARRAY_BUFFER, sizeof(linevertices), linevertices, GL_STATIC_DRAW);
855: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
856: glEnableVertexAttribArray(0);
857: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
858: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
859: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
861: glGenBuffers(1, &colorBufferObject);
862: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
863: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
864: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
865: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
866: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
867: glEnableVertexAttribArray(1);
868: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
869: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
870: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
872: glDrawArrays(GL_LINES, 0, 2);
873: glDisableVertexAttribArray(0);
874: glDisableVertexAttribArray(1);
875: glDeleteBuffers(1, &positionBufferObject);
876: glDeleteBuffers(1, &colorBufferObject);
877: return(0);
878: }
882: static PetscErrorCode PetscDrawTriangle_OpenGL(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,PetscReal Y2,PetscReal X3,PetscReal Y3,int c1,int c2,int c3)
883: {
884: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
885: PetscErrorCode ierr;
886: GLfloat vertices[6],colors[9];
887: GLenum err;
888: GLuint positionBufferObject;
889: GLuint colorBufferObject;
892: vertices[0] = XTRANS(draw,X1);
893: vertices[1] = YTRANS(draw,Y_1);
894: vertices[2] = XTRANS(draw,X2);
895: vertices[3] = YTRANS(draw,Y2);
896: vertices[4] = XTRANS(draw,X3);
897: vertices[5] = YTRANS(draw,Y3);
898: colors[0] = rcolor[c1]/255.0; colors[1] = gcolor[c1]/255.0; colors[2] = bcolor[c1]/255.0;
899: colors[3] = rcolor[c2]/255.0; colors[4] = gcolor[c2]/255.0; colors[5] = bcolor[c2]/255.0;
900: colors[6] = rcolor[c3]/255.0; colors[7] = gcolor[c3]/255.0; colors[8] = bcolor[c3]/255.0;
902: OpenGLWindow(win);
903: glGenBuffers(1, &positionBufferObject);
904: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
905: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
906: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
907: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
908: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
909: glEnableVertexAttribArray(0);
910: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
911: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
912: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
914: glGenBuffers(1, &colorBufferObject);
915: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
916: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
917: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
918: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
919: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
920: glEnableVertexAttribArray(1);
921: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
922: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
923: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
925: glDrawArrays(GL_TRIANGLES, 0, 3);
926: glDisableVertexAttribArray(0);
927: glDisableVertexAttribArray(1);
928: glDeleteBuffers(1, &positionBufferObject);
929: glDeleteBuffers(1, &colorBufferObject);
930: return(0);
931: }
935: static PetscErrorCode PetscDrawRectangle_OpenGL(PetscDraw draw,PetscReal Xl,PetscReal Yl,PetscReal Xr,PetscReal Yr,int c1,int c2,int c3,int c4)
936: {
937: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
938: PetscErrorCode ierr;
939: GLfloat vertices[12],colors[18];
940: float x1,y_1,x2,y2;
941: GLuint positionBufferObject;
942: GLuint colorBufferObject;
943: GLenum err;
946: x1 = XTRANS(draw,Xl);
947: y_1 = YTRANS(draw,Yl);
948: x2 = XTRANS(draw,Xr);
949: y2 = YTRANS(draw,Yr);
951: OpenGLWindow(win);
953: vertices[0] = x1; colors[0] = rcolor[c1]/255.0; colors[1] = gcolor[c1]/255.0; colors[2] = bcolor[c1]/255.0;
954: vertices[1] = y_1;
955: vertices[2] = x2;colors[3] = rcolor[c2]/255.0; colors[4] = gcolor[c2]/255.0; colors[5] = bcolor[c2]/255.0;
956: vertices[3] = y_1;
957: vertices[4] = x1;colors[6] = rcolor[c4]/255.0; colors[7] = gcolor[c4]/255.0; colors[8] = bcolor[c4]/255.0;
958: vertices[5] = y2;
960: vertices[6] = x1;colors[9] = rcolor[c4]/255.0; colors[10] = gcolor[c4]/255.0; colors[11] = bcolor[c4]/255.0;
961: vertices[7] = y2;
962: vertices[8] = x2;colors[12] = rcolor[c3]/255.0; colors[13] = gcolor[c3]/255.0; colors[14] = bcolor[c3]/255.0;
963: vertices[9] = y2;
964: vertices[10] = x2;colors[15] = rcolor[c2]/255.0; colors[16] = gcolor[c2]/255.0; colors[17] = bcolor[c2]/255.0;
965: vertices[11] = y_1;
967: glGenBuffers(1, &positionBufferObject);
968: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
969: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
970: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
971: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
972: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
973: glEnableVertexAttribArray(0);
974: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
975: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
976: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
978: glGenBuffers(1, &colorBufferObject);
979: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
980: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
981: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
982: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
983: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
984: glEnableVertexAttribArray(1);
985: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
986: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
987: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
989: glDrawArrays(GL_TRIANGLES, 0, 6);
990: glDisableVertexAttribArray(0);
991: glDisableVertexAttribArray(1);
992: glDeleteBuffers(1, &positionBufferObject);
993: glDeleteBuffers(1, &colorBufferObject);
994: return(0);
995: }
1000: static PetscErrorCode PetscDrawPause_OpenGL(PetscDraw draw)
1001: {
1005: if (draw->pause > 0) PetscSleep(draw->pause);
1006: else if (draw->pause == -1) {
1007: PetscDrawButton button;
1008: PetscMPIInt rank;
1009: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
1010: if (!rank) {
1011: PetscDrawGetMouseButton(draw,&button,0,0,0,0);
1012: if (button == PETSC_BUTTON_CENTER) draw->pause = 0;
1013: }
1014: MPI_Bcast(&draw->pause,1,MPI_INT,0,PetscObjectComm((PetscObject)draw));
1015: }
1016: return(0);
1017: }
1020: static struct _PetscDrawOps DvOps = { 0,
1021: PetscDrawFlush_OpenGL,
1022: PetscDrawLine_OpenGL,
1023: 0,
1024: 0,
1025: PetscDrawPoint_OpenGL,
1026: 0,
1027: PetscDrawString_OpenGL,
1028: PetscDrawStringVertical_OpenGL,
1029: 0, /* PetscDrawStringSetSize_OpenGL,*/
1030: PetscDrawStringGetSize_OpenGL,
1031: 0, /* PetscDrawSetViewport_OpenGL,*/
1032: PetscDrawClear_OpenGL,
1033: PetscDrawSynchronizedFlush_OpenGL,
1034: PetscDrawRectangle_OpenGL,
1035: PetscDrawTriangle_OpenGL,
1036: 0, /* PetscDrawEllipse_OpenGL,*/
1037: PetscDrawGetMouseButton_OpenGL,
1038: PetscDrawPause_OpenGL,
1039: PetscDrawSynchronizedClear_OpenGL,
1040: 0,
1041: 0,
1042: PetscDrawGetPopup_OpenGL,
1043: PetscDrawSetTitle_OpenGL,
1044: PetscDrawCheckResizedWindow_OpenGL,
1045: PetscDrawResizeWindow_OpenGL,
1046: PetscDrawDestroy_OpenGL,
1047: 0,
1048: 0, /* PetscDrawGetSingleton_OpenGL,*/
1049: 0, /* PetscDrawRestoreSingleton_OpenGL,*/
1050: 0,
1051: 0,
1052: 0,
1053: PetscDrawLine_OpenGL};
1055: #if defined(PETSC_HAVE_GLUT)
1056: /* callbacks required by GLUT */
1057: static void display(void) {;}
1058: static void reshape(int width, int height)
1059: {
1060: glViewport(0, 0, width, height);
1061: resized = PETSC_TRUE;
1062: }
1063: static void mouse(int button, int state,int x, int y)
1064: {
1065: if (state == GLUT_UP) {
1066: Mouse.button = button;
1067: Mouse.x = x;
1068: Mouse.y = y;
1069: }
1070: }
1074: PETSC_EXTERN PetscErrorCode PetscDrawCreate_GLUT(PetscDraw draw)
1075: {
1076: PetscDraw_OpenGL *win;
1077: PetscErrorCode ierr;
1078: PetscInt xywh[4],osize = 4;
1079: int x = draw->x,y = draw->y,w = draw->w,h = draw->h;
1080: static int xavailable = 0,yavailable = 0,xmax = 0,ymax = 0,ybottom = 0;
1081: static PetscBool initialized = PETSC_FALSE;
1082: int argc;
1083: char **argv;
1086: if (!initialized) {
1087: PetscGetArgs(&argc,&argv);
1088: glutInit(&argc, argv);
1089: glutInitDisplayMode(GLUT_RGBA /* | GLUT_DOUBLE */| GLUT_DEPTH);
1090: InitializeColors();
1091: }
1093: /*
1094: Initialize the display size
1095: */
1096: if (!xmax) {
1097: xmax = glutGet(GLUT_SCREEN_WIDTH);
1098: ymax = glutGet(GLUT_SCREEN_HEIGHT);
1099: }
1101: if (w == PETSC_DECIDE) w = draw->w = 300;
1102: if (h == PETSC_DECIDE) h = draw->h = 300;
1103: switch (w) {
1104: case PETSC_DRAW_FULL_SIZE: w = draw->w = xmax - 10; break;
1105: case PETSC_DRAW_HALF_SIZE: w = draw->w = (xmax - 20)/2; break;
1106: case PETSC_DRAW_THIRD_SIZE: w = draw->w = (xmax - 30)/3; break;
1107: case PETSC_DRAW_QUARTER_SIZE: w = draw->w = (xmax - 40)/4; break;
1108: }
1109: switch (h) {
1110: case PETSC_DRAW_FULL_SIZE: h = draw->h = ymax - 10; break;
1111: case PETSC_DRAW_HALF_SIZE: h = draw->h = (ymax - 20)/2; break;
1112: case PETSC_DRAW_THIRD_SIZE: h = draw->h = (ymax - 30)/3; break;
1113: case PETSC_DRAW_QUARTER_SIZE: h = draw->h = (ymax - 40)/4; break;
1114: }
1116: /* allow user to set location and size of window */
1117: xywh[0] = x; xywh[1] = y; xywh[2] = w; xywh[3] = h;
1118: PetscOptionsGetIntArray(NULL,"-geometry",xywh,&osize,NULL);
1119: x = (int) xywh[0]; y = (int) xywh[1]; w = (int) xywh[2]; h = (int) xywh[3];
1122: if (draw->x == PETSC_DECIDE || draw->y == PETSC_DECIDE) {
1123: /*
1124: PETSc tries to place windows starting in the upper left corner and
1125: moving across to the right.
1127: --------------------------------------------
1128: | Region used so far +xavailable,yavailable |
1129: | + |
1130: | + |
1131: |++++++++++++++++++++++ybottom |
1132: | |
1133: | |
1134: |--------------------------------------------|
1135: */
1136: /* First: can we add it to the right? */
1137: if (xavailable+w+10 <= xmax) {
1138: x = xavailable;
1139: y = yavailable;
1140: ybottom = PetscMax(ybottom,y + h + 30);
1141: } else {
1142: /* No, so add it below on the left */
1143: xavailable = 0;
1144: x = 0;
1145: yavailable = ybottom;
1146: y = ybottom;
1147: ybottom = ybottom + h + 30;
1148: }
1149: }
1150: /* update available region */
1151: xavailable = PetscMax(xavailable,x + w + 10);
1152: if (xavailable >= xmax) {
1153: xavailable = 0;
1154: yavailable = yavailable + h + 30;
1155: ybottom = yavailable;
1156: }
1157: if (yavailable >= ymax) {
1158: y = 0;
1159: yavailable = 0;
1160: ybottom = 0;
1161: }
1163: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
1165: /* actually create and open the window */
1166: PetscNew(&win);
1167: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_OpenGL));
1169: if (x < 0 || y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative corner of window");
1170: if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative window width or height");
1172: win->x = x;
1173: win->y = y;
1174: win->w = w;
1175: win->h = h;
1177: glutInitWindowSize(w, h);
1178: glutInitWindowPosition(x,y);
1179: win->win = glutCreateWindow(draw->title);
1180: glutDisplayFunc(display);
1181: glutReshapeFunc(reshape);
1182: Mouse.button = -1;
1183: Mouse.x = -1;
1184: Mouse.y = -1;
1185: glutMouseFunc(mouse);
1187: glClearColor(1.0,1.0,1.0,1.0);
1189: draw->data = win;
1190: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1191: InitializeShader();
1193: PetscDrawClear(draw);
1194: resized = PETSC_FALSE; /* opening the window triggers OpenGL call to reshape so need to cancel that resized flag */
1195: glutCheckLoop();
1196: return(0);
1197: }
1201: /*@C
1202: PetscDrawOpenGLUT - Opens an OpenGL window based on GLUT for use with the PetscDraw routines.
1204: Collective on MPI_Comm
1206: Input Parameters:
1207: + comm - the communicator that will share X-window
1208: . display - the X display on which to open,or null for the local machine
1209: . title - the title to put in the title bar,or null for no title
1210: . x,y - the screen coordinates of the upper left corner of window
1211: may use PETSC_DECIDE for these two arguments, then PETSc places the
1212: window
1213: - w, h - the screen width and height in pixels, or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
1214: or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
1216: Output Parameters:
1217: . draw - the drawing context.
1219: Options Database Keys:
1220: + -nox - Disables all x-windows output
1221: . -draw_pause <pause> - Sets time (in seconds) that the
1222: program pauses after PetscDrawPause() has been called
1223: (0 is default, -1 implies until user input).
1225: Level: beginner
1227: Note:
1228: When finished with the drawing context, it should be destroyed
1229: with PetscDrawDestroy().
1231: Note for Fortran Programmers:
1232: Whenever indicating null character data in a Fortran code,
1233: NULL_CHARACTER must be employed; using NULL is not
1234: correct for character data! Thus, NULL_CHARACTER can be
1235: used for the display and title input parameters.
1237: Concepts: OpenGL^drawing to
1239: .seealso: PetscDrawSynchronizedFlush(), PetscDrawDestroy(), PetscDrawOpenX(), PetscDrawCreate()
1240: @*/
1241: PetscErrorCode PetscDrawOpenGLUT(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *draw)
1242: {
1246: PetscDrawCreate(comm,display,title,x,y,w,h,draw);
1247: PetscDrawSetType(*draw,PETSC_DRAW_GLUT);
1248: return(0);
1249: }
1251: #elif defined(PETSC_HAVE_OPENGLES)
1255: PetscErrorCode PetscDrawOpenGLESRegisterGLKView(GLKView *view)
1256: {
1257: PetscInt i;
1260: for (i=0; i<10; i++) {
1261: if (view == globalGLKView[i]) return(0); /* already registered */
1262: if (!globalGLKView[i]) {
1263: globalGLKView[i] = view;
1264: return(0);
1265: }
1266: }
1267: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Out of GLKView slots");
1268: return(0);
1269: }
1273: PETSC_EXTERN PetscErrorCode PetscDrawCreate_OpenGLES(PetscDraw draw)
1274: {
1275: PetscDraw_OpenGL *win;
1276: PetscErrorCode ierr;
1277: static PetscBool initialized = PETSC_FALSE;
1278: PetscInt i;
1281: NSLog(@"Beginning PetscDrawCreate_OpenGLES()");
1283: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
1284: PetscNew(&win);
1285: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_OpenGL));
1287: draw->data = win;
1288: win->view = -1;
1289: for (i=0; i<10; i++) {
1290: if (!globalGLKViewUsed[i]) {
1291: win->view = i;
1292: win->w = globalGLKView[win->view].frame.size.width;
1293: win->h = globalGLKView[win->view].frame.size.height;
1294: [globalGLKView[win->view] bindDrawable];
1295: globalGLKViewUsed[i] = 1;
1296: break;
1297: }
1298: }
1299: if (win->view == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Requested more OpenGL ES windows then provided with PetscDrawOpenGLRegisterGLKView()");
1301: if (!initialized) {
1302: initialized = PETSC_TRUE;
1303: InitializeColors();
1304: }
1305: InitializeShader();
1307: PetscDrawClear(draw);
1308: NSLog(@"Ending PetscDrawCreate_OpenGLES()");
1309: return(0);
1310: }
1312: #endif