glxtest.pp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. {
  2. GLX demo for FreePascal
  3. 2005 Bart Tierens, [email protected]
  4. This program is in the public domain
  5. Warning: This demo works only with FreePascal 2.1 and better, due to changes to the glx header
  6. }
  7. program glxTest;
  8. {$MODE delphi}
  9. uses glx,unix,x,xlib,xutil,gl,glu;
  10. var
  11. { Attributes to choose context with glXChooseVisual }
  12. Attr: Array[0..8] of integer = (
  13. GLX_RGBA,
  14. GLX_RED_SIZE, 1,
  15. GLX_GREEN_SIZE, 1,
  16. GLX_BLUE_SIZE, 1,
  17. GLX_DOUBLEBUFFER,
  18. none);
  19. { Attributes to choose context with glXChooseFBConfig.
  20. Similar to Attr, but not exactly compatible. }
  21. AttrFB: Array[0..10] of integer = (
  22. GLX_X_RENDERABLE, 1 { true },
  23. GLX_RED_SIZE, 1,
  24. GLX_GREEN_SIZE, 1,
  25. GLX_BLUE_SIZE, 1,
  26. GLX_DOUBLEBUFFER, 1 { true },
  27. none);
  28. visinfo: PXVisualInfo;
  29. cm: TColormap;
  30. winAttr: TXSetWindowAttributes;
  31. glXCont: GLXContext;
  32. dpy: PDisplay;
  33. win: TWindow;
  34. procedure redraw();
  35. begin
  36. glClear(GL_COLOR_BUFFER_BIT);
  37. glTranslatef(-0.5,-0.5,-2);
  38. glBegin(GL_QUADS);
  39. glColor3f(1,0,0);
  40. glVertex3f(0,0,0);
  41. glColor3f(0,1,0);
  42. glVertex3f(1,0,0);
  43. glColor3f(0,0,1);
  44. glVertex3f(1,1,0);
  45. glColor3f(1,1,1);
  46. glVertex3f(0,1,0);
  47. glEnd();
  48. glXSwapBuffers(dpy, win); //Swap the buffers
  49. end;
  50. procedure resize(width,height: integer);
  51. begin
  52. glViewport(0,0,width,height);
  53. glMatrixMode(GL_PROJECTION);
  54. glLoadIdentity();
  55. gluPerspective(45,width/height,0.1,200);
  56. glMatrixMode(GL_MODELVIEW);
  57. end;
  58. procedure loop();
  59. var
  60. event: TXEvent;
  61. begin
  62. while true do
  63. begin
  64. XNextEvent(dpy,@event);
  65. case event._type of
  66. Expose: redraw();
  67. ConfigureNotify: resize(event.xconfigure.width,event.xconfigure.height);
  68. KeyPress: halt(1);
  69. end;
  70. end;
  71. end;
  72. procedure Error(const S: string);
  73. begin
  74. Writeln(ErrOutput, 'Error: ', S);
  75. Halt(1);
  76. end;
  77. var
  78. window_title_property: TXTextProperty;
  79. title: String;
  80. FBConfig: TGLXFBConfig;
  81. FBConfigs: PGLXFBConfig;
  82. FBConfigsCount: Integer;
  83. { Used with glXCreateContextAttribsARB to select 3.0 forward-compatible context }
  84. Context30Forward: array [0..6] of Integer =
  85. ( GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
  86. GLX_CONTEXT_MINOR_VERSION_ARB, 0,
  87. GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
  88. None
  89. );
  90. begin
  91. dpy := XOpenDisplay(nil);
  92. if(dpy = nil) then
  93. Error('Could not connect to X server');
  94. if not GLX_version_1_0(dpy) then
  95. Error('GLX extension not supported');
  96. if GLX_version_1_3(dpy) then
  97. begin
  98. { use approach recommended since glX 1.3 }
  99. FBConfigs := glXChooseFBConfig(dpy, DefaultScreen(dpy), AttrFB, FBConfigsCount);
  100. if FBConfigsCount = 0 then
  101. Error('Could not find FB config');
  102. { just choose the first FB config from the FBConfigs list.
  103. More involved selection possible. }
  104. FBConfig := FBConfigs^;
  105. visinfo := glXGetVisualFromFBConfig(dpy, FBConfig);
  106. end else
  107. begin
  108. visinfo := glXChooseVisual(dpy, DefaultScreen(dpy), Attr);
  109. end;
  110. if(visinfo = nil) then
  111. Error('Could not find visual');
  112. //Create a new colormap
  113. cm := XCreateColormap(dpy,RootWindow(dpy,visinfo.screen),visinfo.visual,AllocNone);
  114. winAttr.colormap := cm;
  115. winAttr.border_pixel := 0;
  116. winAttr.background_pixel := 0;
  117. winAttr.event_mask := ExposureMask or ButtonPressMask or StructureNotifyMask or KeyPressMask;
  118. //Create a window
  119. win := XCreateWindow(dpy,RootWindow(dpy,visinfo.screen),0,0,640,480,0,visinfo.depth,InputOutput,visinfo.visual,CWBorderPixel or CWColormap or CWEventMask,@winAttr);
  120. title := 'FreePascal GLX demo --------- Press any key to exit';
  121. XStringListToTextProperty(@title,1,@window_title_property);
  122. XSetWMName(dpy,win,@window_title_property);
  123. //Create an OpenGL rendering context
  124. if GLX_version_1_3(dpy) then
  125. begin
  126. writeln('Using GLX 1.3 code path');
  127. { Uncomment two lines below to use GLX_ARB_create_context extension
  128. to request OpenGL 3.0 forward-compatible context. This is just
  129. a simple example, be aware of some shortcomings:
  130. - In case of failure, glXCreateContextAttribsARB not only returns nil,
  131. it also raises X error that by default simply breaks your program.
  132. In a real program, you probably want to catch it (use XSetErrorHandler
  133. to assign custom error handler) and retry glXCreateContextAttribsARB
  134. with less restrictive attributes.
  135. - In case of success, you will just see a black screen.
  136. That's because the Redraw and Resize procedures defined in this program
  137. actually use deprecated OpenGL calls, that are *not* available in
  138. a forward-compatible context (glGetError would show actual errors). }
  139. // if GLX_ARB_create_context(dpy, DefaultScreen(dpy)) then
  140. // glXCont := glXCreateContextAttribsARB(dpy, FBConfig, 0, true, Context30Forward) else
  141. { use approach recommended since glX 1.3 }
  142. glXCont := glXCreateNewContext(dpy, FBConfig, GLX_RGBA_TYPE, 0, true);
  143. end else
  144. glXCont := glXCreateContext(dpy, visinfo, none, true);
  145. if(glXCont = nil) then
  146. Error('Could not create an OpenGL rendering context');
  147. //Make it current
  148. glXMakeCurrent(dpy,win,glXCont);
  149. //Map the window on the display
  150. XMapWindow(dpy,win);
  151. loop();
  152. end.