VrAppFrameworkの型について

SDKのソースを読んでいるうちにどのデータにどういうプロパティがあって、どういう役割なのか頭がこんがらがってきたのでまとめてみた。

## ovrSurfaceDef

3Dオブジェクトの形状と描画方法に関する情報

```cpp:ovrSurfaceDef
struct ovrSurfaceDef
{
  ovrSurfaceDef() : numInstances( 1 ) {}

  // モデルファイルからの名前。コードからサーフェイスを操作するのに使用できる。
  // 複数のソースメッシュが一つのサーフェイスにマージされる場合、セミコロン区切りで複数の名前になることがある。
  String surfaceName;

  // There is a space savings to be had with triangle strips
  // if primitive restart is supported, but it is a net speed
  // loss on most architectures.  Adreno docs still recommend,
  // so it might be worth trying.
  GlGeometry geo;

  // state + program + uniforms
  ovrGraphicsCommand graphicsCommand;

  // レンダリングされるインスタンスの数(0 か 1 はインスタンス化を表しません)
  int numInstances;
};
```

## ovrGraphicsCommand

描画方法の詳細

```cpp:ovrGraphicsCommand
struct ovrGraphicsCommand
{
  GlProgram       Program;
  ovrGpuState     GpuState;
  ovrUniformData  UniformData[ovrUniform::MAX_UNIFORMS]; // Program.Uniforms[]に対応するデータ

  // ----非推奨
  // the old ovrMaterialDef interface... this will go away eventually!
  bool UseDeprecatedInterface;
  ovrGraphicsCommand()
  : UseDeprecatedInterface( false )
  , numTextures( 0 )
  {
    for ( int i = 0; i < ovrUniform::MAX_UNIFORMS; ++i )
    {
      uniformSlots[i] = -1;
    }
  }

  // Parameter setting stops when uniformSlots[x] == -1
  GLint		uniformSlots[ovrUniform::MAX_UNIFORMS];
  GLfloat		uniformValues[ovrUniform::MAX_UNIFORMS][4];

  // Currently assumes GL_TEXTURE_2D for all; will need to be
  // extended for GL_TEXTURE_CUBE and GL_TEXTURE_EXTERNAL_OES.
  //
  // There should never be any 0 textures in the active elements.
  //
  // This should be a range checked container.
  int			numTextures;
  GlTexture	textures[ovrUniform::MAX_UNIFORMS];
  // There should only be one joint uniform buffer for the deprecated path.
  GlBuffer	joints;
  // ----非推奨
};
```

## ovrDrawSurface

サーフェイスをどの位置に描画するか

```cpp:ovrDrawSurface
struct ovrDrawSurface
{
  ovrDrawSurface();

  ovrDrawSurface(const Matrix4f & modelMatrix, const ovrSurfaceDef * surface);

  ovrDrawSurface(const ovrSurfaceDef * surface);

  void Clear();

  Matrix4f              modelMatrix;
  const ovrSurfaceDef * surface;
};
```

## ovrGpuState

個々のオブジェクトを描画する時のブレンドモード等

```cpp:ovrGpuState
struct ovrGpuState
{
	enum ovrBlendEnable
	{
		BLEND_DISABLE,
		BLEND_ENABLE,
		BLEND_ENABLE_SEPARATE
	};

	ovrGpuState() // デフォルト値
		: blendMode( GL_FUNC_ADD )
		, blendSrc( GL_ONE )
		, blendDst( GL_ZERO )
		, blendSrcAlpha( GL_ONE )
		, blendDstAlpha( GL_ZERO )
		, blendModeAlpha( GL_FUNC_ADD )
		, depthFunc( GL_LEQUAL )
		, frontFace( GL_CCW )
		, polygonMode( GL_FILL )
		, blendEnable( BLEND_DISABLE )
		, depthEnable( true )
		, depthMaskEnable( true )
		, polygonOffsetEnable( false )
		, cullEnable( true )
		, lineWidth( 1.0f )
	{
		colorMaskEnable[0] = colorMaskEnable[1] = colorMaskEnable[2] = colorMaskEnable[3] = true;
		depthRange[0] = 0.0f;
		depthRange[1] = 1.0f;
	}

	GLenum	blendMode;		// GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX
	GLenum	blendSrc;
	GLenum	blendDst;
	GLenum	blendSrcAlpha;
	GLenum	blendDstAlpha;
	GLenum	blendModeAlpha;
	GLenum	depthFunc;
	GLenum	frontFace;		// GL_CW, GL_CCW
	GLenum	polygonMode;

	ovrBlendEnable	blendEnable;	// off, normal, separate

	bool		depthEnable;
	bool		depthMaskEnable;
	bool		colorMaskEnable[4];
	bool		polygonOffsetEnable;
	bool		cullEnable;
	GLfloat		lineWidth;
	GLfloat		depthRange[2];		// nearVal, farVal
};
```

## GlProgram

OpenGLプログラムを抽象化する。`ovrGraphicsCommand`の`Program`に渡す。

頂点シェーダーとフラグメントシェーダーの文字列を使って作成する例(Oculus360Videosより抜粋、一部変更)。

```cpp
static const char * imageExternalDirectives =
	"#extension GL_OES_EGL_image_external : enable\n"
	"#extension GL_OES_EGL_image_external_essl3 : enable\n";

static const char * vertexShaderSrc =
	"uniform highp mat4 Texm[NUM_VIEWS];\n"
	"attribute vec4 Position;\n"
	"attribute vec2 TexCoord;\n"
	"varying  highp vec2 oTexCoord;\n"
	"void main()\n"
	"{\n"
	"   gl_Position = TransformVertex( Position );\n"
	"   oTexCoord = vec2( Texm[VIEW_ID] * vec4( TexCoord, 0, 1 ) );\n"
	"}\n";

static const char * fragmentShaderSrc =
	"uniform samplerExternalOES Texture0;\n"
	"uniform lowp vec4 UniformColor;\n"
	"varying highp vec2 oTexCoord;\n"
	"void main()\n"
	"{\n"
	"	gl_FragColor = UniformColor * texture2D( Texture0, oTexCoord );\n"
	"}\n";

static ovrProgramParm parms[] =
{
    { "Texm",         ovrProgramParmType::FLOAT_MATRIX4 },
    { "UniformColor", ovrProgramParmType::FLOAT_VECTOR4 },
    { "Texture0",     ovrProgramParmType::TEXTURE_SAMPLED },
};

program = GlProgram::Build( NULL, vertexShaderSrc, imageExternalDirectives, fragmentShaderSrc,
                           parms, sizeof( parms ) / sizeof( ovrProgramParm ) );
```

不要になったら破棄する。

```cpp
GlProgram::Free( program );
```