Actual source code: openglops.c
petsc-3.10.5 2019-03-28
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>
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];
44: static PetscErrorCode InitializeColors(void)
45: {
49: rcolor[PETSC_DRAW_WHITE] = 255;
50: gcolor[PETSC_DRAW_WHITE] = 255;
51: bcolor[PETSC_DRAW_WHITE] = 255;
52: rcolor[PETSC_DRAW_BLACK] = 0;
53: gcolor[PETSC_DRAW_BLACK] = 0;
54: bcolor[PETSC_DRAW_BLACK] = 0;
55: rcolor[PETSC_DRAW_RED] = 255;
56: gcolor[PETSC_DRAW_RED] = 0;
57: bcolor[PETSC_DRAW_RED] = 0;
58: rcolor[PETSC_DRAW_GREEN] = 0;
59: gcolor[PETSC_DRAW_GREEN] = 128;
60: bcolor[PETSC_DRAW_GREEN] = 0;
61: rcolor[PETSC_DRAW_CYAN] = 0;
62: gcolor[PETSC_DRAW_CYAN] = 139;
63: bcolor[PETSC_DRAW_CYAN] = 139;
64: rcolor[PETSC_DRAW_BLUE] = 0;
65: gcolor[PETSC_DRAW_BLUE] = 0;
66: bcolor[PETSC_DRAW_BLUE] = 255;
67: rcolor[PETSC_DRAW_MAGENTA] = 255;
68: gcolor[PETSC_DRAW_MAGENTA] = 0;
69: bcolor[PETSC_DRAW_MAGENTA] = 255;
70: rcolor[PETSC_DRAW_AQUAMARINE] = 127;
71: gcolor[PETSC_DRAW_AQUAMARINE] = 255;
72: bcolor[PETSC_DRAW_AQUAMARINE] = 212;
73: rcolor[PETSC_DRAW_FORESTGREEN] = 34;
74: gcolor[PETSC_DRAW_FORESTGREEN] = 139;
75: bcolor[PETSC_DRAW_FORESTGREEN] = 34;
76: rcolor[PETSC_DRAW_ORANGE] = 255;
77: gcolor[PETSC_DRAW_ORANGE] = 165;
78: bcolor[PETSC_DRAW_ORANGE] = 0;
79: rcolor[PETSC_DRAW_VIOLET] = 238;
80: gcolor[PETSC_DRAW_VIOLET] = 130;
81: bcolor[PETSC_DRAW_VIOLET] = 238;
82: rcolor[PETSC_DRAW_BROWN] = 165;
83: gcolor[PETSC_DRAW_BROWN] = 42;
84: bcolor[PETSC_DRAW_BROWN] = 42;
85: rcolor[PETSC_DRAW_PINK] = 255;
86: gcolor[PETSC_DRAW_PINK] = 192;
87: bcolor[PETSC_DRAW_PINK] = 203;
88: rcolor[PETSC_DRAW_CORAL] = 255;
89: gcolor[PETSC_DRAW_CORAL] = 127;
90: bcolor[PETSC_DRAW_CORAL] = 80;
91: rcolor[PETSC_DRAW_GRAY] = 128;
92: gcolor[PETSC_DRAW_GRAY] = 128;
93: bcolor[PETSC_DRAW_GRAY] = 128;
94: rcolor[PETSC_DRAW_YELLOW] = 255;
95: gcolor[PETSC_DRAW_YELLOW] = 255;
96: bcolor[PETSC_DRAW_YELLOW] = 0;
97: rcolor[PETSC_DRAW_GOLD] = 255;
98: gcolor[PETSC_DRAW_GOLD] = 215;
99: bcolor[PETSC_DRAW_GOLD] = 0;
100: rcolor[PETSC_DRAW_LIGHTPINK] = 255;
101: gcolor[PETSC_DRAW_LIGHTPINK] = 182;
102: bcolor[PETSC_DRAW_LIGHTPINK] = 193;
103: rcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 72;
104: gcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 209;
105: bcolor[PETSC_DRAW_MEDIUMTURQUOISE] = 204;
106: rcolor[PETSC_DRAW_KHAKI] = 240;
107: gcolor[PETSC_DRAW_KHAKI] = 230;
108: bcolor[PETSC_DRAW_KHAKI] = 140;
109: rcolor[PETSC_DRAW_DIMGRAY] = 105;
110: gcolor[PETSC_DRAW_DIMGRAY] = 105;
111: bcolor[PETSC_DRAW_DIMGRAY] = 105;
112: rcolor[PETSC_DRAW_YELLOWGREEN] = 54;
113: gcolor[PETSC_DRAW_YELLOWGREEN] = 205;
114: bcolor[PETSC_DRAW_YELLOWGREEN] = 50;
115: rcolor[PETSC_DRAW_SKYBLUE] = 135;
116: gcolor[PETSC_DRAW_SKYBLUE] = 206;
117: bcolor[PETSC_DRAW_SKYBLUE] = 235;
118: rcolor[PETSC_DRAW_DARKGREEN] = 0;
119: gcolor[PETSC_DRAW_DARKGREEN] = 100;
120: bcolor[PETSC_DRAW_DARKGREEN] = 0;
121: rcolor[PETSC_DRAW_NAVYBLUE] = 0;
122: gcolor[PETSC_DRAW_NAVYBLUE] = 0;
123: bcolor[PETSC_DRAW_NAVYBLUE] = 128;
124: rcolor[PETSC_DRAW_SANDYBROWN] = 244;
125: gcolor[PETSC_DRAW_SANDYBROWN] = 164;
126: bcolor[PETSC_DRAW_SANDYBROWN] = 96;
127: rcolor[PETSC_DRAW_CADETBLUE] = 95;
128: gcolor[PETSC_DRAW_CADETBLUE] = 158;
129: bcolor[PETSC_DRAW_CADETBLUE] = 160;
130: rcolor[PETSC_DRAW_POWDERBLUE] = 176;
131: gcolor[PETSC_DRAW_POWDERBLUE] = 224;
132: bcolor[PETSC_DRAW_POWDERBLUE] = 230;
133: rcolor[PETSC_DRAW_DEEPPINK] = 255;
134: gcolor[PETSC_DRAW_DEEPPINK] = 20;
135: bcolor[PETSC_DRAW_DEEPPINK] = 147;
136: rcolor[PETSC_DRAW_THISTLE] = 216;
137: gcolor[PETSC_DRAW_THISTLE] = 191;
138: bcolor[PETSC_DRAW_THISTLE] = 216;
139: rcolor[PETSC_DRAW_LIMEGREEN] = 50;
140: gcolor[PETSC_DRAW_LIMEGREEN] = 205;
141: bcolor[PETSC_DRAW_LIMEGREEN] = 50;
142: rcolor[PETSC_DRAW_LAVENDERBLUSH] = 255;
143: gcolor[PETSC_DRAW_LAVENDERBLUSH] = 240;
144: bcolor[PETSC_DRAW_LAVENDERBLUSH] = 245;
145: rcolor[PETSC_DRAW_PLUM] = 221;
146: gcolor[PETSC_DRAW_PLUM] = 160;
147: bcolor[PETSC_DRAW_PLUM] = 221;
149: PetscDrawUtilitySetCmap(NULL,256-PETSC_DRAW_BASIC_COLORS,rcolor+PETSC_DRAW_BASIC_COLORS,gcolor+PETSC_DRAW_BASIC_COLORS,bcolor+PETSC_DRAW_BASIC_COLORS);
150: return(0);
151: }
153: static GLuint vertexshader,fragmentshader,shaderprogram;
154: static PetscErrorCode InitializeShader(void)
155: {
156: const char *vertexsource = "attribute vec2 position;\
157: attribute vec3 color; \
158: varying vec4 vColor;\
159: void main(void)\
160: {\
161: vColor = vec4(color,0.50);\
162: gl_Position = vec4(position,0.0,1.0);\
163: }\n";
164: #if defined(PETSC_HAVE_GLUT)
165: const char *fragmentsource = "varying vec4 vColor;\
166: void main (void)\
167: {\
168: gl_FragColor = vColor; \
169: }\n";
170: #else
171: const char *fragmentsource = "precision mediump float;\
172: varying vec4 vColor;\
173: void main (void)\
174: {\
175: gl_FragColor = vColor; \
176: }\n";
177: #endif
178: int isCompiled_VS, isCompiled_FS;
179: int isLinked;
180: GLenum err;
183: /* http://www.opengl.org/wiki/OpenGL_Shading_Language */
184: /* Create an empty vertex shader handle */
185: vertexshader = glCreateShader(GL_VERTEX_SHADER);
187: /* Send the vertex shader source code to GL */
188: /* Note that the source code is NULL character terminated. */
189: /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
190: glShaderSource(vertexshader, 1, (const GLchar**)&vertexsource, 0);
192: /* Compile the vertex shader */
193: glCompileShader(vertexshader);
194: glGetShaderiv(vertexshader, GL_COMPILE_STATUS, &isCompiled_VS);
195: if (isCompiled_VS == GL_FALSE) {
197: int maxLength;
198: char *vertexInfoLog;
199: glGetShaderiv(vertexshader, GL_INFO_LOG_LENGTH, &maxLength);
200: PetscMalloc1(maxLength,&vertexInfoLog);
201: glGetShaderInfoLog(vertexshader, maxLength, &maxLength, vertexInfoLog);
202: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile vertex shader %s",vertexInfoLog);
203: }
205: /* Create an empty fragment shader handle */
206: fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
208: /* Send the fragment shader source code to GL */
209: /* Note that the source code is NULL character terminated. */
210: /* GL will automatically detect that therefore the length info can be 0 in this case (the last parameter) */
211: glShaderSource(fragmentshader, 1, (const GLchar**)&fragmentsource, 0);
213: /* Compile the fragment shader */
214: glCompileShader(fragmentshader);
215: glGetShaderiv(fragmentshader, GL_COMPILE_STATUS, &isCompiled_FS);
216: if (isCompiled_FS == GL_FALSE) {
218: int maxLength;
219: char *fragmentInfoLog;
220: glGetShaderiv(fragmentshader, GL_INFO_LOG_LENGTH, &maxLength);
221: PetscMalloc1(maxLength,&fragmentInfoLog);
222: glGetShaderInfoLog(fragmentshader, maxLength, &maxLength, fragmentInfoLog);
223: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile fragment shader %s",fragmentInfoLog);
224: }
226: /* If we reached this point it means the vertex and fragment shaders compiled and are syntax error free. */
227: /* We must link them together to make a GL shader program */
228: /* GL shader programs are monolithic. It is a single piece made of 1 vertex shader and 1 fragment shader. */
229: /* Assign our program handle a "name" */
230: shaderprogram = glCreateProgram();
232: /* Attach our shaders to our program */
233: glAttachShader(shaderprogram, vertexshader);
234: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
235: glAttachShader(shaderprogram, fragmentshader);
236: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
238: glBindAttribLocation(shaderprogram,0,"position");
239: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
240: glBindAttribLocation(shaderprogram,1,"color");
241: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
243: /* Link our program */
244: /* At this stage, the vertex and fragment programs are inspected, optimized and a binary code is generated for the shader. */
245: /* The binary code is uploaded to the GPU, if there is no error. */
246: glLinkProgram(shaderprogram);
248: /* Again, we must check and make sure that it linked. If it fails, it would mean either there is a mismatch between the vertex */
249: /* and fragment shaders. It might be that you have surpassed your GPU's abilities. Perhaps too many ALU operations or */
250: /* too many texel fetch instructions or too many interpolators or dynamic loops. */
252: glGetProgramiv(shaderprogram, GL_LINK_STATUS, &isLinked);
253: if (isLinked == GL_FALSE) {
254: /*
255: char *shaderProgramInfoLog;
256: glGetProgramiv(shaderprogram, GL_INFO_LOG_LENGTH, &maxLength);
257: shaderProgramInfoLog = new char[maxLength];
258: glGetProgramInfoLog(shaderprogram, maxLength, &maxLength, shaderProgramInfoLog);
259: free(shaderProgramInfoLog);
260: */
261: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Failed to compile fragment shader");
262: }
264: /* In your rendering code, you just need to call glUseProgram, call the various glUniform** to update your uniforms */
265: /* and then render. */
266: /* Load the shader into the rendering pipeline */
267: glUseProgram(shaderprogram);
268: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
269: return(0);
270: }
272: /*
273: This is currently all wrong, there is actually a separate shader for each window
274: so they cannot be stored as global
275: */
276: static PetscErrorCode FinalizeShader(void)
277: {
279: /* When the user shuts down your program, you should deallocate all your GL resources. */
280: /* Unbind your shader. */
281: glUseProgram(0);
282: /* Let's detach */
283: glDetachShader(shaderprogram, vertexshader);
284: glDetachShader(shaderprogram, fragmentshader);
285: /* Delete the shaders */
286: glDeleteShader(vertexshader);
287: glDeleteShader(fragmentshader);
288: /* Delete the shader object */
289: glDeleteProgram(shaderprogram);
290: return(0);
291: }
293: PETSC_INTERN PetscErrorCode PetscDrawClear_OpenGL_Base(PetscDraw);
295: #if defined(PETSC_HAVE_GLUT)
296: #include <GLUT/glut.h>
297: typedef struct {
298: int win; /* OpenGL GLUT window identifier */
299: int x,y,w,h; /* Size and location of window */
300: } PetscDraw_OpenGL;
302: static int currentwindow = -1;
303: PETSC_STATIC_INLINE PetscErrorCode OpenGLWindow(PetscDraw_OpenGL *win)
304: {
305: if (win->win == currentwindow) return 0;
306: currentwindow = win->win;
307: glutSetWindow(win->win);
308: return 0;
309: }
311: PETSC_STATIC_INLINE PetscErrorCode OpenGLString(float x,float y, const char *str,size_t len,int icolor)
312: {
313: PetscInt i;
315: glColor3ub(rcolor[icolor],gcolor[icolor],bcolor[icolor]);
316: glRasterPos2f(x, y);
317: for (i = 0; i < len; i++) glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str[i]);
318: return 0;
319: }
321: PetscErrorCode PetscDrawClear_OpenGL(PetscDraw draw)
322: {
326: PetscDrawClear_OpenGL_Base(draw);
327: return(0);
328: }
330: static PetscErrorCode PetscDrawGetPopup_OpenGL(PetscDraw draw,PetscDraw *popup)
331: {
335: PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,popup);
336: PetscDrawSetType(*popup,((PetscObject)draw)->type_name);
338: draw->popup = *popup;
339: return(0);
340: }
342: static PetscErrorCode PetscDrawStringVertical_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
343: {
344: PetscErrorCode ierr;
345: float xx,yy;
346: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
347: PetscReal tw,th;
348: size_t i,n;
351: OpenGLWindow(win);
352: PetscStrlen(chrs,&n);
353: PetscDrawStringGetSize(draw,&tw,&th);
354: xx = XTRANS(draw,x);
355: for (i=0; i<n; i++) {
356: yy = YTRANS(draw,y-th*i);
357: OpenGLString(xx,yy,chrs+i,1,c);
358: }
359: return(0);
360: }
362: static PetscErrorCode PetscDrawString_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
363: {
364: PetscErrorCode ierr;
365: float xx,yy;
366: size_t len;
367: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
368: char *substr;
369: PetscToken token;
372: xx = XTRANS(draw,x);
373: yy = YTRANS(draw,y);
374: OpenGLWindow(win);
376: PetscTokenCreate(chrs,'\n',&token);
377: PetscTokenFind(token,&substr);
378: PetscStrlen(substr,&len);
379: OpenGLString(xx,yy,substr,len,c);
380: PetscTokenFind(token,&substr);
381: while (substr) {
382: yy += 16;
383: PetscStrlen(substr,&len);
384: OpenGLString(xx,yy,substr,len,c);
385: PetscTokenFind(token,&substr);
386: }
387: PetscTokenDestroy(&token);
388: return(0);
389: }
391: static PetscErrorCode PetscDrawSetTitle_OpenGL(PetscDraw draw,const char title[])
392: {
393: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
394: PetscErrorCode ierr;
397: OpenGLWindow(win);
398: glutSetWindowTitle(title);
399: return(0);
400: }
402: static PetscErrorCode PetscDrawDestroy_OpenGL(PetscDraw draw)
403: {
404: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
405: PetscErrorCode ierr;
408: PetscDrawClear(draw);
409: PetscDrawDestroy(&draw->popup);
410: glutDestroyWindow(win->win);
411: PetscFree(draw->data);
412: return(0);
413: }
415: static PetscErrorCode PetscDrawFlush_OpenGL(PetscDraw draw)
416: {
417: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
418: PetscErrorCode ierr;
421: OpenGLWindow(win);
422: glutCheckLoop();
423: glFinish();
424: return(0);
425: }
427: static PetscErrorCode PetscDrawStringGetSize_OpenGL(PetscDraw draw,PetscReal *x,PetscReal *y)
428: {
429: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
430: PetscInt w;
431: PetscErrorCode ierr;
434: OpenGLWindow(win);
435: w = glutBitmapWidth(GLUT_BITMAP_8_BY_13,'W');
436: if (x) *x = w*(draw->coor_xr - draw->coor_xl)/((win->w)*(draw->port_xr - draw->port_xl));
437: if (y) *y = (13./8.0)*w*(draw->coor_yr - draw->coor_yl)/((win->h)*(draw->port_yr - draw->port_yl));
438: return(0);
439: }
441: static PetscErrorCode PetscDrawResizeWindow_OpenGL(PetscDraw draw,int w,int h)
442: {
443: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
444: PetscErrorCode ierr;
447: OpenGLWindow(win);
448: glutReshapeWindow(w,h);
449: PetscDrawFlush(draw);
450: PetscDrawCheckResizedWindow(draw);
451: return(0);
452: }
454: static PetscBool resized = PETSC_FALSE;
456: static PetscErrorCode PetscDrawCheckResizedWindow_OpenGL(PetscDraw draw)
457: {
461: if (!resized) return(0);
462: resized = PETSC_FALSE;
463: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
464: PetscDrawClear(draw);
465: return(0);
466: }
468: typedef struct {
469: int button,x,y;
470: } OpenGLButton;
471: static OpenGLButton Mouse;
473: static PetscErrorCode PetscDrawGetMouseButton_OpenGL(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
474: {
475: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
476: int px,py;
479: while (Mouse.button == -1) glutCheckLoop();
481: *button = (PetscDrawButton)(Mouse.button + 1);
482: px = Mouse.x;
483: py = Mouse.y;
484: Mouse.button = -1;
486: if (x_phys) *x_phys = ((double)px)/((double)win->w);
487: if (y_phys) *y_phys = 1.0 - ((double)py)/((double)win->h);
489: 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);
490: 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);
491: return(0);
492: }
493: #elif defined(PETSC_HAVE_OPENGLES)
494: typedef struct {
495: GLint win; /* not currently used */
496: int w,h; /* width and height in pixels */
497: int view;
498: } PetscDraw_OpenGL;
500: static GLKView *globalGLKView[10] = {0,0,0,0,0,0,0,0,0,0};
501: static int globalGLKViewUsed[10] = {0,0,0,0,0,0,0,0,0,0};
502: PETSC_STATIC_INLINE PetscErrorCode OpenGLWindow(PetscDraw_OpenGL *win)
503: {
504: return 0;
505: }
507: static PetscErrorCode PetscDrawClear_OpenGL(PetscDraw draw)
508: {
509: PetscErrorCode ierr;
510: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
513: /* remove all UIText added to window */
514: for (UIView *view in [globalGLKView[win->view] subviews]) {[view removeFromSuperview];}
515: PetscDrawClear_OpenGL_Base(draw);
516: return(0);
517: }
519: static PetscErrorCode PetscDrawGetPopup_OpenGL(PetscDraw draw,PetscDraw *popup)
520: {
524: *popup = NULL;
525: return(0);
526: }
528: static PetscErrorCode PetscDrawString_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
529: {
530: PetscErrorCode ierr;
531: float xx,yy;
532: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
533: UILabel *yourLabel;
536: OpenGLWindow(win);
537: xx = XPTRANS(draw,win,x);
538: yy = YPTRANS(draw,win,y);
539: NSLog(@"Draw string start");
540: yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(xx, yy, 300, 20)];
541: [yourLabel setTextColor:[UIColor colorWithRed:rcolor[c]/255.0 green:gcolor[c]/255.0 blue:rcolor[c]/255.0 alpha:1.0]];
542: [yourLabel setText: [[NSString alloc] initWithCString:chrs encoding:NSMacOSRomanStringEncoding]];
543: [yourLabel setBackgroundColor:[UIColor clearColor]];
544: /* [yourLabel setFont:[UIFont fontWithName: @"Trebuchet MS" size: 14.0f]]; */
545: [globalGLKView[win->view] addSubview:yourLabel];
546: NSLog(@"Draw string end");
547: return(0);
548: }
550: /*
551: I don't understand the rotation. It seems to maybe rotate from the middle of the width?
553: It would be nice if the frame could be made to match the text length automatically
555: This makes src/sys/draw/examples/tests/ex3.c look good but may be terrible for other locations
556: */
557: static PetscErrorCode PetscDrawStringVertical_OpenGL(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
558: {
559: PetscErrorCode ierr;
560: float xx,yy, w = 100,h = 20;
561: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
562: UILabel *yourLabel;
565: OpenGLWindow(win);
566: xx = XPTRANS(draw,win,x);
567: yy = YPTRANS(draw,win,y);
568: NSLog(@"Draw string vertical start");
569: yourLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, w, h)];
570: [yourLabel setTextColor:[UIColor colorWithRed:rcolor[c]/255.0 green:gcolor[c]/255.0 blue:rcolor[c]/255.0 alpha:1.0]];
571: [yourLabel setText: [[NSString alloc] initWithCString:chrs encoding:NSMacOSRomanStringEncoding]];
572: [yourLabel setBackgroundColor:[UIColor clearColor]];
573: [yourLabel setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(-PETSC_PI / 2),-w/2.0-yy,-h+xx)];
574: /* [yourLabel setFont:[UIFont fontWithName: @"Trebuchet MS" size: 14.0f]]; */
575: [globalGLKView[win->view] addSubview:yourLabel];
576: NSLog(@"Draw string vertical end");
577: return(0);
578: }
580: static PetscErrorCode PetscDrawSetTitle_OpenGL(PetscDraw draw,const char title[])
581: {
582: return 0;
583: }
584: static PetscErrorCode PetscDrawDestroy_OpenGL(PetscDraw draw)
585: {
586: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
587: PetscErrorCode ierr;
588: PetscInt i;
591: globalGLKViewUsed[win->view] = 0;
592: PetscFree(draw->data);
593: return(0);
594: return(0);
595: }
596: static PetscErrorCode PetscDrawFlush_OpenGL(PetscDraw draw)
597: {
598: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
600: GLenum err;
601: glFlush();
602: err = glGetError();
603: if (err != GL_NO_ERROR) {
604: NSLog(@"GL error detected glFlush()");
605: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to flush OpenGL Error Code %d",err);
606: }
607: [globalGLKView[win->view] display];
608: NSLog(@"Completed display in PetscDrawFlush()");
609: return 0;
610: }
611: static PetscErrorCode PetscDrawStringGetSize_OpenGL(PetscDraw draw,PetscReal *x,PetscReal *y)
612: {
613: float w = .02;
614: if (x) *x = w*(draw->coor_xr - draw->coor_xl)/(draw->port_xr - draw->port_xl);
615: if (y) *y = (13./8.0)*w*(draw->coor_yr - draw->coor_yl)/(draw->port_yr - draw->port_yl);
616: return 0;
617: }
618: static PetscErrorCode PetscDrawResizeWindow_OpenGL(PetscDraw draw,int w,int h)
619: {
620: return 0;
621: }
622: static PetscErrorCode PetscDrawCheckResizedWindow_OpenGL(PetscDraw draw)
623: {
624: return 0;
625: }
626: static PetscErrorCode PetscDrawGetMouseButton_OpenGL(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
627: {
628: return 0;
629: }
630: #endif
632: /* -----------------------------------------------------------------------*/
634: PetscErrorCode PetscDrawClear_OpenGL_Base(PetscDraw draw)
635: {
636: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
637: PetscErrorCode ierr;
638: float xl,yl,xr,yr;
639: GLfloat vertices[12];
640: GLfloat colors[18];
641: GLuint positionBufferObject;
642: GLuint colorBufferObject;
643: GLenum err;
646: OpenGLWindow(win);
647: xl = -1.0 + 2.0*((draw)->port_xl);
648: xr = -1.0 + 2.0*((draw)->port_xr);
649: yl = -1.0 + 2.0*((draw)->port_yl);
650: yr = -1.0 + 2.0*((draw)->port_yr);
652: vertices[0] = xl;
653: vertices[1] = yl;
654: vertices[2] = xr;
655: vertices[3] = yl;
656: vertices[4] = xl;
657: vertices[5] = yr;
659: vertices[6] = xl;
660: vertices[7] = yr;
661: vertices[8] = xr;
662: vertices[9] = yr;
663: vertices[10] = xr;
664: vertices[11] = yl;
666: colors[0] = 1.0; colors[1] = 1.0; colors[2] = 1.0;
667: colors[3] = 1.0; colors[4] = 1.0; colors[5] = 1.0;
668: colors[6] = 1.0; colors[7] = 1.0; colors[8] = 1.0;
670: colors[9] = 1.0; colors[10] = 1.0; colors[11] = 1.0;
671: colors[12] = 1.0; colors[13] = 1.0; colors[14] = 1.0;
672: colors[15] = 1.0; colors[16] = 1.0; colors[17] = 1.0;
674: glGenBuffers(1, &positionBufferObject);
675: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
676: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
677: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
678: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
679: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
680: glEnableVertexAttribArray(0);
681: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
682: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
683: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
685: glGenBuffers(1, &colorBufferObject);
686: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
687: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
688: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
689: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
690: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
691: glEnableVertexAttribArray(1);
692: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
693: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
694: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
696: glDrawArrays(GL_TRIANGLES, 0, 6);
697: glDisableVertexAttribArray(0);
698: glDisableVertexAttribArray(1);
699: glDeleteBuffers(1, &positionBufferObject);
700: glDeleteBuffers(1, &colorBufferObject);
701: PetscDrawFlush(draw);
702: return(0);
703: }
705: static PetscErrorCode PetscDrawPoint_OpenGL(PetscDraw draw,PetscReal xl,PetscReal yl,int cl)
706: {
707: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
708: GLfloat vertices[2],colors[3];
709: PetscErrorCode ierr;
710: GLuint positionBufferObject;
711: GLuint colorBufferObject;
712: GLenum err;
715: vertices[0] = XTRANS(draw,xl);
716: vertices[1] = YTRANS(draw,yl);
717: colors[0] = rcolor[cl]/255.0; colors[1] = gcolor[cl]/255.0; colors[2] = bcolor[cl]/255.0;
719: OpenGLWindow(win);
720: glGenBuffers(1, &positionBufferObject);
721: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
722: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
723: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
724: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
725: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
726: glEnableVertexAttribArray(0);
727: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
728: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
729: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
731: glGenBuffers(1, &colorBufferObject);
732: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
733: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
734: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
735: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
736: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
737: glEnableVertexAttribArray(1);
738: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
739: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
740: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
742: glDrawArrays(GL_POINTS, 0, 2);
743: glDisableVertexAttribArray(0);
744: glDisableVertexAttribArray(1);
745: glDeleteBuffers(1, &positionBufferObject);
746: glDeleteBuffers(1, &colorBufferObject);
747: return(0);
748: }
750: static PetscErrorCode PetscDrawLine_OpenGL(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
751: {
752: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
753: GLfloat linevertices[4],colors[6];
754: PetscErrorCode ierr;
755: GLenum err;
756: GLuint positionBufferObject;
757: GLuint colorBufferObject;
761: linevertices[0] = XTRANS(draw,xl);
762: linevertices[2] = XTRANS(draw,xr);
763: linevertices[1] = YTRANS(draw,yl);
764: linevertices[3] = YTRANS(draw,yr);
765: if (linevertices[0] == linevertices[2] && linevertices[1] == linevertices[3]) return(0);
766: colors[0] = rcolor[cl]/255.0; colors[1] = gcolor[cl]/255.0; colors[2] = bcolor[cl]/255.0;
767: colors[3] = rcolor[cl]/255.0; colors[4] = gcolor[cl]/255.0; colors[5] = bcolor[cl]/255.0;
769: OpenGLWindow(win);
770: /* http://arcsynthesis.org/gltut/Basics/Tutorial%2001.html */
771: glGenBuffers(1, &positionBufferObject);
772: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
773: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
774: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
775: glBufferData(GL_ARRAY_BUFFER, sizeof(linevertices), linevertices, GL_STATIC_DRAW);
776: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
777: glEnableVertexAttribArray(0);
778: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
779: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
780: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
782: glGenBuffers(1, &colorBufferObject);
783: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
784: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
785: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
786: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
787: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
788: glEnableVertexAttribArray(1);
789: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
790: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
791: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
793: glDrawArrays(GL_LINES, 0, 2);
794: glDisableVertexAttribArray(0);
795: glDisableVertexAttribArray(1);
796: glDeleteBuffers(1, &positionBufferObject);
797: glDeleteBuffers(1, &colorBufferObject);
798: return(0);
799: }
801: 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)
802: {
803: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
804: PetscErrorCode ierr;
805: GLfloat vertices[6],colors[9];
806: GLenum err;
807: GLuint positionBufferObject;
808: GLuint colorBufferObject;
811: vertices[0] = XTRANS(draw,X1);
812: vertices[1] = YTRANS(draw,Y_1);
813: vertices[2] = XTRANS(draw,X2);
814: vertices[3] = YTRANS(draw,Y2);
815: vertices[4] = XTRANS(draw,X3);
816: vertices[5] = YTRANS(draw,Y3);
817: colors[0] = rcolor[c1]/255.0; colors[1] = gcolor[c1]/255.0; colors[2] = bcolor[c1]/255.0;
818: colors[3] = rcolor[c2]/255.0; colors[4] = gcolor[c2]/255.0; colors[5] = bcolor[c2]/255.0;
819: colors[6] = rcolor[c3]/255.0; colors[7] = gcolor[c3]/255.0; colors[8] = bcolor[c3]/255.0;
821: OpenGLWindow(win);
822: glGenBuffers(1, &positionBufferObject);
823: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
824: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
825: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
826: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
827: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
828: glEnableVertexAttribArray(0);
829: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
830: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
831: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
833: glGenBuffers(1, &colorBufferObject);
834: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
835: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
836: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
837: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
838: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
839: glEnableVertexAttribArray(1);
840: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
841: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
842: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
844: glDrawArrays(GL_TRIANGLES, 0, 3);
845: glDisableVertexAttribArray(0);
846: glDisableVertexAttribArray(1);
847: glDeleteBuffers(1, &positionBufferObject);
848: glDeleteBuffers(1, &colorBufferObject);
849: return(0);
850: }
852: static PetscErrorCode PetscDrawRectangle_OpenGL(PetscDraw draw,PetscReal Xl,PetscReal Yl,PetscReal Xr,PetscReal Yr,int c1,int c2,int c3,int c4)
853: {
854: PetscDraw_OpenGL *win = (PetscDraw_OpenGL*)draw->data;
855: PetscErrorCode ierr;
856: GLfloat vertices[12],colors[18];
857: float x1,y_1,x2,y2;
858: GLuint positionBufferObject;
859: GLuint colorBufferObject;
860: GLenum err;
863: x1 = XTRANS(draw,Xl);
864: y_1 = YTRANS(draw,Yl);
865: x2 = XTRANS(draw,Xr);
866: y2 = YTRANS(draw,Yr);
868: OpenGLWindow(win);
870: vertices[0] = x1; colors[0] = rcolor[c1]/255.0; colors[1] = gcolor[c1]/255.0; colors[2] = bcolor[c1]/255.0;
871: vertices[1] = y_1;
872: vertices[2] = x2;colors[3] = rcolor[c2]/255.0; colors[4] = gcolor[c2]/255.0; colors[5] = bcolor[c2]/255.0;
873: vertices[3] = y_1;
874: vertices[4] = x1;colors[6] = rcolor[c4]/255.0; colors[7] = gcolor[c4]/255.0; colors[8] = bcolor[c4]/255.0;
875: vertices[5] = y2;
877: vertices[6] = x1;colors[9] = rcolor[c4]/255.0; colors[10] = gcolor[c4]/255.0; colors[11] = bcolor[c4]/255.0;
878: vertices[7] = y2;
879: vertices[8] = x2;colors[12] = rcolor[c3]/255.0; colors[13] = gcolor[c3]/255.0; colors[14] = bcolor[c3]/255.0;
880: vertices[9] = y2;
881: vertices[10] = x2;colors[15] = rcolor[c2]/255.0; colors[16] = gcolor[c2]/255.0; colors[17] = bcolor[c2]/255.0;
882: vertices[11] = y_1;
884: glGenBuffers(1, &positionBufferObject);
885: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
886: glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
887: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
888: glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
889: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
890: glEnableVertexAttribArray(0);
891: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
892: glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
893: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
895: glGenBuffers(1, &colorBufferObject);
896: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
897: glBindBuffer(GL_ARRAY_BUFFER, colorBufferObject);
898: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
899: glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
900: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
901: glEnableVertexAttribArray(1);
902: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
903: glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
904: err = glGetError(); if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"OpenGL error %d\n",err);
906: glDrawArrays(GL_TRIANGLES, 0, 6);
907: glDisableVertexAttribArray(0);
908: glDisableVertexAttribArray(1);
909: glDeleteBuffers(1, &positionBufferObject);
910: glDeleteBuffers(1, &colorBufferObject);
911: return(0);
912: }
915: static PetscErrorCode PetscDrawPause_OpenGL(PetscDraw draw)
916: {
920: if (draw->pause > 0) PetscSleep(draw->pause);
921: else if (draw->pause == -1) {
922: PetscDrawButton button = PETSC_BUTTON_NONE;
923: PetscDrawGetMouseButton(draw,&button,0,0,0,0);
924: if (button == PETSC_BUTTON_CENTER) draw->pause = 0;
925: }
926: return(0);
927: }
930: static struct _PetscDrawOps DvOps = { 0,
931: PetscDrawFlush_OpenGL,
932: PetscDrawLine_OpenGL,
933: 0,
934: 0,
935: PetscDrawPoint_OpenGL,
936: 0,
937: PetscDrawString_OpenGL,
938: PetscDrawStringVertical_OpenGL,
939: 0, /* PetscDrawStringSetSize_OpenGL,*/
940: PetscDrawStringGetSize_OpenGL,
941: 0, /* PetscDrawSetViewport_OpenGL,*/
942: PetscDrawClear_OpenGL,
943: PetscDrawRectangle_OpenGL,
944: PetscDrawTriangle_OpenGL,
945: 0, /* PetscDrawEllipse_OpenGL,*/
946: PetscDrawGetMouseButton_OpenGL,
947: PetscDrawPause_OpenGL,
948: 0,
949: 0,
950: PetscDrawGetPopup_OpenGL,
951: PetscDrawSetTitle_OpenGL,
952: PetscDrawCheckResizedWindow_OpenGL,
953: PetscDrawResizeWindow_OpenGL,
954: PetscDrawDestroy_OpenGL,
955: 0,
956: 0, /* PetscDrawGetSingleton_OpenGL,*/
957: 0, /* PetscDrawRestoreSingleton_OpenGL,*/
958: 0,
959: 0,
960: 0,
961: PetscDrawLine_OpenGL};
963: #if defined(PETSC_HAVE_GLUT)
964: /* callbacks required by GLUT */
965: static void display(void) {;}
966: static void reshape(int width, int height)
967: {
968: glViewport(0, 0, width, height);
969: resized = PETSC_TRUE;
970: }
971: static void mouse(int button, int state,int x, int y)
972: {
973: if (state == GLUT_UP) {
974: Mouse.button = button;
975: Mouse.x = x;
976: Mouse.y = y;
977: }
978: }
980: PETSC_EXTERN PetscErrorCode PetscDrawCreate_GLUT(PetscDraw draw)
981: {
982: PetscDraw_OpenGL *win;
983: PetscErrorCode ierr;
984: PetscInt xywh[4],osize = 4;
985: int x = draw->x,y = draw->y,w = draw->w,h = draw->h;
986: static int xavailable = 0,yavailable = 0,xmax = 0,ymax = 0,ybottom = 0;
987: static PetscBool initialized = PETSC_FALSE;
988: int argc;
989: char **argv;
992: if (!initialized) {
993: PetscGetArgs(&argc,&argv);
994: glutInit(&argc, argv);
995: glutInitDisplayMode(GLUT_RGBA /* | GLUT_DOUBLE */| GLUT_DEPTH);
996: InitializeColors();
997: }
999: /*
1000: Initialize the display size
1001: */
1002: if (!xmax) {
1003: xmax = glutGet(GLUT_SCREEN_WIDTH);
1004: ymax = glutGet(GLUT_SCREEN_HEIGHT);
1005: }
1007: if (w == PETSC_DECIDE) w = draw->w = 300;
1008: if (h == PETSC_DECIDE) h = draw->h = 300;
1009: switch (w) {
1010: case PETSC_DRAW_FULL_SIZE: w = draw->w = xmax - 10; break;
1011: case PETSC_DRAW_HALF_SIZE: w = draw->w = (xmax - 20)/2; break;
1012: case PETSC_DRAW_THIRD_SIZE: w = draw->w = (xmax - 30)/3; break;
1013: case PETSC_DRAW_QUARTER_SIZE: w = draw->w = (xmax - 40)/4; break;
1014: }
1015: switch (h) {
1016: case PETSC_DRAW_FULL_SIZE: h = draw->h = ymax - 10; break;
1017: case PETSC_DRAW_HALF_SIZE: h = draw->h = (ymax - 20)/2; break;
1018: case PETSC_DRAW_THIRD_SIZE: h = draw->h = (ymax - 30)/3; break;
1019: case PETSC_DRAW_QUARTER_SIZE: h = draw->h = (ymax - 40)/4; break;
1020: }
1022: /* allow user to set location and size of window */
1023: xywh[0] = x; xywh[1] = y; xywh[2] = w; xywh[3] = h;
1024: PetscOptionsGetIntArray(NULL,"-geometry",xywh,&osize,NULL);
1025: x = (int) xywh[0]; y = (int) xywh[1]; w = (int) xywh[2]; h = (int) xywh[3];
1028: if (draw->x == PETSC_DECIDE || draw->y == PETSC_DECIDE) {
1029: /*
1030: PETSc tries to place windows starting in the upper left corner and
1031: moving across to the right.
1033: --------------------------------------------
1034: | Region used so far +xavailable,yavailable |
1035: | + |
1036: | + |
1037: |++++++++++++++++++++++ybottom |
1038: | |
1039: | |
1040: |--------------------------------------------|
1041: */
1042: /* First: can we add it to the right? */
1043: if (xavailable+w+10 <= xmax) {
1044: x = xavailable;
1045: y = yavailable;
1046: ybottom = PetscMax(ybottom,y + h + 30);
1047: } else {
1048: /* No, so add it below on the left */
1049: xavailable = 0;
1050: x = 0;
1051: yavailable = ybottom;
1052: y = ybottom;
1053: ybottom = ybottom + h + 30;
1054: }
1055: }
1056: /* update available region */
1057: xavailable = PetscMax(xavailable,x + w + 10);
1058: if (xavailable >= xmax) {
1059: xavailable = 0;
1060: yavailable = yavailable + h + 30;
1061: ybottom = yavailable;
1062: }
1063: if (yavailable >= ymax) {
1064: y = 0;
1065: yavailable = 0;
1066: ybottom = 0;
1067: }
1069: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
1071: /* actually create and open the window */
1072: PetscNew(&win);
1073: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_OpenGL));
1075: if (x < 0 || y < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative corner of window");
1076: if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative window width or height");
1078: win->x = x;
1079: win->y = y;
1080: win->w = w;
1081: win->h = h;
1083: glutInitWindowSize(w, h);
1084: glutInitWindowPosition(x,y);
1085: win->win = glutCreateWindow(draw->title);
1086: glutDisplayFunc(display);
1087: glutReshapeFunc(reshape);
1088: Mouse.button = -1;
1089: Mouse.x = -1;
1090: Mouse.y = -1;
1091: glutMouseFunc(mouse);
1093: glClearColor(1.0,1.0,1.0,1.0);
1095: draw->data = win;
1096: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1097: InitializeShader();
1099: PetscDrawClear(draw);
1100: resized = PETSC_FALSE; /* opening the window triggers OpenGL call to reshape so need to cancel that resized flag */
1101: glutCheckLoop();
1102: return(0);
1103: }
1105: /*@C
1106: PetscDrawOpenGLUT - Opens an OpenGL window based on GLUT for use with the PetscDraw routines.
1108: Collective on MPI_Comm
1110: Input Parameters:
1111: + comm - the communicator that will share X-window
1112: . display - the X display on which to open,or null for the local machine
1113: . title - the title to put in the title bar,or null for no title
1114: . x,y - the screen coordinates of the upper left corner of window
1115: may use PETSC_DECIDE for these two arguments, then PETSc places the
1116: window
1117: - w, h - the screen width and height in pixels, or PETSC_DRAW_HALF_SIZE, PETSC_DRAW_FULL_SIZE,
1118: or PETSC_DRAW_THIRD_SIZE or PETSC_DRAW_QUARTER_SIZE
1120: Output Parameters:
1121: . draw - the drawing context.
1123: Options Database Keys:
1124: + -nox - Disables all x-windows output
1125: . -draw_pause <pause> - Sets time (in seconds) that the
1126: program pauses after PetscDrawPause() has been called
1127: (0 is default, -1 implies until user input).
1128: . -draw_cmap <name> - Sets the colormap to use.
1129: . -draw_cmap_reverse - Reverses the colormap.
1130: - -draw_cmap_brighten - Brighten (0 < beta < 1) or darken (-1 < beta < 0) the colormap.
1132: Level: beginner
1134: Note:
1135: When finished with the drawing context, it should be destroyed
1136: with PetscDrawDestroy().
1138: Note for Fortran Programmers:
1139: Whenever indicating null character data in a Fortran code,
1140: NULL_CHARACTER must be employed; using NULL is not
1141: correct for character data! Thus, NULL_CHARACTER can be
1142: used for the display and title input parameters.
1144: Concepts: OpenGL^drawing to
1146: .seealso: PetscDrawFlush(), PetscDrawDestroy(), PetscDrawOpenX(), PetscDrawCreate()
1147: @*/
1148: PetscErrorCode PetscDrawOpenGLUT(MPI_Comm comm,const char display[],const char title[],int x,int y,int w,int h,PetscDraw *draw)
1149: {
1153: PetscDrawCreate(comm,display,title,x,y,w,h,draw);
1154: PetscDrawSetType(*draw,PETSC_DRAW_GLUT);
1155: return(0);
1156: }
1158: #elif defined(PETSC_HAVE_OPENGLES)
1160: PetscErrorCode PetscDrawOpenGLESRegisterGLKView(GLKView *view)
1161: {
1162: PetscInt i;
1165: for (i=0; i<10; i++) {
1166: if (view == globalGLKView[i]) return(0); /* already registered */
1167: if (!globalGLKView[i]) {
1168: globalGLKView[i] = view;
1169: return(0);
1170: }
1171: }
1172: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Out of GLKView slots");
1173: return(0);
1174: }
1176: PETSC_EXTERN PetscErrorCode PetscDrawCreate_OpenGLES(PetscDraw draw)
1177: {
1178: PetscDraw_OpenGL *win;
1179: PetscErrorCode ierr;
1180: static PetscBool initialized = PETSC_FALSE;
1181: PetscInt i;
1184: NSLog(@"Beginning PetscDrawCreate_OpenGLES()");
1186: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
1187: PetscNew(&win);
1188: PetscLogObjectMemory((PetscObject)draw,sizeof(PetscDraw_OpenGL));
1190: draw->data = win;
1191: win->view = -1;
1192: for (i=0; i<10; i++) {
1193: if (!globalGLKViewUsed[i]) {
1194: win->view = i;
1195: win->w = globalGLKView[win->view].frame.size.width;
1196: win->h = globalGLKView[win->view].frame.size.height;
1197: [globalGLKView[win->view] bindDrawable];
1198: globalGLKViewUsed[i] = 1;
1199: break;
1200: }
1201: }
1202: if (win->view == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Requested more OpenGL ES windows then provided with PetscDrawOpenGLRegisterGLKView()");
1204: if (!initialized) {
1205: initialized = PETSC_TRUE;
1206: InitializeColors();
1207: }
1208: InitializeShader();
1210: PetscDrawClear(draw);
1211: NSLog(@"Ending PetscDrawCreate_OpenGLES()");
1212: return(0);
1213: }
1215: #endif