123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- program es2example1;
- // By Benjamin 'BeRo' Rosseaux - [email protected] - http://www.rosseaux.com
- // Tested on desktop linux and the Nokia N900 with Maemo 5
- {$ifdef fpc}
- {$mode delphi}
- {$ifdef CPUARM}
- {$define ogles}
- {$endif}
- {$ifdef CPUI386}
- {$define CPU386}
- {$endif}
- {$ifdef CPU386}
- {$asmmode intel}
- {$endif}
- {$endif}
- uses SysUtils,Classes,BaseUnix,Unix,UnixType,X,XLib,XUtil,XAtom{$ifdef ogles},gles20{$else},xf86vmode,GL,GLX,GLExt{$endif};
- const VertexArray:array[0..11] of single=(0,-1,0,1,
- 1,1,0,1,
- -1,1,0,1);
- ShaderPrecode={$ifdef ogles}''{$else}'#version 120'#10{$endif};
- VertexShaderSource:string=ShaderPrecode+'attribute vec4 position;'#10+
- 'varying mediump vec2 pos;'#10+
- 'void main(){'#10+
- ' gl_Position=position;'#10+
- ' pos=position.xy;'#10+
- '}';
-
- FragmentShaderSource:string=ShaderPrecode+'varying mediump vec2 pos;'#10+
- 'uniform mediump float phase;'#10+
- 'void main(){'#10+
- ' gl_FragColor=vec4(1.0,1.0,1.0,1.0)*sin(((pos.x*pos.x)+(pos.y*pos.y))*40.0+phase);'#10+
- '}';
- var ReturnCode,CanvasWidth,CanvasHeight:integer;
- Running:boolean;
- VertexShader,FragmentShader,ShaderProgram:TGLuint;
- PhaseLocation:TGLint;
- CurrentTime:int64;
- function GetTime:int64;
- var NowTime:TDateTime;
- Year,Month,Day,hour,min,sec,msec:word;
- begin
- NowTime:=Now;
- DecodeDate(NowTime,Year,Month,Day);
- DecodeTime(NowTime,hour,min,sec,msec);
- result:=(((((((((((Year*365)+Month)*31)+Day)*24)+hour)*60)+min)*60)+sec)*1000)+msec;
- end;
-
- procedure PrintShaderInfoLog(Shader:TGLUint;ShaderType:string);
- var len,Success:TGLint;
- Buffer:pchar;
- begin
- glGetShaderiv(Shader,GL_COMPILE_STATUS,@Success);
- if Success<>GL_TRUE then begin
- glGetShaderiv(Shader,GL_INFO_LOG_LENGTH,@len);
- if len>0 then begin
- getmem(Buffer,len+1);
- glGetShaderInfoLog(Shader,len,nil,Buffer);
- writeln(ShaderType,': ',Buffer);
- freemem(Buffer);
- Running:=false;
- ReturnCode:=1;
- end;
- end;
- end;
- function CreateShader(ShaderType:TGLenum;Source:pchar):TGLuint;
- begin
- result:=glCreateShader(ShaderType);
- glShaderSource(result,1,@Source,nil);
- glCompileShader(result);
- if ShaderType=GL_VERTEX_SHADER then begin
- PrintShaderInfoLog(result,'Vertex shader');
- end else begin
- PrintShaderInfoLog(result,'Fragment shader');
- end;
- end;
- procedure Init;
- begin
- ShaderProgram:=glCreateProgram();
- VertexShader:=CreateShader(GL_VERTEX_SHADER,pchar(VertexShaderSource));
- FragmentShader:=CreateShader(GL_FRAGMENT_SHADER,pchar(FragmentShaderSource));
- glAttachShader(ShaderProgram,VertexShader);
- glAttachShader(ShaderProgram,FragmentShader);
-
- glLinkProgram(ShaderProgram);
-
- glUseProgram(ShaderProgram);
-
- PhaseLocation:=glGetUniformLocation(ShaderProgram,'phase');
- if PhaseLocation<0 then begin
- writeln('Error: Cannot get phase shader uniform location');
- Running:=false;
- ReturnCode:=1;
- end;
- end;
- procedure Done;
- begin
- end;
- procedure Render;
- begin
- glViewPort(0,0,CanvasWidth,CanvasHeight);
- glClearColor(0,1,0,1);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- glUniform1f(PhaseLocation,(GetTime mod 2000)*0.001*pi);
-
- glVertexAttribPointer(0,4,GL_FLOAT,0,0,@VertexArray);
- glEnableVertexAttribArray(0);
- glDrawArrays(GL_TRIANGLE_STRIP,0,3);
-
- end;
- const MOUSE_MASK=ButtonPressMask or ButtonReleaseMask or PointerMotionMask or ButtonMotionMask;
- KEY_MASK=KeyPressMask or KeyReleaseMask or KeymapStateMask;
- X_MASK=KEY_MASK or MOUSE_MASK or VisibilityChangeMask or StructureNotifymask or ExposureMask;
- {$ifdef ogles}
- Attr:array[0..6] of EGLint=(EGL_BUFFER_SIZE,16,
- EGL_DEPTH_SIZE,8,
- EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
- EGL_NONE);
- { Attr:array[0..12] of EGLint=(EGL_BUFFER_SIZE,16,
- EGL_RED_SIZE,6,
- EGL_GREEN_SIZE,5,
- EGL_BLUE_SIZE,6,
- EGL_DEPTH_SIZE,8,
- EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,
- EGL_NONE);}
- CtxAttr:array[0..2] of EGLint=(EGL_CONTEXT_CLIENT_VERSION,2,EGL_NONE);
- {$else}
- Attr:array[0..8] of TGLint=(GLX_RGBA,
- GLX_RED_SIZE,1,
- GLX_GREEN_SIZE,1,
- GLX_BLUE_SIZE,1,
- GLX_DOUBLEBUFFER,
- none);
- {$endif}
- Title:string='GL test';
-
- var dpy:PXDisplay;
- win,root:TWindow;
- screennum,ScreenWidth,ScreenHeight:integer;
- screen:PScreen;
- visual:PVisual;
- Event:TXEvent;
- {$ifdef ogles}
- swa:TXSetWindowAttributes;
- ecfg:EGLConfig;
- num_config:EGLint;
- esfc:EGLSurface;
- ectxt:EGLContext;
- edpy:EGLDisplay;
- mouse_accel_numerator,mouse_accel_denominator,mouse_threshold:integer;
- {$else}
- WinAttr:TXSetWindowAttributes;
- GLXCont:GLXContext;
- WindowTitleProperty:TXTextProperty;
- visualinfo:PXVisualInfo;
- ErrorBase,EventBase:integer;
- {$endif}
- WM_DELETE_WINDOW:TAtom;
-
- procedure DisableComposition;
- {$ifdef ogles}
- const one:integer=1;
- {$endif}
- var xclient:TXClientMessageEvent;
- wm_state,fullscreen{$ifdef ogles},non_composited{$endif}:TAtom;
- begin
- wm_state:=XInternAtom(dpy,'_NET_WM_STATE',false);
- fullscreen:=XInternAtom(dpy,'_NET_WN_STATE_FULLSCREEN',false);
- XChangeProperty(dpy,win,wm_state,XA_ATOM,32,PropModeReplace,@fullscreen,1);
- XFlush(dpy);
-
- {$ifdef ogles}
- non_composited:=XInternAtom(dpy,'_HILDON_NON_COMPOSITED_WINDOW',false);
- XChangeProperty(dpy,win,non_composited,XA_INTEGER,32,PropModeReplace,@one,1);
- XFlush(dpy);
- {$endif}
-
- xclient._type:=ClientMessage;
- xclient.window:=win;
- xclient.message_type:=XInternAtom(dpy,'_NET_WM_STATE',false);
- xclient.format:=32;
- xclient.data.l[0]:=1;
- xclient.data.l[1]:=XInternAtom(dpy,'_NET_WM_STATE_FULLSCREEN',false);
- xclient.data.l[2]:=0;
- xclient.data.l[3]:=0;
- xclient.data.l[4]:=0;
- XSendEvent(dpy,root,false,SubstructureRedirectMask or SubstructureNotifyMask,PXEvent(pointer(@xclient)));
- XFlush(dpy);
- end;
- procedure SetEmptyMouseCursor;
- const bm_no_data:array[0..7] of byte=(0,0,0,0,0,0,0,0);
- var bm_no:TPixmap;
- cmap:TColormap;
- no_ptr:TCursor;
- black,dummy:TXColor;
- begin
- cmap:=DefaultColormap(Dpy,screennum);
- XAllocNamedColor(Dpy,cmap,'black',@black,@dummy);
- bm_no:=XCreateBitmapFromData(Dpy,Win,POINTER(@bm_no_data),8,8);
- no_ptr:=XCreatePixmapCursor(Dpy,bm_no,bm_no,@black,@black,0,0);
- XDefineCursor(Dpy,Win,no_ptr);
- XFreeCursor(Dpy,no_ptr);
- if bm_no<>None then begin
- XFreePixmap(Dpy,bm_no);
- end;
- XFreeColors(Dpy,cmap,@black.pixel,1,0);
- end;
- begin
- CurrentTime:=0;
-
- dpy:=XOpenDisplay(nil);
- if not assigned(dpy) then begin
- writeln('Error: Cannot connect to X server');
- halt(1);
- end;
-
- root:=DefaultRootWindow(dpy);
- screen:=XDefaultScreenOfDisplay(dpy);
- if not assigned(screen) then begin
- writeln('Error: Cannot get default screen');
- halt(1);
- end;
-
- ScreenWidth:=screen^.Width;
- ScreenHeight:=screen^.Height;
- screennum:=XDefaultScreen(dpy);
-
- visual:=XDefaultVisualOfScreen(screen);
-
- CanvasWidth:=ScreenWidth;
- CanvasHeight:=ScreenHeight;
- {$ifdef ogles}
-
- swa.event_mask:=X_MASK;
- win:=XCreateWindow(dpy,root,0,0,ScreenWidth,ScreenHeight,0,CopyFromParent,InputOutput,Visual,CWEventMask,@swa);
-
- WM_DELETE_WINDOW:=XInternAtom(dpy,'WM_DELETE_WINDOW',FALSE);
- XSetWMProtocols(dpy,win,@WM_DELETE_WINDOW,1);
- XFlush(dpy);
-
- DisableComposition;
-
- XMapWindow(dpy,win);
- XFlush(dpy);
-
- DisableComposition;
- XSelectInput(Dpy,Win,FocusChangeMask or KeyPressMask or KeyReleaseMask or PropertyChangeMask or StructureNotifyMask or KeymapStateMask or PointerMotionMask or EnterWindowMask or LeaveWindowMask or ButtonPressMask or ButtonReleaseMask or ExposureMask);
-
- XStoreName(dpy,win,pchar(Title));
- XFlush(dpy);
- XMoveWindow(dpy,win,0,0);
- XRaiseWindow(dpy,win);
- //XWarpPointer(dpy,None,win,0,0,0,0,0,0);
- XFlush(dpy);
- SetEmptyMouseCursor;
-
- XGrabPointer(dpy,win,true,MOUSE_MASK,GrabModeAsync,GrabModeAsync,win,None,CurrentTime);
- XFlush(dpy);
-
- XGetPointerControl(dpy,@mouse_accel_numerator,@mouse_accel_denominator,@mouse_threshold);
- XFlush(dpy);
-
- XChangePointerControl(dpy,1,1,1,1,0);
- XFlush(dpy);
-
- XGrabKeyboard(dpy,win,false,GrabModeAsync,GrabModeAsync,CurrentTime);
- XFlush(dpy);
-
- edpy:=eglGetDisplay(dpy);
- if edpy=EGL_NO_DISPLAY then begin
- writeln('Error: Got no EGL display');
- halt(1);
- end;
- if eglInitialize(edpy,nil,nil)=0 then begin
- writeln('Error: Unable to initialize EGL');
- halt(1);
- end;
- num_config:=0;
- if eglChooseConfig(edpy,@Attr,@ecfg,1,@num_config)=0 then begin
- writeln('Error: Failed to choose config (',eglGetError,')');
- halt(1);
- end;
- if num_config<>1 then begin
- writeln('Error: Didn''t get exactly config but ',num_config);
- halt(1);
- end;
-
- esfc:=eglCreateWindowSurface(edpy,ecfg,win,nil);
- if esfc=EGL_NO_SURFACE then begin
- writeln('Error: Unable to create EGL surface (',eglGetError,')');
- halt(1);
- end;
-
- ectxt:=eglCreateContext(edpy,ecfg,EGL_NO_CONTEXT,@CtxAttr);
- if ectxt=EGL_NO_CONTEXT then begin
- writeln('Error: Unable to create EGL context (',eglGetError,')');
- halt(1);
- end;
-
- eglMakeCurrent(edpy,esfc,esfc,ectxt);
-
- {$else}
- InitGLX;
-
- if not glXQueryExtension(dpy,ErrorBase,EventBase) then begin
- writeln('Error: GLX extension not supported');
- halt(1);
- end;
-
- visualinfo:=glXChooseVisual(dpy,screennum,Attr);
- if not assigned(Visualinfo) THEN BEGIN
- writeln('Error: Could not find visual info');
- exit;
- end;
- WinAttr.colormap:=XCreateColormap(dpy,root,VisualInfo.Visual,AllocNone);
- WinAttr.border_pixel:=0;
- WinAttr.background_pixel:=0;
- WinAttr.event_mask:=X_MASK;
- WinAttr.override_redirect:=1;
- WinAttr.backing_store:=NotUseful;
- WinAttr.save_under:=0;
-
- Win:=XCreateWindow(dpy,root,0,0,ScreenWidth,ScreenHeight,0,VisualInfo.Depth,InputOutput,VisualInfo.Visual,CWOverrideRedirect or CWBackPixel or CWColormap or CWBackingStore or CWSaveUnder or CWEventMask,@WinAttr);
- XSelectInput(Dpy,Win,FocusChangeMask or KeyPressMask or KeyReleaseMask or PropertyChangeMask or StructureNotifyMask or KeymapStateMask or PointerMotionMask or EnterWindowMask or LeaveWindowMask or ButtonPressMask or ButtonReleaseMask or ExposureMask);
- XStringListToTextProperty(@Title,1,@WindowTitleProperty);
- XSetWMName(Dpy,Win,@WindowTitleProperty);
- glXCont:=glXCreateContext(Dpy,VisualInfo,none,true);
- if not assigned(glXCont) then begin
- writeln('Error: Could not create an OpenGL rendering context');
- halt(1);
- end;
- DisableComposition;
- XMapWindow(Dpy,Win);
- XFlush(dpy);
-
- DisableComposition;
- glXMakeCurrent(Dpy,Win,glXCont);
-
- SetEmptyMouseCursor;
-
- XMoveWindow(dpy,win,0,0);
- XRaiseWindow(dpy,win);
- XWarpPointer(dpy,None,win,0,0,0,0,0,0);
- XFlush(dpy);
- XF86VidmodeSetViewPort(dpy,screennum,0,0);
- XFlush(dpy);
-
- XGrabPointer(dpy,win,true,MOUSE_MASK,GrabModeAsync,GrabModeAsync,win,None,CurrentTime);
- XGrabKeyboard(dpy,win,false,GrabModeAsync,GrabModeAsync,CurrentTime);
- XFlush(dpy);
- XAutoRepeatOn(Dpy);
- XFlush(dpy);
-
- WM_DELETE_WINDOW:=XInternAtom(dpy,'WM_DELETE_WINDOW',FALSE);
- XSetWMProtocols(dpy,win,@WM_DELETE_WINDOW,1);
- XFlush(Dpy);
-
- CanvasWidth:=ScreenWidth;
- CanvasHeight:=ScreenHeight;
-
- if assigned(visual) then begin
- // Den Compiler befriedigen, so dass der kein Warning deswegen ausspuckt :)
- end;
- {$endif}
-
- Running:=true;
- ReturnCode:=0;
- {$ifndef ogles}
- if not (Load_GL_version_1_2 and Load_GL_version_1_3 and Load_GL_version_1_4 and Load_GL_version_2_0) then begin
- Running:=false;
- writeln('Error: Cannot load OpenGL 2.0 API');
- ReturnCode:=1;
- end;
- {$endif}
- if Running then begin
- Init;
- CurrentTime:=GetTime;
- end;
- while Running do begin
-
- while XPending(Dpy)>0 do begin
- XNextEvent(Dpy,@Event);
-
- case Event._type of
- ClientMessage:BEGIN
- if (Event.xclient.format=32) and (longword(Event.xclient.Data.l[0])=longword(WM_DELETE_WINDOW)) then begin
- Running:=false;
- end;
- end;
-
- Expose:begin
- end;
-
- ConfigureNotify:begin
- end;
-
- MotionNotify:begin
- // Running:=false;
- end;
-
- ButtonPress:begin
- Running:=false;
- end;
-
- ButtonRelease:begin
- Running:=false;
- end;
-
- KeyMapNotify:begin
- end;
-
- KeyPress:begin
- Running:=false;
- end;
-
- KeyRelease:begin
- Running:=false;
- end;
-
- end;
-
- end;
-
- CurrentTime:=GetTime;
- Render;
-
- {$ifdef ogles}
- eglSwapBuffers(edpy,esfc);
- {$else}
- glXSwapBuffers(dpy,win);
- {$endif}
- XFlush(dpy);
-
- end;
- if ReturnCode=0 then begin
- Done;
- end;
-
- {$ifdef ogles}
- XChangePointerControl(dpy,1,1,mouse_accel_numerator,mouse_accel_denominator,mouse_threshold);
- XUngrabPointer(dpy,CurrentTime);
- XUngrabKeyboard(dpy,CurrentTime);
- eglDestroyContext(edpy,ectxt);
- eglDestroySurface(edpy,esfc);
- eglTerminate(edpy);
- {$else}
- XUngrabPointer(dpy,CurrentTime);
- XUngrabKeyboard(dpy,CurrentTime);
- glXDestroyContext(dpy,glxCont);
- {$endif}
- XDestroyWindow(dpy,win);
- XCloseDisplay(dpy);
- halt(ReturnCode);
- end.
|