ovr_sdk

diff LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h	Wed Jan 14 06:51:16 2015 +0200
     1.3 @@ -0,0 +1,553 @@
     1.4 +/************************************************************************************
     1.5 +
     1.6 +Filename    :   CAPI_GL_Util.h
     1.7 +Content     :   Utility header for OpenGL
     1.8 +Created     :   March 27, 2014
     1.9 +Authors     :   Andrew Reisse, David Borel
    1.10 +
    1.11 +Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
    1.12 +
    1.13 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
    1.14 +you may not use the Oculus VR Rift SDK except in compliance with the License,
    1.15 +which is provided at the time of installation or download, or which
    1.16 +otherwise accompanies this software in either electronic or hard copy form.
    1.17 +
    1.18 +You may obtain a copy of the License at
    1.19 +
    1.20 +http://www.oculusvr.com/licenses/LICENSE-3.2
    1.21 +
    1.22 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK
    1.23 +distributed under the License is distributed on an "AS IS" BASIS,
    1.24 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.25 +See the License for the specific language governing permissions and
    1.26 +limitations under the License.
    1.27 +
    1.28 +************************************************************************************/
    1.29 +
    1.30 +#ifndef INC_OVR_CAPI_GL_Util_h
    1.31 +#define INC_OVR_CAPI_GL_Util_h
    1.32 +
    1.33 +#include "../../OVR_CAPI.h"  
    1.34 +#include "../../Kernel/OVR_Array.h"
    1.35 +#include "../../Kernel/OVR_Math.h"
    1.36 +#include "../../Kernel/OVR_RefCount.h"
    1.37 +#include "../../Kernel/OVR_String.h"
    1.38 +#include "../../Kernel/OVR_Types.h"
    1.39 +#include "../../Kernel/OVR_Log.h"
    1.40 +
    1.41 +#if defined(OVR_OS_WIN32)
    1.42 +#define WIN32_LEAN_AND_MEAN
    1.43 +#include <Windows.h>
    1.44 +#endif
    1.45 +
    1.46 +#if !defined(OVR_DISABLE_GLE)   // By default we use the GLE module in order to link to OpenGL functions. However, if an external user 
    1.47 +#include "CAPI_GLE.h"           // wants to use an alternative mechanism to connect to OpenGL functions, they can #define OVR_DISABLE_GLE.
    1.48 +#endif
    1.49 +
    1.50 +
    1.51 +#if defined(OVR_OS_MAC)
    1.52 +    #include <CoreGraphics/CGDirectDisplay.h>
    1.53 +    #include <OpenGL/CGLTypes.h>
    1.54 +#endif
    1.55 +
    1.56 +
    1.57 +namespace OVR
    1.58 +{
    1.59 +    // Get the shared LibOVR GLEContext instance.
    1.60 +    class GLEContext;
    1.61 +    GLEContext* GetGLEContext();
    1.62 +}
    1.63 +
    1.64 +namespace OVR { namespace CAPI { namespace GL {
    1.65 +void InitGLExtensions();
    1.66 +
    1.67 +
    1.68 +// Rendering primitive type used to render Model.
    1.69 +enum PrimitiveType
    1.70 +{
    1.71 +    Prim_Triangles,
    1.72 +    Prim_Lines,
    1.73 +    Prim_TriangleStrip,
    1.74 +    Prim_Unknown,
    1.75 +    Prim_Count
    1.76 +};
    1.77 +
    1.78 +// Types of shaders that can be stored together in a ShaderSet.
    1.79 +enum ShaderStage
    1.80 +{
    1.81 +    Shader_Vertex   = 0,
    1.82 +    Shader_Fragment = 2,
    1.83 +    Shader_Pixel    = 2,
    1.84 +    Shader_Count    = 3,
    1.85 +};
    1.86 +
    1.87 +enum MapFlags
    1.88 +{
    1.89 +    Map_Discard        = 1,
    1.90 +    Map_Read           = 2, // do not use
    1.91 +    Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE
    1.92 +};
    1.93 +
    1.94 +
    1.95 +// Buffer types used for uploading geometry & constants.
    1.96 +enum BufferUsage
    1.97 +{
    1.98 +    Buffer_Unknown  = 0,
    1.99 +    Buffer_Vertex   = 1,
   1.100 +    Buffer_Index    = 2,
   1.101 +    Buffer_Uniform  = 4,
   1.102 +    Buffer_TypeMask = 0xff,
   1.103 +    Buffer_ReadOnly = 0x100, // Buffer must be created with Data().
   1.104 +};
   1.105 +
   1.106 +enum TextureFormat
   1.107 +{
   1.108 +    Texture_RGBA            = 0x0100,
   1.109 +    Texture_Depth           = 0x8000,
   1.110 +    Texture_TypeMask        = 0xff00,
   1.111 +    Texture_SamplesMask     = 0x00ff,
   1.112 +    Texture_RenderTarget    = 0x10000,
   1.113 +    Texture_GenMipmaps      = 0x20000,
   1.114 +};
   1.115 +
   1.116 +// Texture sampling modes.
   1.117 +enum SampleMode
   1.118 +{
   1.119 +    Sample_Linear       = 0,
   1.120 +    Sample_Nearest      = 1,
   1.121 +    Sample_Anisotropic  = 2,
   1.122 +    Sample_FilterMask   = 3,
   1.123 +
   1.124 +    Sample_Repeat       = 0,
   1.125 +    Sample_Clamp        = 4,
   1.126 +    Sample_ClampBorder  = 8, // If unsupported Clamp is used instead.
   1.127 +    Sample_AddressMask  =12,
   1.128 +
   1.129 +    Sample_Count        =13,
   1.130 +};
   1.131 +
   1.132 +
   1.133 +// Rendering parameters/pointers describing GL rendering setup.
   1.134 +struct RenderParams
   1.135 +{
   1.136 +#if defined(OVR_OS_WIN32)
   1.137 +    HWND   Window;
   1.138 +    HDC    DC;
   1.139 +#elif defined(OVR_OS_LINUX)
   1.140 +    struct _XDisplay* Disp;
   1.141 +#endif
   1.142 +
   1.143 +    ovrSizei    BackBufferSize;
   1.144 +    int    Multisample;
   1.145 +};
   1.146 +
   1.147 +
   1.148 +class Buffer : public RefCountBase<Buffer>
   1.149 +{
   1.150 +public:
   1.151 +    RenderParams* pParams;
   1.152 +    size_t        Size;
   1.153 +    GLenum        Use;
   1.154 +    GLuint        GLBuffer;
   1.155 +
   1.156 +public:
   1.157 +    Buffer(RenderParams* r);
   1.158 +    ~Buffer();
   1.159 +
   1.160 +    GLuint         GetBuffer() { return GLBuffer; }
   1.161 +
   1.162 +    virtual size_t GetSize() { return Size; }
   1.163 +    virtual void*  Map(size_t start, size_t size, int flags = 0);
   1.164 +    virtual bool   Unmap(void *m);
   1.165 +    virtual bool   Data(int use, const void* buffer, size_t size);
   1.166 +};
   1.167 +
   1.168 +class Texture : public RefCountBase<Texture>
   1.169 +{
   1.170 +	bool IsUserAllocated;
   1.171 +
   1.172 +public:
   1.173 +    RenderParams* pParams;
   1.174 +    GLuint        TexId;
   1.175 +    int           Width, Height;
   1.176 +
   1.177 +    Texture(RenderParams* rp, int w, int h);
   1.178 +    ~Texture();
   1.179 +
   1.180 +    virtual int GetWidth() const { return Width; }
   1.181 +    virtual int GetHeight() const { return Height; }
   1.182 +
   1.183 +    virtual void SetSampleMode(int sm);
   1.184 +
   1.185 +    // Updates texture to point to specified resources
   1.186 +    //  - used for slave rendering.
   1.187 +    void UpdatePlaceholderTexture(GLuint texId,
   1.188 +                                  const Sizei& textureSize);
   1.189 +
   1.190 +    virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
   1.191 +};
   1.192 +
   1.193 +// Base class for vertex and pixel shaders. Stored in ShaderSet.
   1.194 +class Shader : public RefCountBase<Shader>
   1.195 +{
   1.196 +    friend class ShaderSet;
   1.197 +
   1.198 +protected:
   1.199 +    ShaderStage Stage;
   1.200 +
   1.201 +public:
   1.202 +    Shader(ShaderStage s) : Stage(s) {}
   1.203 +    virtual ~Shader() {}
   1.204 +
   1.205 +    ShaderStage GetStage() const { return Stage; }
   1.206 +
   1.207 +    virtual void Set(PrimitiveType) const { }
   1.208 +    virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); }
   1.209 +
   1.210 +protected:
   1.211 +    virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; }
   1.212 +    virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; }
   1.213 +};
   1.214 +
   1.215 +
   1.216 +
   1.217 +// A group of shaders, one per stage.
   1.218 +// A ShaderSet is applied for rendering with a given fill.
   1.219 +class ShaderSet : public RefCountBase<ShaderSet>
   1.220 +{
   1.221 +protected:
   1.222 +    Ptr<Shader> Shaders[Shader_Count];
   1.223 +
   1.224 +    struct Uniform
   1.225 +    {
   1.226 +        String Name;
   1.227 +        int    Location, Size;
   1.228 +        int    Type; // currently number of floats in vector
   1.229 +
   1.230 +        Uniform() : Name(), Location(0), Size(0), Type(0){}
   1.231 +    };
   1.232 +    Array<Uniform> UniformInfo;
   1.233 +	
   1.234 +public:
   1.235 +	GLuint    Prog;
   1.236 +    GLint     ProjLoc, ViewLoc;
   1.237 +    GLint     TexLoc[8];
   1.238 +    bool      UsesLighting;
   1.239 +    int       LightingVer;
   1.240 +
   1.241 +    ShaderSet();
   1.242 +    ~ShaderSet();
   1.243 +
   1.244 +    virtual void SetShader(Shader *s);
   1.245 +    virtual void UnsetShader(int stage);
   1.246 +    Shader* GetShader(int stage) { return Shaders[stage]; }
   1.247 +
   1.248 +    virtual void Set(PrimitiveType prim) const
   1.249 +    {
   1.250 +		glUseProgram(Prog);
   1.251 +
   1.252 +        for (int i = 0; i < Shader_Count; i++)
   1.253 +            if (Shaders[i])
   1.254 +                Shaders[i]->Set(prim);
   1.255 +    }
   1.256 +
   1.257 +    // Set a uniform (other than the standard matrices). It is undefined whether the
   1.258 +    // uniforms from one shader occupy the same space as those in other shaders
   1.259 +    // (unless a buffer is used, then each buffer is independent).     
   1.260 +    virtual bool SetUniform(const char* name, int n, const float* v);
   1.261 +    bool SetUniform1f(const char* name, float x)
   1.262 +    {
   1.263 +        const float v[] = {x};
   1.264 +        return SetUniform(name, 1, v);
   1.265 +    }
   1.266 +    bool SetUniform2f(const char* name, float x, float y)
   1.267 +    {
   1.268 +        const float v[] = {x,y};
   1.269 +        return SetUniform(name, 2, v);
   1.270 +    }
   1.271 +    bool SetUniform3f(const char* name, float x, float y, float z)
   1.272 +    {
   1.273 +        const float v[] = {x,y,z};
   1.274 +        return SetUniform(name, 3, v);
   1.275 +    }
   1.276 +    bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
   1.277 +    {
   1.278 +        const float v[] = {x,y,z,w};
   1.279 +        return SetUniform(name, 4, v);
   1.280 +    }
   1.281 +
   1.282 +    bool SetUniformv(const char* name, const Vector3f& v)
   1.283 +    {
   1.284 +        const float a[] = {v.x,v.y,v.z,1};
   1.285 +        return SetUniform(name, 4, a);
   1.286 +    }
   1.287 + 
   1.288 +    virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
   1.289 +    {
   1.290 +        Matrix4f mt = m.Transposed();
   1.291 +        return SetUniform(name, 16, &mt.M[0][0]);
   1.292 +    }
   1.293 +
   1.294 +    virtual bool SetUniform3x3f(const char* name, const Matrix4f& m)
   1.295 +    {
   1.296 +        Matrix4f mt = m.Transposed();
   1.297 +        // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code.
   1.298 +        return SetUniform(name, 12, &mt.M[0][0]);
   1.299 +    }
   1.300 +
   1.301 +
   1.302 +protected:
   1.303 +	GLint GetGLShader(Shader* s);
   1.304 +    bool Link();
   1.305 +};
   1.306 +
   1.307 +
   1.308 +// Fill combines a ShaderSet (vertex, pixel) with textures, if any.
   1.309 +// Every model has a fill.
   1.310 +class ShaderFill : public RefCountBase<ShaderFill>
   1.311 +{
   1.312 +    Ptr<ShaderSet>     Shaders;
   1.313 +    Ptr<class Texture> Textures[8];
   1.314 +    void*              InputLayout; // HACK this should be abstracted
   1.315 +
   1.316 +public:
   1.317 +    ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; }
   1.318 +    ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; }    
   1.319 +
   1.320 +    ShaderSet*  GetShaders() const      { return Shaders; }
   1.321 +    void*       GetInputLayout() const  { return InputLayout; }
   1.322 +
   1.323 +    virtual void Set(PrimitiveType prim = Prim_Unknown) const {
   1.324 +		Shaders->Set(prim);
   1.325 +		for(int i = 0; i < 8; i++)
   1.326 +		{
   1.327 +			if(Textures[i])
   1.328 +			{
   1.329 +				Textures[i]->Set(i);
   1.330 +			}
   1.331 +		}
   1.332 +	}
   1.333 +
   1.334 +    virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
   1.335 +};
   1.336 +
   1.337 +    
   1.338 +struct DisplayId
   1.339 +{
   1.340 +    // Windows
   1.341 +    String MonitorName; // Monitor name for fullscreen mode
   1.342 +    
   1.343 +    // MacOS
   1.344 +    long   CgDisplayId; // CGDirectDisplayID
   1.345 +    
   1.346 +    DisplayId() : CgDisplayId(0) {}
   1.347 +    DisplayId(long id) : CgDisplayId(id) {}
   1.348 +    DisplayId(String m, long id=0) : MonitorName(m), CgDisplayId(id) {}
   1.349 +    
   1.350 +    operator bool () const
   1.351 +    {
   1.352 +        return MonitorName.GetLength() || CgDisplayId;
   1.353 +    }
   1.354 +    
   1.355 +    bool operator== (const DisplayId& b) const
   1.356 +    {
   1.357 +        return CgDisplayId == b.CgDisplayId &&
   1.358 +            (strstr(MonitorName.ToCStr(), b.MonitorName.ToCStr()) ||
   1.359 +             strstr(b.MonitorName.ToCStr(), MonitorName.ToCStr()));
   1.360 +    }
   1.361 +};
   1.362 +
   1.363 +
   1.364 +class ShaderBase : public Shader
   1.365 +{
   1.366 +public:    
   1.367 +    RenderParams*   pParams;
   1.368 +    unsigned char*  UniformData;
   1.369 +    int             UniformsSize;
   1.370 +
   1.371 +	enum VarType
   1.372 +	{
   1.373 +		VARTYPE_FLOAT,
   1.374 +		VARTYPE_INT,
   1.375 +		VARTYPE_BOOL,
   1.376 +	};
   1.377 +
   1.378 +	struct Uniform
   1.379 +	{
   1.380 +		const char* Name;
   1.381 +		VarType     Type;
   1.382 +        int         Offset;
   1.383 +        int         Size;
   1.384 +	};
   1.385 +
   1.386 +    const Uniform*  UniformRefl;
   1.387 +    size_t          UniformReflSize;
   1.388 +
   1.389 +	ShaderBase(RenderParams* rp, ShaderStage stage) :
   1.390 +        Shader(stage),
   1.391 +        pParams(rp),
   1.392 +        UniformData(NULL),
   1.393 +        UniformsSize(0),
   1.394 +        UniformRefl(NULL),
   1.395 +        UniformReflSize(0)
   1.396 +    {
   1.397 +    }
   1.398 +	~ShaderBase()
   1.399 +	{
   1.400 +        if (UniformData)
   1.401 +        {
   1.402 +            OVR_FREE(UniformData);
   1.403 +            UniformData = NULL;
   1.404 +        }
   1.405 +
   1.406 +        // Do not need to free UniformRefl
   1.407 +        UniformRefl = NULL;
   1.408 +	}
   1.409 +
   1.410 +    void InitUniforms(const Uniform* refl, size_t reflSize);
   1.411 +	bool SetUniform(const char* name, int n, const float* v);
   1.412 +	bool SetUniformBool(const char* name, int n, const bool* v);
   1.413 +};
   1.414 +
   1.415 +
   1.416 +template<ShaderStage SStage, GLenum SType>
   1.417 +class ShaderImpl : public ShaderBase
   1.418 +{
   1.419 +    friend class ShaderSet;
   1.420 +
   1.421 +public:
   1.422 +    ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize)
   1.423 +		: ShaderBase(rp, SStage)
   1.424 +		, GLShader(0)
   1.425 +    {
   1.426 +		bool success;
   1.427 +        OVR_UNUSED(size);
   1.428 +        success = Compile((const char*) s);
   1.429 +        OVR_ASSERT(success);
   1.430 +        OVR_UNUSED(success);
   1.431 +		InitUniforms(refl, reflSize);
   1.432 +    }
   1.433 +    ~ShaderImpl()
   1.434 +    {      
   1.435 +		if (GLShader)
   1.436 +		{
   1.437 +			glDeleteShader(GLShader);
   1.438 +			GLShader = 0;
   1.439 +		}
   1.440 +    }
   1.441 +    bool Compile(const char* src)
   1.442 +	{
   1.443 +		if (!GLShader)
   1.444 +			GLShader = glCreateShader(GLStage());
   1.445 +
   1.446 +		glShaderSource(GLShader, 1, &src, 0);
   1.447 +		glCompileShader(GLShader);
   1.448 +		GLint r;
   1.449 +		glGetShaderiv(GLShader, GL_COMPILE_STATUS, &r);
   1.450 +		if (!r)
   1.451 +		{
   1.452 +			GLchar msg[1024];
   1.453 +			glGetShaderInfoLog(GLShader, sizeof(msg), 0, msg);
   1.454 +			if (msg[0])
   1.455 +				OVR_DEBUG_LOG(("Compiling shader\n%s\nfailed: %s\n", src, msg));
   1.456 +
   1.457 +			return 0;
   1.458 +		}
   1.459 +		return 1;
   1.460 +	}
   1.461 +	
   1.462 +    GLenum GLStage() const
   1.463 +    {
   1.464 +		return SType;
   1.465 +	}
   1.466 +
   1.467 +private:
   1.468 +	GLuint GLShader;
   1.469 +};
   1.470 +
   1.471 +typedef ShaderImpl<Shader_Vertex,  GL_VERTEX_SHADER> VertexShader;
   1.472 +typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader;
   1.473 +
   1.474 +
   1.475 +
   1.476 +// Allows us to have independent OpenGL contexts for our systems.
   1.477 +class Context
   1.478 +{
   1.479 +    bool                initialized;
   1.480 +    bool                ownsContext;
   1.481 +    int                 incarnation;
   1.482 +#if defined(OVR_OS_WIN32)
   1.483 +    HDC                 hdc;
   1.484 +    HGLRC               systemContext;
   1.485 +#elif defined(OVR_OS_LINUX)
   1.486 +    Display            *x11Display;
   1.487 +    GLXDrawable         x11Drawable;
   1.488 +    GLXContext          systemContext;
   1.489 +    XVisualInfo         x11Visual;
   1.490 +#elif defined(OVR_OS_MAC)
   1.491 +    CGLContextObj       systemContext;
   1.492 +#endif
   1.493 +        
   1.494 +public:
   1.495 +
   1.496 +    Context();
   1.497 +    void InitFromCurrent();
   1.498 +    void CreateShared( Context & ctx );
   1.499 +#if defined(OVR_OS_MAC)
   1.500 +    void SetSurface( Context & ctx );
   1.501 +#endif
   1.502 +    void Destroy();
   1.503 +    void Bind();
   1.504 +    void Unbind();
   1.505 +    int  GetIncarnation() const { return incarnation; }
   1.506 +
   1.507 +};
   1.508 +
   1.509 +
   1.510 +// AutoContext
   1.511 +//
   1.512 +// Implements a common sequence of function calls with the Context class.
   1.513 +// See the AutoContext constructor below for what it does. 
   1.514 +//
   1.515 +// Example usage:
   1.516 +//     void SomeClass::Draw()
   1.517 +//     {
   1.518 +//         AutoContext autoContext(someClassContext);
   1.519 +//
   1.520 +//         <draw calls>
   1.521 +//     }
   1.522 +
   1.523 +struct AutoContext
   1.524 +{
   1.525 +    Context  savedCurrentContext;
   1.526 +    Context& ourContext;
   1.527 +
   1.528 +    AutoContext(Context& context) :
   1.529 +        savedCurrentContext(), ourContext(context)
   1.530 +    {
   1.531 +        // We use a member savedCurrentContext which is initialized here, as opposed to having the user pass in a 
   1.532 +        // pre-existing Context (which the user could declare as a global or C++ member variable). We have to do this
   1.533 +        // because if we were to use some pre-existing Context the app might delete its underlying GL context behind our back
   1.534 +        // or associate it with another thread, which would cause our bind of it in our dtor to be a bad operation.
   1.535 +        savedCurrentContext.InitFromCurrent();
   1.536 +        if(ourContext.GetIncarnation() == 0) // If not yet initialized...
   1.537 +            ourContext.CreateShared(savedCurrentContext);
   1.538 +        ourContext.Bind();
   1.539 +        #if defined(OVR_OS_MAC) // To consider: merge the following into the Bind function.
   1.540 +            ourContext.SetSurface(savedCurrentContext);
   1.541 +        #endif
   1.542 +    }
   1.543 +
   1.544 +   ~AutoContext()
   1.545 +    {
   1.546 +        savedCurrentContext.Bind();
   1.547 +    }
   1.548 +
   1.549 +    OVR_NON_COPYABLE(AutoContext)
   1.550 +};
   1.551 +
   1.552 +
   1.553 +}}} // namespace OVR::CAPI::GL
   1.554 +
   1.555 +
   1.556 +#endif // INC_OVR_CAPI_GL_Util_h