Back to index

nux  3.0.0
GpuDevice.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef GLDEVICEFACTORY_H
00024 #define GLDEVICEFACTORY_H
00025 
00026 #include "GLResource.h"
00027 #include "GLDeviceFrameBufferObject.h"
00028 #include "GLDeviceObjects.h"
00029 #include "GLTextureStates.h"
00030 #include "GLTemplatePrimitiveBuffer.h"
00031 
00032 namespace nux
00033 {
00034   class GpuRenderStates;
00035 
00037   typedef enum
00038   {
00039     GPU_VENDOR_UNKNOWN = 0,
00040     GPU_BRAND_AMD,
00041     GPU_BRAND_NVIDIA,
00042     GPU_BRAND_INTEL,
00043   } GpuBrand;
00044 
00045   template<typename T> class ObjectPtr;
00046 
00047   struct STREAMSOURCE
00048   {
00049     WORD Stream;
00050     ObjectPtr<IOpenGLVertexBuffer> VertexBuffer;
00051     unsigned short StreamOffset;
00052     unsigned short StreamStride;
00053 
00054     STREAMSOURCE()
00055     {
00056       Stream = 0;
00057       //VertexBuffer = 0;
00058       StreamOffset = 0;
00059       StreamStride = 0;
00060     }
00061 
00062     void ResetStreamSource()
00063     {
00064       Stream = 0;
00065       StreamOffset = 0;
00066       VertexBuffer = ObjectPtr<IOpenGLVertexBuffer> (0);
00067       StreamStride = 0;
00068     }
00069   };
00070 
00071   // GPU Graphics information.
00072   class GpuInfo
00073   {
00074   public:
00075 
00076     GpuInfo();
00077 
00078     bool SupportOpenGL11() const    {return _support_opengl_version_11;}
00079     bool SupportOpenGL12() const    {return _support_opengl_version_12;}
00080     bool SupportOpenGL13() const    {return _support_opengl_version_13;}
00081     bool SupportOpenGL14() const    {return _support_opengl_version_14;}
00082     bool SupportOpenGL15() const    {return _support_opengl_version_15;}
00083     bool SupportOpenGL20() const    {return _support_opengl_version_20;}
00084     bool SupportOpenGL21() const    {return _support_opengl_version_21;}
00085     bool SupportOpenGL30() const    {return _support_opengl_version_30;}
00086     bool SupportOpenGL31() const    {return _support_opengl_version_31;}
00087     bool SupportOpenGL33() const    {return _support_opengl_version_33;}
00088     bool SupportOpenGL32() const    {return _support_opengl_version_32;}
00089     bool SupportOpenGL40() const    {return _support_opengl_version_40;}
00090     bool SupportOpenGL41() const    {return _support_opengl_version_41;}
00091 
00092     bool Support_EXT_Swap_Control()              const    {return _support_ext_swap_control;}
00093     bool Support_ARB_Texture_Rectangle()         const    {return _support_arb_texture_rectangle;}
00094     bool Support_ARB_Vertex_Program()            const    {return _support_arb_vertex_program;}
00095     bool Support_ARB_Fragment_Program()          const    {return _support_arb_fragment_program;}
00096     bool Support_ARB_Shader_Objects()            const    {return _support_arb_shader_objects;}
00097     bool Support_ARB_Vertex_Shader()             const    {return _support_arb_vertex_shader;}
00098     bool Support_ARB_Fragment_Shader()           const    {return _support_arb_fragment_shader;}
00099     bool Support_ARB_Vertex_Buffer_Object()      const    {return _support_arb_vertex_buffer_object;}
00100     bool Support_ARB_Texture_Non_Power_Of_Two()  const    {return _support_arb_texture_non_power_of_two;}
00101     bool Support_EXT_Framebuffer_Object()        const    {return _support_ext_framebuffer_object;}
00102     bool Support_EXT_Draw_Range_Elements()       const    {return _support_ext_draw_range_elements;}
00103     bool Support_EXT_Stencil_Two_Side()          const    {return _support_ext_stencil_two_side;}
00104     bool Support_EXT_Texture_Rectangle()         const    {return _support_ext_texture_rectangle;}
00105     bool Support_NV_Texture_Rectangle()          const    {return _support_nv_texture_rectangle;}
00106     bool Support_ARB_Pixel_Buffer_Object()       const    {return _support_arb_pixel_buffer_object;}
00107     bool Support_EXT_Blend_Equation_Separate()   const    {return _support_ext_blend_equation_separate;}
00108 
00109 #ifndef NUX_OPENGLES_20
00110     bool Support_EXT_Texture_sRGB()              const    {return _support_ext_texture_srgb;}
00111     bool Support_EXT_Texture_Decode()            const    {return _support_ext_texture_srgb_decode;}
00112     bool Support_EXT_Framebuffer_sRGB()          const    {return _support_ext_framebuffer_srgb;}
00113     bool Support_ARB_Framebuffer_sRGB()          const    {return _support_arb_framebuffer_srgb;}
00114 #endif
00115 
00116     int GetMaxFboAttachment() {return _opengl_max_fb_attachment;}
00117 
00118 
00119   private:
00120     void Setup();
00121 
00122     bool _support_opengl_version_11;
00123     bool _support_opengl_version_12;
00124     bool _support_opengl_version_13;
00125     bool _support_opengl_version_14;
00126     bool _support_opengl_version_15;
00127     bool _support_opengl_version_20;
00128     bool _support_opengl_version_21;
00129     bool _support_opengl_version_30;
00130     bool _support_opengl_version_31;
00131     bool _support_opengl_version_32;
00132     bool _support_opengl_version_33;
00133     bool _support_opengl_version_40;
00134     bool _support_opengl_version_41;
00135 
00136     int _opengl_max_texture_units;
00137     int _opengl_max_texture_coords;
00138     int _opengl_max_texture_image_units;
00139     int _opengl_max_fb_attachment;
00140     int _opengl_max_vertex_attributes;
00141 
00142     bool _support_ext_swap_control;
00143     bool _support_arb_vertex_program;
00144     bool _support_arb_fragment_program;
00145     bool _support_arb_shader_objects;
00146     bool _support_arb_vertex_shader;
00147     bool _support_arb_fragment_shader;
00148     bool _support_arb_vertex_buffer_object;
00149     bool _support_arb_texture_non_power_of_two;
00150     bool _support_ext_framebuffer_object;
00151     bool _support_ext_draw_range_elements;
00152     bool _support_ext_stencil_two_side;
00153     bool _support_ext_texture_rectangle;
00154     bool _support_arb_texture_rectangle; 
00155     bool _support_nv_texture_rectangle;
00156     bool _support_arb_pixel_buffer_object;
00157     bool _support_ext_blend_equation_separate;
00158 
00159 #ifndef NUX_OPENGLES_20
00160     bool _support_ext_texture_srgb;
00161     bool _support_ext_texture_srgb_decode;
00162     bool _support_ext_framebuffer_srgb;
00163     bool _support_arb_framebuffer_srgb;
00164 #endif
00165 
00166     friend class GpuDevice;
00167   };
00168 
00170 
00174   class GpuDevice
00175   {
00176   private:
00177     static STREAMSOURCE _StreamSource[MAX_NUM_STREAM];
00178 
00179     int CreateTexture(
00180       unsigned int Width
00181       , unsigned int Height
00182       , unsigned int Levels
00183       , BitmapFormat PixelFormat
00184       , IOpenGLTexture2D **ppTexture
00185       , NUX_FILE_LINE_PROTO
00186     );
00187 
00188     int CreateRectangleTexture(
00189       unsigned int Width
00190       , unsigned int Height
00191       , unsigned int Levels
00192       , BitmapFormat PixelFormat
00193       , IOpenGLRectangleTexture **ppTexture
00194       , NUX_FILE_LINE_PROTO
00195     );
00196 
00197     int CreateCubeTexture(
00198       unsigned int EdgeLength
00199       , unsigned int Levels
00200       , BitmapFormat PixelFormat
00201       , IOpenGLCubeTexture **ppCubeTexture
00202       , NUX_FILE_LINE_PROTO
00203     );
00204 
00205     int CreateVolumeTexture(
00206       unsigned int Width
00207       , unsigned int Height
00208       , unsigned int Depth
00209       , unsigned int Levels
00210       , BitmapFormat PixelFormat
00211       , IOpenGLVolumeTexture **ppVolumeTexture
00212       , NUX_FILE_LINE_PROTO
00213     );
00214 
00215     int CreateAnimatedTexture(
00216       unsigned int Width
00217       , unsigned int Height
00218       , unsigned int Depth
00219       , BitmapFormat PixelFormat
00220       , IOpenGLAnimatedTexture **ppAnimatedTexture
00221     );
00222 
00223     int CreateVertexBuffer(
00224       unsigned int Length
00225       , VBO_USAGE Usage    // Dynamic or WriteOnly
00226       , IOpenGLVertexBuffer **ppVertexBuffer
00227     );
00228 
00229     int CreateIndexBuffer(
00230       unsigned int Length
00231       , VBO_USAGE Usage    // Dynamic or WriteOnly
00232       , INDEX_FORMAT Format
00233       , IOpenGLIndexBuffer **ppIndexBuffer
00234     );
00235 
00236     int CreatePixelBufferObject(int Size, VBO_USAGE Usage,   // Dynamic or WriteOnly
00237                                  IOpenGLPixelBufferObject **ppPixelBufferObject
00238                                 );
00239 
00240     int CreateQuery(
00241       QUERY_TYPE Type,
00242       IOpenGLQuery **ppQuery);
00243 
00244     int CreateVertexDeclaration(
00245       const VERTEXELEMENT *pVertexElements,
00246       IOpenGLVertexDeclaration **ppDecl);
00247 
00248     int CreateFrameBufferObject(
00249       IOpenGLFrameBufferObject **ppFrameBufferObject);
00250 
00251     int CreateShaderProgram(
00252       IOpenGLShaderProgram **ppShaderProgram);
00253 
00254     int CreateVertexShader(
00255       IOpenGLVertexShader **ppVertexShader);
00256 
00257     int CreatePixelShader(
00258       IOpenGLPixelShader **ppPixelShader);
00259 
00260     int CreateAsmShaderProgram(
00261       IOpenGLAsmShaderProgram **ppAsmShaderProgram);
00262 
00263     int CreateAsmVertexShader(
00264       IOpenGLAsmVertexShader **ppAsmVertexShader);
00265 
00266     int CreateAsmPixelShader(
00267       IOpenGLAsmPixelShader **ppAsmPixelShader);
00268 
00269 #if (NUX_ENABLE_CG_SHADERS)
00270     int CreateCGVertexShader(
00271       ICgVertexShader **ppCgVertexShader);
00272 
00273     int CreateCGPixelShader(
00274       ICgPixelShader **ppCgPixelShader);
00275 #endif
00276 
00277   public:
00278     ObjectPtr<IOpenGLTexture2D> CreateTexture(
00279       int Width,
00280       int Height,
00281       int Levels,
00282       BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00283 
00284     ObjectPtr<IOpenGLTexture2D> CreateTexture2DFromID(int id,
00285       int Width,
00286       int Height,
00287       int Levels,
00288       BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00289 
00290     ObjectPtr<IOpenGLRectangleTexture> CreateRectangleTexture(
00291       int Width
00292       , int Height
00293       , int Levels
00294       , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00295 
00296     ObjectPtr<IOpenGLCubeTexture> CreateCubeTexture(
00297       int EdgeLength
00298       , int Levels
00299       , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00300 
00301     ObjectPtr<IOpenGLVolumeTexture> CreateVolumeTexture(
00302       int Width
00303       , int Height
00304       , int Depth
00305       , int Levels
00306       , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00307 
00308     ObjectPtr<IOpenGLAnimatedTexture> CreateAnimatedTexture(
00309       int Width
00310       , int Height
00311       , int Depth
00312       , BitmapFormat PixelFormat);
00313 
00314     ObjectPtr<IOpenGLVertexBuffer> CreateVertexBuffer(
00315       int Length
00316       , VBO_USAGE Usage);
00317 
00318     ObjectPtr<IOpenGLIndexBuffer> CreateIndexBuffer(
00319       int Length
00320       , VBO_USAGE Usage    // Dynamic or WriteOnly
00321       , INDEX_FORMAT Format);
00322 
00323     ObjectPtr<IOpenGLPixelBufferObject> CreatePixelBufferObject(int Size, VBO_USAGE Usage);
00324 
00325     ObjectPtr<IOpenGLQuery> CreateQuery(
00326       QUERY_TYPE Type);
00327 
00328     ObjectPtr<IOpenGLVertexDeclaration> CreateVertexDeclaration(
00329       const VERTEXELEMENT *pVertexElements);
00330 
00331     ObjectPtr<IOpenGLFrameBufferObject> CreateFrameBufferObject();
00332 
00333     ObjectPtr<IOpenGLShaderProgram> CreateShaderProgram();
00334     ObjectPtr<IOpenGLVertexShader> CreateVertexShader();
00335     ObjectPtr<IOpenGLPixelShader> CreatePixelShader();
00336     ObjectPtr<IOpenGLAsmShaderProgram> CreateAsmShaderProgram();
00337     ObjectPtr<IOpenGLAsmVertexShader> CreateAsmVertexShader();
00338     ObjectPtr<IOpenGLAsmPixelShader> CreateAsmPixelShader();
00339 
00340 #if (NUX_ENABLE_CG_SHADERS)
00341     ObjectPtr<ICgVertexShader> CreateCGVertexShader();
00342     ObjectPtr<ICgPixelShader> CreateCGPixelShader();
00343 #endif
00344 
00345     // This is for the fixed pipeline
00346     // When using shaders see how a shader sampler parameter links to a texture with a call to setTexture.
00347     int SetTexture(unsigned int TextureUnit, IOpenGLBaseTexture *texture);
00348 
00349     int DrawIndexedPrimitive(
00350       ObjectPtr<IOpenGLIndexBuffer> IndexBuffer,
00351       ObjectPtr<IOpenGLVertexDeclaration> VertexDeclaration,
00352       PRIMITIVE_TYPE PrimitiveType,
00353       int PrimitiveCount
00354     );
00355 
00356     // Draw Primitive without index buffer
00357     int DrawPrimitive(
00358       ObjectPtr<IOpenGLVertexDeclaration> VertexDeclaration,
00359       PRIMITIVE_TYPE pt_,
00360       unsigned vtx_start_,
00361       unsigned num_prims_);
00362 
00363     // Draw Primitive without index buffer, and use a user pointer for the source of the stream.
00364     int DrawPrimitiveUP(
00365       ObjectPtr<IOpenGLVertexDeclaration> VertexDeclaration,
00366       PRIMITIVE_TYPE PrimitiveType,
00367       unsigned int PrimitiveCount,
00368       const void *pVertexStreamZeroData,
00369       unsigned int VertexStreamZeroStride
00370     );
00371 
00372     int SetStreamSource(
00373       unsigned int StreamNumber,
00374       ObjectPtr<IOpenGLVertexBuffer> pStreamData,
00375       unsigned int OffsetInBytes,
00376       unsigned int Stride);
00377 
00379     void InvalidateVertexBuffer();
00381     void InvalidateIndexBuffer();
00383     void InvalidateTextureUnit(int TextureUnitIndex);
00384 
00385     unsigned int GetPixelStoreAlignment()
00386     {
00387       return _PixelStoreAlignment;
00388     }
00389 
00390     int AllocateUnpackPixelBufferIndex(int *index);
00391     int FreeUnpackPixelBufferIndex(const int index);
00392     int BindUnpackPixelBufferIndex(const int index);
00393     int BindPackPixelBufferIndex(const int index);
00394     void *LockUnpackPixelBufferIndex(const int index, const int Size);
00395     void *LockPackPixelBufferIndex(const int index, const int Size);
00396 
00397     void UnlockUnpackPixelBufferIndex(const int index);
00398     void UnlockPackPixelBufferIndex(const int index);
00399 
00400     // All these operations are done on the default frame buffer object: _FrameBufferObject.
00401     int FormatFrameBufferObject(unsigned int Width, unsigned int Height, BitmapFormat PixelFormat);
00402     int SetColorRenderTargetSurface(unsigned int ColorAttachmentIndex, ObjectPtr<IOpenGLSurface> pRenderTargetSurface);
00403     int SetDepthRenderTargetSurface(ObjectPtr<IOpenGLSurface> pDepthSurface);
00404     ObjectPtr<IOpenGLSurface> GetColorRenderTargetSurface(unsigned int ColorAttachmentIndex);
00405     ObjectPtr<IOpenGLSurface> GetDepthRenderTargetSurface();
00406     // Activate and Deactivate the default framebuffer: _FrameBufferObject.
00407     void ActivateFrameBuffer();
00408 
00410     void DeactivateFrameBuffer(); 
00411 
00412   public:
00413     void SetCurrentFrameBufferObject(ObjectPtr<IOpenGLFrameBufferObject> fbo);
00414     ObjectPtr<IOpenGLFrameBufferObject> GetCurrentFrameBufferObject();
00415 
00416     int GetOpenGLMajorVersion() const;
00417     int GetOpenGLMinorVersion() const;
00418   private:
00419     // Default FrameBufferobject
00420     ObjectPtr<IOpenGLFrameBufferObject> _FrameBufferObject;
00421     ObjectPtr<IOpenGLFrameBufferObject> _CurrentFrameBufferObject;
00422 
00423     struct PixelBufferObject
00424     {
00425       ObjectPtr<IOpenGLPixelBufferObject> PBO;
00426       bool   IsReserved;
00427     };
00428 
00429     unsigned int _PixelStoreAlignment;
00430 
00431     std::vector<PixelBufferObject> _PixelBufferArray;
00432 
00433   public:
00434 
00435 #if (NUX_ENABLE_CG_SHADERS)
00436     CGcontext GetCgContext()
00437     {
00438       return m_Cgcontext;
00439     }
00440     CGcontext m_Cgcontext;
00441 #endif
00442 
00443     inline bool UsePixelBufferObjects() const
00444     {
00445       return _UsePixelBufferObject;
00446     }
00447 
00448     GpuBrand GetGPUBrand() const;
00449 
00450     GpuRenderStates &GetRenderStates();
00451 
00452     GpuInfo &GetGpuInfo();
00453 
00454     void ResetRenderStates();
00455 
00456     void VerifyRenderStates();
00457 
00459 
00466     ObjectPtr<IOpenGLBaseTexture> CreateSystemCapableDeviceTexture(
00467       int Width
00468       , int Height
00469       , int Levels
00470       , BitmapFormat PixelFormat, NUX_FILE_LINE_PROTO);
00471 
00473 
00476     BaseTexture* CreateSystemCapableTexture(NUX_FILE_LINE_PROTO);
00477 
00478     bool SUPPORT_GL_ARB_TEXTURE_NON_POWER_OF_TWO() const
00479     {
00480       return _gpu_info->Support_ARB_Texture_Non_Power_Of_Two();
00481     }
00482 
00483     bool SUPPORT_GL_EXT_TEXTURE_RECTANGLE()    const
00484     {
00485       return _gpu_info->Support_EXT_Texture_Rectangle();
00486     }
00487 
00488     bool SUPPORT_GL_ARB_TEXTURE_RECTANGLE()    const
00489     {
00490       return _gpu_info->Support_ARB_Texture_Rectangle();
00491     }
00492     
00493   private:
00494 
00495     // 
00496     int _opengl_major;  
00497     int _opengl_minor;  
00498     int _glsl_version_major;  
00499     int _glsl_version_minor;  
00500 
00501     NString _board_vendor_string;     
00502     NString _board_renderer_string;   
00503     NString _openGL_version_string;   
00504     NString _glsl_version_string;     
00505     GpuBrand _gpu_brand;              
00506 
00507     bool _UsePixelBufferObject;
00508 
00509     bool OGL_EXT_SWAP_CONTROL;
00510     bool GL_ARB_VERTEX_PROGRAM;
00511     bool GL_ARB_FRAGMENT_PROGRAM;
00512     bool GL_ARB_SHADER_OBJECTS;
00513     bool GL_ARB_VERTEX_SHADER;
00514     bool GL_ARB_FRAGMENT_SHADER;
00515     bool GL_ARB_VERTEX_BUFFER_OBJECT;
00516     bool GL_ARB_TEXTURE_NON_POWER_OF_TWO;
00517     bool GL_EXT_FRAMEBUFFER_OBJECT;
00518     bool GL_EXT_DRAW_RANGE_ELEMENTS;
00519     bool GL_EXT_STENCIL_TWO_SIDE;
00520     bool GL_EXT_TEXTURE_RECTANGLE;
00521     bool GL_ARB_TEXTURE_RECTANGLE; 
00522     bool GL_NV_TEXTURE_RECTANGLE;
00523 
00524     GpuRenderStates *_gpu_render_states;
00525     GpuInfo *_gpu_info;
00526 
00527   public:
00528     
00529     ObjectPtr<IOpenGLTexture2D> backup_texture0_;
00530 
00531 #if defined(NUX_OS_WINDOWS)
00532     GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight, BitmapFormat DeviceFormat,
00533       HDC device_context,
00534       HGLRC &opengl_rendering_context,
00535       int req_opengl_major = 1,   // requested opengl major version.
00536       int req_opengl_minor = 0,   // requested opengl minor version.
00537       bool opengl_es_20 = false);
00538 
00539 #elif defined(NUX_OS_LINUX)
00540     #ifdef NUX_OPENGLES_20
00541         GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight,
00542           BitmapFormat DeviceFormat,
00543           Display *display,
00544           Window window,
00545           bool has_new_glx_support,
00546           EGLConfig fb_config,
00547           EGLContext &opengl_rendering_context,
00548           int req_opengl_major = 2,
00549           int req_opengl_minor = 0,
00550           bool opengl_es_20 = true);
00551     #else
00552         GpuDevice(unsigned int DeviceWidth, unsigned int DeviceHeight,
00553           BitmapFormat DeviceFormat,
00554           Display *display,
00555           Window window,
00556           bool has_new_glx_support,
00557           GLXFBConfig fb_config,
00558           GLXContext &opengl_rendering_context,
00559           int req_opengl_major = 1,   // requested opengl major version.
00560           int req_opengl_minor = 0,   // requested opengl minor version.
00561           bool opengl_es_20 = false);
00562     #endif
00563 #endif
00564     
00565     ~GpuDevice();
00566     friend class IOpenGLSurface;
00567     friend class GraphicsEngine;
00568   };
00569 
00570 }
00571 
00572 #endif // GLDEVICEFACTORY_H
00573