openGLDemo.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. # Ported from the win32 and MFC OpenGL Samples.
  2. from pywin.mfc import docview
  3. import sys
  4. try:
  5. from OpenGL.GL import *
  6. from OpenGL.GLU import *
  7. except ImportError:
  8. print("The OpenGL extensions do not appear to be installed.")
  9. print("This Pythonwin demo can not run")
  10. sys.exit(1)
  11. import win32con
  12. import win32ui
  13. import win32api
  14. import timer
  15. PFD_TYPE_RGBA = 0
  16. PFD_TYPE_COLORINDEX = 1
  17. PFD_MAIN_PLANE = 0
  18. PFD_OVERLAY_PLANE = 1
  19. PFD_UNDERLAY_PLANE = (-1)
  20. PFD_DOUBLEBUFFER = 0x00000001
  21. PFD_STEREO = 0x00000002
  22. PFD_DRAW_TO_WINDOW = 0x00000004
  23. PFD_DRAW_TO_BITMAP = 0x00000008
  24. PFD_SUPPORT_GDI = 0x00000010
  25. PFD_SUPPORT_OPENGL = 0x00000020
  26. PFD_GENERIC_FORMAT = 0x00000040
  27. PFD_NEED_PALETTE = 0x00000080
  28. PFD_NEED_SYSTEM_PALETTE = 0x00000100
  29. PFD_SWAP_EXCHANGE = 0x00000200
  30. PFD_SWAP_COPY = 0x00000400
  31. PFD_SWAP_LAYER_BUFFERS = 0x00000800
  32. PFD_GENERIC_ACCELERATED = 0x00001000
  33. PFD_DEPTH_DONTCARE = 0x20000000
  34. PFD_DOUBLEBUFFER_DONTCARE = 0x40000000
  35. PFD_STEREO_DONTCARE = 0x80000000
  36. #threeto8 = [0, 0o111>>1, 0o222>>1, 0o333>>1, 0o444>>1, 0o555>>1, 0o666>>1, 0o377]
  37. threeto8 = [0, 73>>1, 146>>1, 219>>1, 292>>1, 365>>1, 438>>1, 255]
  38. twoto8 = [0, 0x55, 0xaa, 0xff]
  39. oneto8 = [0, 255]
  40. def ComponentFromIndex(i, nbits, shift):
  41. # val = (unsigned char) (i >> shift);
  42. val = (i >> shift) & 0xF;
  43. if nbits==1:
  44. val = val & 0x1
  45. return oneto8[val]
  46. elif nbits==2:
  47. val = val & 0x3
  48. return twoto8[val]
  49. elif nbits==3:
  50. val = val & 0x7
  51. return threeto8[val]
  52. else:
  53. return 0;
  54. OpenGLViewParent=docview.ScrollView
  55. class OpenGLView(OpenGLViewParent):
  56. def PreCreateWindow(self, cc):
  57. self.HookMessage (self.OnSize, win32con.WM_SIZE)
  58. # An OpenGL window must be created with the following flags and must not
  59. # include CS_PARENTDC for the class style. Refer to SetPixelFormat
  60. # documentation in the "Comments" section for further information.
  61. style = cc[5]
  62. style = style | win32con.WS_CLIPSIBLINGS | win32con.WS_CLIPCHILDREN
  63. cc = cc[0], cc[1], cc[2], cc[3], cc[4], style, cc[6], cc[7], cc[8]
  64. cc = self._obj_.PreCreateWindow(cc)
  65. return cc
  66. def OnSize (self, params):
  67. lParam = params[3]
  68. cx = win32api.LOWORD(lParam)
  69. cy = win32api.HIWORD(lParam)
  70. glViewport(0, 0, cx, cy)
  71. if self.oldrect[2] > cx or self.oldrect[3] > cy:
  72. self.RedrawWindow()
  73. self.OnSizeChange(cx, cy)
  74. self.oldrect = self.oldrect[0], self.oldrect[1], cx, cy
  75. def OnInitialUpdate(self):
  76. self.SetScaleToFitSize((100,100)) # or SetScrollSizes() - A Pythonwin requirement
  77. return self._obj_.OnInitialUpdate()
  78. # return rc
  79. def OnCreate(self, cs):
  80. self.oldrect = self.GetClientRect()
  81. self._InitContexts()
  82. self.Init()
  83. def OnDestroy(self, msg):
  84. self.Term()
  85. self._DestroyContexts()
  86. return OpenGLViewParent.OnDestroy(self, msg)
  87. def OnDraw(self, dc):
  88. self.DrawScene()
  89. def OnEraseBkgnd(self, dc):
  90. return 1
  91. # The OpenGL helpers
  92. def _SetupPixelFormat(self):
  93. dc = self.dc.GetSafeHdc()
  94. pfd = CreatePIXELFORMATDESCRIPTOR()
  95. pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER
  96. pfd.iPixelType = PFD_TYPE_RGBA
  97. pfd.cColorBits = 24
  98. pfd.cDepthBits = 32
  99. pfd.iLayerType = PFD_MAIN_PLANE
  100. pixelformat = ChoosePixelFormat(dc, pfd)
  101. SetPixelFormat(dc, pixelformat, pfd)
  102. self._CreateRGBPalette()
  103. def _CreateRGBPalette(self):
  104. dc = self.dc.GetSafeHdc()
  105. n = GetPixelFormat(dc)
  106. pfd = DescribePixelFormat(dc, n)
  107. if pfd.dwFlags & PFD_NEED_PALETTE:
  108. n = 1 << pfd.cColorBits
  109. pal = []
  110. for i in range(n):
  111. this = ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift), \
  112. ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift), \
  113. ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift), \
  114. 0
  115. pal.append(this)
  116. hpal = win32ui.CreatePalette(pal)
  117. self.dc.SelectPalette(hpal, 0)
  118. self.dc.RealizePalette()
  119. def _InitContexts(self):
  120. self.dc = self.GetDC()
  121. self._SetupPixelFormat()
  122. hrc = wglCreateContext(self.dc.GetSafeHdc())
  123. wglMakeCurrent(self.dc.GetSafeHdc(), hrc)
  124. def _DestroyContexts(self):
  125. hrc = wglGetCurrentContext()
  126. wglMakeCurrent(0, 0)
  127. if hrc: wglDeleteContext(hrc)
  128. # The methods to support OpenGL
  129. def DrawScene(self):
  130. assert 0, "You must override this method"
  131. def Init(self):
  132. assert 0, "You must override this method"
  133. def OnSizeChange(self, cx, cy):
  134. pass
  135. def Term(self):
  136. pass
  137. class TestView(OpenGLView):
  138. def OnSizeChange(self, right, bottom):
  139. glClearColor( 0.0, 0.0, 0.0, 1.0 );
  140. glClearDepth( 1.0 );
  141. glEnable(GL_DEPTH_TEST)
  142. glMatrixMode( GL_PROJECTION )
  143. if bottom:
  144. aspect = right / bottom
  145. else:
  146. aspect = 0 # When window created!
  147. glLoadIdentity()
  148. gluPerspective( 45.0, aspect, 3.0, 7.0 )
  149. glMatrixMode( GL_MODELVIEW )
  150. near_plane = 3.0;
  151. far_plane = 7.0;
  152. maxObjectSize = 3.0;
  153. self.radius = near_plane + maxObjectSize/2.0;
  154. def Init(self):
  155. pass
  156. def DrawScene(self):
  157. glClearColor(0.0, 0.0, 0.0, 1.0)
  158. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
  159. glPushMatrix()
  160. glTranslatef(0.0, 0.0, -self.radius);
  161. self._DrawCone()
  162. self._DrawPyramid()
  163. glPopMatrix()
  164. glFinish()
  165. SwapBuffers( wglGetCurrentDC() )
  166. def _DrawCone(self):
  167. glColor3f(0.0, 1.0, 0.0)
  168. glPushMatrix()
  169. glTranslatef(-1.0, 0.0, 0.0);
  170. quadObj = gluNewQuadric();
  171. gluQuadricDrawStyle(quadObj, GLU_FILL);
  172. gluQuadricNormals(quadObj, GLU_SMOOTH);
  173. gluCylinder(quadObj, 1.0, 0.0, 1.0, 20, 10);
  174. # gluDeleteQuadric(quadObj);
  175. glPopMatrix();
  176. def _DrawPyramid(self):
  177. glPushMatrix()
  178. glTranslatef(1.0, 0.0, 0.0)
  179. glBegin(GL_TRIANGLE_FAN)
  180. glColor3f(1.0, 0.0, 0.0)
  181. glVertex3f(0.0, 1.0, 0.0)
  182. glColor3f(0.0, 1.0, 0.0)
  183. glVertex3f(-1.0, 0.0, 0.0)
  184. glColor3f(0.0, 0.0, 1.0)
  185. glVertex3f(0.0, 0.0, 1.0)
  186. glColor3f(0.0, 1.0, 0.0)
  187. glVertex3f(1.0, 0.0, 0.0)
  188. glEnd()
  189. glPopMatrix()
  190. class CubeView(OpenGLView):
  191. def OnSizeChange(self, right, bottom):
  192. glClearColor( 0.0, 0.0, 0.0, 1.0 );
  193. glClearDepth( 1.0 );
  194. glEnable(GL_DEPTH_TEST)
  195. glMatrixMode( GL_PROJECTION )
  196. if bottom:
  197. aspect = right / bottom
  198. else:
  199. aspect = 0 # When window created!
  200. glLoadIdentity()
  201. gluPerspective( 45.0, aspect, 3.0, 7.0 )
  202. glMatrixMode( GL_MODELVIEW )
  203. near_plane = 3.0;
  204. far_plane = 7.0;
  205. maxObjectSize = 3.0;
  206. self.radius = near_plane + maxObjectSize/2.0;
  207. def Init(self):
  208. self.busy = 0
  209. self.wAngleY = 10.0
  210. self.wAngleX = 1.0
  211. self.wAngleZ = 5.0
  212. self.timerid = timer.set_timer (150, self.OnTimer)
  213. def OnTimer(self, id, timeVal):
  214. self.DrawScene()
  215. def Term(self):
  216. timer.kill_timer(self.timerid)
  217. def DrawScene(self):
  218. if self.busy: return
  219. self.busy = 1
  220. glClearColor(0.0, 0.0, 0.0, 1.0);
  221. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  222. glPushMatrix();
  223. glTranslatef(0.0, 0.0, -self.radius);
  224. glRotatef(self.wAngleX, 1.0, 0.0, 0.0);
  225. glRotatef(self.wAngleY, 0.0, 1.0, 0.0);
  226. glRotatef(self.wAngleZ, 0.0, 0.0, 1.0);
  227. self.wAngleX = self.wAngleX + 1.0
  228. self.wAngleY = self.wAngleY + 10.0
  229. self.wAngleZ = self.wAngleZ + 5.0;
  230. glBegin(GL_QUAD_STRIP);
  231. glColor3f(1.0, 0.0, 1.0);
  232. glVertex3f(-0.5, 0.5, 0.5);
  233. glColor3f(1.0, 0.0, 0.0);
  234. glVertex3f(-0.5, -0.5, 0.5);
  235. glColor3f(1.0, 1.0, 1.0);
  236. glVertex3f(0.5, 0.5, 0.5);
  237. glColor3f(1.0, 1.0, 0.0);
  238. glVertex3f(0.5, -0.5, 0.5);
  239. glColor3f(0.0, 1.0, 1.0);
  240. glVertex3f(0.5, 0.5, -0.5);
  241. glColor3f(0.0, 1.0, 0.0);
  242. glVertex3f(0.5, -0.5, -0.5);
  243. glColor3f(0.0, 0.0, 1.0);
  244. glVertex3f(-0.5, 0.5, -0.5);
  245. glColor3f(0.0, 0.0, 0.0);
  246. glVertex3f(-0.5, -0.5, -0.5);
  247. glColor3f(1.0, 0.0, 1.0);
  248. glVertex3f(-0.5, 0.5, 0.5);
  249. glColor3f(1.0, 0.0, 0.0);
  250. glVertex3f(-0.5, -0.5, 0.5);
  251. glEnd();
  252. glBegin(GL_QUADS);
  253. glColor3f(1.0, 0.0, 1.0);
  254. glVertex3f(-0.5, 0.5, 0.5);
  255. glColor3f(1.0, 1.0, 1.0);
  256. glVertex3f(0.5, 0.5, 0.5);
  257. glColor3f(0.0, 1.0, 1.0);
  258. glVertex3f(0.5, 0.5, -0.5);
  259. glColor3f(0.0, 0.0, 1.0);
  260. glVertex3f(-0.5, 0.5, -0.5);
  261. glEnd();
  262. glBegin(GL_QUADS);
  263. glColor3f(1.0, 0.0, 0.0);
  264. glVertex3f(-0.5, -0.5, 0.5);
  265. glColor3f(1.0, 1.0, 0.0);
  266. glVertex3f(0.5, -0.5, 0.5);
  267. glColor3f(0.0, 1.0, 0.0);
  268. glVertex3f(0.5, -0.5, -0.5);
  269. glColor3f(0.0, 0.0, 0.0);
  270. glVertex3f(-0.5, -0.5, -0.5);
  271. glEnd();
  272. glPopMatrix();
  273. glFinish();
  274. SwapBuffers(wglGetCurrentDC());
  275. self.busy = 0
  276. def test():
  277. template = docview.DocTemplate(None, None, None, CubeView )
  278. # template = docview.DocTemplate(None, None, None, TestView )
  279. template.OpenDocumentFile(None)
  280. if __name__=='__main__':
  281. test()