Выкладываю полный код.
{$REGION 'Types OpenGL'} type GLenum = Cardinal; GLboolean = BYTEBOOL; GLbitfield = Cardinal; GLbyte = Shortint; GLshort = SmallInt; GLint = Integer; GLsizei = Integer; GLubyte = Byte; GLushort = Word; GLuint = Cardinal; GLfloat = Single; GLclampf = Single; GLdouble = Double; GLclampd = Double; GLvoid = Pointer; GLint64 = Int64; PGLenum = ^GLenum; PGLboolean = ^GLboolean; PGLbitfield = ^GLbitfield; PGLbyte = ^GLbyte; PGLshort = ^GLshort; PGLint = ^GLint; PGLsizei = ^GLsizei; PGLubyte = ^GLubyte; PGLushort = ^GLushort; PGLuint = ^GLuint; PGLfloat = ^GLfloat; PGLclampf = ^GLclampf; PGLdouble = ^GLdouble; PGLclampd = ^GLclampd; PGLvoid = ^GLvoid; PGLint64 = ^GLint64; const GL_TRUE = 1; GL_FALSE = 0; {$ENDREGION} type TOpenGLWFunc = class(TObject) wglGetProcAddress: function(ProcName: PAnsiChar): Pointer; stdcall; wglSetPixelFormat: function(DC: HDC; PixelFormat: Integer; FormatDef: PPixelFormatDescriptor): Boolean; stdcall; wglSwapBuffers: function(DC: HDC): BOOL; stdcall; wglDescribePixelFormat: function(DC: HDC; p2: Integer; p3: UINT; var p4: TPixelFormatDescriptor): Boolean; stdcall; wglGetPixelFormat: function(DC: HDC): Integer; stdcall; wglGetDefaultProcAddress: function(ProcName: PAnsiChar): Pointer; stdcall; wglChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; stdcall; wglCopyContext: function(p1: HGLRC; p2: HGLRC; p3: Cardinal): Boolean; stdcall; wglCreateContext: function(DC: HDC): HGLRC; stdcall; wglCreateLayerContext: function(p1: HDC; p2: Integer): HGLRC; stdcall; wglDeleteContext: function(p1: HGLRC): Boolean; stdcall; wglDescribeLayerPlane: function(p1: HDC; p2, p3: Integer; p4: Cardinal; p5: PLayerPlaneDescriptor): Boolean; stdcall; wglGetCurrentContext: function: HGLRC; stdcall; wglGetCurrentDC: function: HDC; stdcall; wglGetLayerPaletteEntries: function(p1: HDC; p2, p3, p4: Integer; var pcr): Integer; stdcall; wglMakeCurrent: function(DC: HDC; p2: HGLRC): Boolean; stdcall; wglRealizeLayerPalette: function(p1: HDC; p2: Integer; p3: Boolean): Boolean; stdcall; wglSetLayerPaletteEntries: function(p1: HDC; p2, p3, p4: Integer; var pcr): Integer; stdcall; wglShareLists: function(p1, p2: HGLRC): Boolean; stdcall; wglSwapLayerBuffers: function(p1: HDC; p2: Cardinal): Boolean; stdcall; wglUseFontBitmapsA: function(DC: HDC; p2, p3, p4: Cardinal): Boolean; stdcall; wglUseFontBitmapsW: function(DC: HDC; p2, p3, p4: Cardinal): Boolean; stdcall; // WTF // wglSwapMultipleBuffers: function(p1: UINT; // const p2: PWGLSWAP): Cardinal; stdcall; // wglUseFontOutlineA // wgluseFontOutlineW end; TOpenGLFunc = class(TObject) glGetString: function(name: GLenum): PAnsiChar; stdcall; glBegin: procedure(const mode: GLenum); stdcall; glEnd: procedure; stdcall; glClearColor: procedure(const red, green, blue, alpha: GLfloat); stdcall; glColor3f: procedure(const red, green, blue: GLfloat); stdcall; glColor3fv: procedure(const v: PGLfloat); stdcall; glVertex2f: procedure(const x, y: GLfloat); stdcall; glVertex2fv: procedure(const v: PGLfloat); stdcall; glLoadIdentity: procedure; stdcall; glMatrixMode: procedure(mode: GLenum); stdcall; glOrtho: procedure(left, right, bottom, top, zNear, zFar: GLdouble); stdcall; glColor4fv: procedure(const v: PGLfloat); stdcall; glColor4f: procedure(x, y, z, w: GLfloat); stdcall; glClear: procedure(mask: GLenum); stdcall; glCompressedTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width, height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); stdcall; glTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLint; width, height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); stdcall; glGenTextures: procedure(n: GLsizei; textures: PGLuint); stdcall; glBindTexture: procedure(target: GLenum; texture: GLuint); stdcall; glPixelStoref: procedure(pname: GLenum; param: GLfloat); stdcall; glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); stdcall; glTexCoord2f: procedure(s, T: GLfloat); stdcall; glTexCoord2fv: procedure(const v: PGLfloat); stdcall; glEnable: procedure(cap: GLenum); stdcall; glDisable: procedure(cap: GLenum); stdcall; glBlendFunc: procedure(sfactor: GLenum; dfactor: GLenum); stdcall; glTranslatef: procedure(x, y, z: GLfloat); stdcall; glScalef: procedure(x, y, z: GLfloat); stdcall; glRotatef: procedure(angle, x, y, z: GLfloat); stdcall; glTexCoordPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const Pointer: GLvoid); stdcall; glVertexPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const Pointer: GLvoid); stdcall; glNormalPointer: procedure(_type: GLenum; stride: GLsizei; const Pointer: GLvoid); stdcall; glEnableClientState: procedure(cap: GLenum); stdcall; glDisableClientState: procedure(cap: GLenum); stdcall; glDrawElements: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: GLvoid); stdcall; glColorPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const Pointer: GLvoid); stdcall; glGenBuffers: procedure(n: GLsizei; buffers: PGLuint); stdcall; glDeleteBuffers: procedure(n: GLsizei; const buffers: PGLuint); stdcall; glBindBuffer: procedure(target: GLenum; buffer: GLuint); stdcall; glBufferData: procedure(target: GLenum; size: GLsizei; const data: GLvoid; usage: GLenum); stdcall; glMapBuffer: function(target: GLenum; access: GLenum): GLvoid; stdcall; glUnmapBuffer: function(target: GLenum): GLboolean; stdcall; glPushMatrix: procedure; stdcall; glPopMatrix: procedure; stdcall; glFrontFace: procedure(mode: GLenum); stdcall; glGetFloatv: procedure(pname: GLenum; params: PGLfloat); stdcall; glGetIntegerv: procedure(pname: GLenum; params: PGLint); stdcall; glTexEnvf: procedure(target, pname: GLenum; param: GLfloat); stdcall; glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); stdcall; glViewport: procedure(const x, y: GLint; const width, height: GLsizei); stdcall; glTranslated: procedure(x, y, z: GLdouble); stdcall; glScaled: procedure(x, y, z: GLdouble); stdcall; glRotated: procedure(angle, x, y, z: GLdouble); stdcall; glPolygonMode: procedure(face: GLenum; mode: GLenum); stdcall; glLineWidth: procedure(width: GLfloat); stdcall; glPointSize: procedure(size: GLfloat); stdcall; end; TOpenGLWExtFunc = class(TObject) wglCreateContextAttribsARB: function(hDC: LongWord; hShareContext: LongWord; const attribList: PGLint): LongWord; stdcall; wglChoosePixelFormatARB: function(hdc: LongWord; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): LongBool; stdcall; wglGetExtensionsStringARB: function(hdc: LongWord): PAnsiChar; stdcall; wglGetPixelFormatAttribivARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): Boolean; stdcall; wglMakeContextCurrentARB: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): Boolean; stdcall; wglGetCurrentReadDCARB: function(): HDC; stdcall; end; TOpenGLExt = class(TObject) strict private HGLRCARB: Cardinal; FRtti: TRttiContext; FLib: NativeUInt; function GetProc(const Name: PAnsiChar): Pointer; function Load(const Obj: TObject): Boolean; public func: TOpenGLFunc; wfunc: TOpenGLWFunc; wextfunc: TOpenGLWExtFunc; constructor Create(const DC: Cardinal); procedure BeforeDestruction; override; end;
procedure TOpenGLExt.BeforeDestruction; begin inherited; Assert(wfunc.wglMakeCurrent(0, 0), 'wglMakeCurrent = False'); Assert(wfunc.wglDeleteContext(HGLRCARB), 'wglMakeCurrent = False'); FRtti.Free; func.Free; wfunc.Free; wextfunc.Free; FreeLibrary(HMODULE(FLib)); end; constructor TOpenGLExt.Create(const DC: Cardinal); {$J+} const pfd: TPixelFormatDescriptor = (nSize: SizeOf(TPixelFormatDescriptor); nVersion: 1; dwFlags: PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; iPixelType: PFD_TYPE_RGBA; cColorBits: 32; cRedBits: 0; cRedShift: 0; cGreenBits: 0; cGreenShift: 0; cBlueBits: 0; cBlueShift: 0; cAlphaBits: 0; cAlphaShift: 0; cAccumBits: 0; cAccumRedBits: 0; cAccumGreenBits: 0; cAccumBlueBits: 0; cAccumAlphaBits: 0; cDepthBits: 24; cStencilBits: 8; cAuxBuffers: 0; iLayerType: PFD_MAIN_PLANE; bReserved: 0; dwLayerMask: 0; dwVisibleMask: 0; dwDamageMask: 0); PixelaAttribList: array [0..14] of Integer = ( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_PIXEL_TYPE_ARB, $202B, WGL_COLOR_BITS_ARB, 32, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, 0); ContextAttribList: array [0..6] of Integer = (WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_FLAGS_ARB, $0002, 0); PixelFormat: Integer = 0; PixelFormatARB: Integer = 0; NumFormatsARB: Integer = 0; HGLRC: Integer = 0; // TempWnd: Cardinal = 0; // TempDC: Cardinal = 0; {$J-} var Ext, ExtARB: String; begin inherited Create; FRtti := TRttiContext.Create; // TempWnd := CreateWindow('BUTTON', nil, 0, 0, 0, 0, 0, 0, 0, 0, nil); // Assert(TempWnd <> 0, 'Temp windows is not created'); // TempDC := GetDC(tempWnd); // Assert(TempDC <> 0, 'Temp dc windows is not created'); func := TOpenGLFunc.Create; wfunc := TOpenGLWFunc.Create; wextfunc := TOpenGLWExtFunc.Create; FLib := LoadLibrary('opengl32.dll'); Assert(FLib <> 0, 'LoadLibrary = 0'); Assert(Load(wfunc), 'Load(wfunc) = False'); PixelFormat := ChoosePixelFormat(DC, @pfd); Assert(PixelFormat <> 0, 'ChoosePixelFormat = 0'); Assert(SetPixelFormat(DC, PixelFormat, @pfd), 'SetPixelFormat = False'); HGLRC := wfunc.wglCreateContext(DC); Assert(HGLRC <> 0, 'HGLRC = 0'); HGLRCARB := HGLRC; Assert(wfunc.wglMakeCurrent(DC, HGLRC), 'wglMakeCurrent = False'); Assert(Load(func), 'Load(func) = False'); Writeln(func.glGetString(GL_VENDOR)); Writeln(func.glGetString(GL_RENDERER)); Writeln(func.glGetString(GL_VERSION)); Writeln(func.glGetString(GL_SHADING_LANGUAGE_VERSION)); Ext := func.glGetString(GL_EXTENSIONS); Writeln(Ext); Load(wextfunc); ExtARB := wextfunc.wglGetExtensionsStringARB(DC); Writeln(ExtARB); if (Pos('WGL_ARB_pixel_format', ExtARB) <> 0) and (Pos('WGL_ARB_create_context_profile', ExtARB) <> 0) then begin Assert(wfunc.wglMakeCurrent(0, 0), 'wglMakeCurrent = False'); Assert(wfunc.wglDeleteContext(HGLRC), 'wglMakeCurrent = False'); // Assert(DestroyWindow(TempWnd), 'Temp window is not destroy'); Assert(wextfunc.wglChoosePixelFormatARB(DC, @PixelaAttribList, nil, 1, @PixelFormatARB, @NumFormatsARB), 'wglChoosePixelFormatARB = False'); // Assert(SetPixelFormat(DC, PixelFormatARB, nil), 'SetPixelFormat = False'); HGLRCARB := wextfunc.wglCreateContextAttribsARB(DC, 0, nil); Assert(HGLRCARB <> 0, 'HGLRCARB = 0'); Assert(wextfunc.wglMakeContextCurrentARB(DC, DC, HGLRCARB), 'wglMakeCurrent = False'); end; end; function TOpenGLExt.GetProc(const Name: PAnsiChar): Pointer; begin if FLib = 0 then Exit(nil); Result := GetProcAddress(NativeUInt(FLib), Name); if Result <> nil then Exit; if Addr(wfunc.wglGetProcAddress) <> nil then Result := wfunc.wglGetProcAddress(Name); end; function TOpenGLExt.Load(const Obj: TObject): Boolean; var Field: TArray<TRttiField>; I: Integer; begin Result := False; Field := FRtti.GetType(Obj.ClassType).GetFields; for I := 0 to Length(Field) - 1 do with Field[I] do begin PPointer(Integer(Obj) + Offset)^ := GetProc(PAnsiChar(AnsiString(Name))); Result := Pointer(Pointer(Integer(Obj) + Offset)^) <> nil; Writeln(Name, ' -> ', Result); // if not Result then Exit end; end;Комментарии не стал делать. Если нужно будет - напишу.
Комментариев нет:
Отправить комментарий