# Ported from the win32 and MFC OpenGL Samples. from pywin.mfc import docview import sys try: from OpenGL.GL import * from OpenGL.GLU import * except ImportError: print("The OpenGL extensions do not appear to be installed.") print("This Pythonwin demo can not run") sys.exit(1) import win32con import win32ui import win32api import timer PFD_TYPE_RGBA = 0 PFD_TYPE_COLORINDEX = 1 PFD_MAIN_PLANE = 0 PFD_OVERLAY_PLANE = 1 PFD_UNDERLAY_PLANE = (-1) PFD_DOUBLEBUFFER = 0x00000001 PFD_STEREO = 0x00000002 PFD_DRAW_TO_WINDOW = 0x00000004 PFD_DRAW_TO_BITMAP = 0x00000008 PFD_SUPPORT_GDI = 0x00000010 PFD_SUPPORT_OPENGL = 0x00000020 PFD_GENERIC_FORMAT = 0x00000040 PFD_NEED_PALETTE = 0x00000080 PFD_NEED_SYSTEM_PALETTE = 0x00000100 PFD_SWAP_EXCHANGE = 0x00000200 PFD_SWAP_COPY = 0x00000400 PFD_SWAP_LAYER_BUFFERS = 0x00000800 PFD_GENERIC_ACCELERATED = 0x00001000 PFD_DEPTH_DONTCARE = 0x20000000 PFD_DOUBLEBUFFER_DONTCARE = 0x40000000 PFD_STEREO_DONTCARE = 0x80000000 #threeto8 = [0, 0o111>>1, 0o222>>1, 0o333>>1, 0o444>>1, 0o555>>1, 0o666>>1, 0o377] threeto8 = [0, 73>>1, 146>>1, 219>>1, 292>>1, 365>>1, 438>>1, 255] twoto8 = [0, 0x55, 0xaa, 0xff] oneto8 = [0, 255] def ComponentFromIndex(i, nbits, shift): # val = (unsigned char) (i >> shift); val = (i >> shift) & 0xF; if nbits==1: val = val & 0x1 return oneto8[val] elif nbits==2: val = val & 0x3 return twoto8[val] elif nbits==3: val = val & 0x7 return threeto8[val] else: return 0; OpenGLViewParent=docview.ScrollView class OpenGLView(OpenGLViewParent): def PreCreateWindow(self, cc): self.HookMessage (self.OnSize, win32con.WM_SIZE) # An OpenGL window must be created with the following flags and must not # include CS_PARENTDC for the class style. Refer to SetPixelFormat # documentation in the "Comments" section for further information. style = cc[5] style = style | win32con.WS_CLIPSIBLINGS | win32con.WS_CLIPCHILDREN cc = cc[0], cc[1], cc[2], cc[3], cc[4], style, cc[6], cc[7], cc[8] cc = self._obj_.PreCreateWindow(cc) return cc def OnSize (self, params): lParam = params[3] cx = win32api.LOWORD(lParam) cy = win32api.HIWORD(lParam) glViewport(0, 0, cx, cy) if self.oldrect[2] > cx or self.oldrect[3] > cy: self.RedrawWindow() self.OnSizeChange(cx, cy) self.oldrect = self.oldrect[0], self.oldrect[1], cx, cy def OnInitialUpdate(self): self.SetScaleToFitSize((100,100)) # or SetScrollSizes() - A Pythonwin requirement return self._obj_.OnInitialUpdate() # return rc def OnCreate(self, cs): self.oldrect = self.GetClientRect() self._InitContexts() self.Init() def OnDestroy(self, msg): self.Term() self._DestroyContexts() return OpenGLViewParent.OnDestroy(self, msg) def OnDraw(self, dc): self.DrawScene() def OnEraseBkgnd(self, dc): return 1 # The OpenGL helpers def _SetupPixelFormat(self): dc = self.dc.GetSafeHdc() pfd = CreatePIXELFORMATDESCRIPTOR() pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER pfd.iPixelType = PFD_TYPE_RGBA pfd.cColorBits = 24 pfd.cDepthBits = 32 pfd.iLayerType = PFD_MAIN_PLANE pixelformat = ChoosePixelFormat(dc, pfd) SetPixelFormat(dc, pixelformat, pfd) self._CreateRGBPalette() def _CreateRGBPalette(self): dc = self.dc.GetSafeHdc() n = GetPixelFormat(dc) pfd = DescribePixelFormat(dc, n) if pfd.dwFlags & PFD_NEED_PALETTE: n = 1 << pfd.cColorBits pal = [] for i in range(n): this = ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift), \ ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift), \ ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift), \ 0 pal.append(this) hpal = win32ui.CreatePalette(pal) self.dc.SelectPalette(hpal, 0) self.dc.RealizePalette() def _InitContexts(self): self.dc = self.GetDC() self._SetupPixelFormat() hrc = wglCreateContext(self.dc.GetSafeHdc()) wglMakeCurrent(self.dc.GetSafeHdc(), hrc) def _DestroyContexts(self): hrc = wglGetCurrentContext() wglMakeCurrent(0, 0) if hrc: wglDeleteContext(hrc) # The methods to support OpenGL def DrawScene(self): assert 0, "You must override this method" def Init(self): assert 0, "You must override this method" def OnSizeChange(self, cx, cy): pass def Term(self): pass class TestView(OpenGLView): def OnSizeChange(self, right, bottom): glClearColor( 0.0, 0.0, 0.0, 1.0 ); glClearDepth( 1.0 ); glEnable(GL_DEPTH_TEST) glMatrixMode( GL_PROJECTION ) if bottom: aspect = right / bottom else: aspect = 0 # When window created! glLoadIdentity() gluPerspective( 45.0, aspect, 3.0, 7.0 ) glMatrixMode( GL_MODELVIEW ) near_plane = 3.0; far_plane = 7.0; maxObjectSize = 3.0; self.radius = near_plane + maxObjectSize/2.0; def Init(self): pass def DrawScene(self): glClearColor(0.0, 0.0, 0.0, 1.0) glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) glPushMatrix() glTranslatef(0.0, 0.0, -self.radius); self._DrawCone() self._DrawPyramid() glPopMatrix() glFinish() SwapBuffers( wglGetCurrentDC() ) def _DrawCone(self): glColor3f(0.0, 1.0, 0.0) glPushMatrix() glTranslatef(-1.0, 0.0, 0.0); quadObj = gluNewQuadric(); gluQuadricDrawStyle(quadObj, GLU_FILL); gluQuadricNormals(quadObj, GLU_SMOOTH); gluCylinder(quadObj, 1.0, 0.0, 1.0, 20, 10); # gluDeleteQuadric(quadObj); glPopMatrix(); def _DrawPyramid(self): glPushMatrix() glTranslatef(1.0, 0.0, 0.0) glBegin(GL_TRIANGLE_FAN) glColor3f(1.0, 0.0, 0.0) glVertex3f(0.0, 1.0, 0.0) glColor3f(0.0, 1.0, 0.0) glVertex3f(-1.0, 0.0, 0.0) glColor3f(0.0, 0.0, 1.0) glVertex3f(0.0, 0.0, 1.0) glColor3f(0.0, 1.0, 0.0) glVertex3f(1.0, 0.0, 0.0) glEnd() glPopMatrix() class CubeView(OpenGLView): def OnSizeChange(self, right, bottom): glClearColor( 0.0, 0.0, 0.0, 1.0 ); glClearDepth( 1.0 ); glEnable(GL_DEPTH_TEST) glMatrixMode( GL_PROJECTION ) if bottom: aspect = right / bottom else: aspect = 0 # When window created! glLoadIdentity() gluPerspective( 45.0, aspect, 3.0, 7.0 ) glMatrixMode( GL_MODELVIEW ) near_plane = 3.0; far_plane = 7.0; maxObjectSize = 3.0; self.radius = near_plane + maxObjectSize/2.0; def Init(self): self.busy = 0 self.wAngleY = 10.0 self.wAngleX = 1.0 self.wAngleZ = 5.0 self.timerid = timer.set_timer (150, self.OnTimer) def OnTimer(self, id, timeVal): self.DrawScene() def Term(self): timer.kill_timer(self.timerid) def DrawScene(self): if self.busy: return self.busy = 1 glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0, 0.0, -self.radius); glRotatef(self.wAngleX, 1.0, 0.0, 0.0); glRotatef(self.wAngleY, 0.0, 1.0, 0.0); glRotatef(self.wAngleZ, 0.0, 0.0, 1.0); self.wAngleX = self.wAngleX + 1.0 self.wAngleY = self.wAngleY + 10.0 self.wAngleZ = self.wAngleZ + 5.0; glBegin(GL_QUAD_STRIP); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glColor3f(1.0, 1.0, 1.0); glVertex3f(0.5, 0.5, 0.5); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.5, -0.5, 0.5); glColor3f(0.0, 1.0, 1.0); glVertex3f(0.5, 0.5, -0.5); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, -0.5, -0.5); glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glEnd(); glBegin(GL_QUADS); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 1.0, 1.0); glVertex3f(0.5, 0.5, 0.5); glColor3f(0.0, 1.0, 1.0); glVertex3f(0.5, 0.5, -0.5); glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); glEnd(); glBegin(GL_QUADS); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.5, -0.5, 0.5); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, -0.5, -0.5); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5); glEnd(); glPopMatrix(); glFinish(); SwapBuffers(wglGetCurrentDC()); self.busy = 0 def test(): template = docview.DocTemplate(None, None, None, CubeView ) # template = docview.DocTemplate(None, None, None, TestView ) template.OpenDocumentFile(None) if __name__=='__main__': test()