mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-25 00:58:30 -05:00
Added GL vertex array object support.
This commit is contained in:
parent
3a251fbc02
commit
9e562eed97
5 changed files with 230 additions and 84 deletions
|
@ -206,7 +206,6 @@ Todo
|
|||
- OSX and iOS platforms.
|
||||
- DX11: MSAA.
|
||||
- GL: MSAA.
|
||||
- GL: ARB_vertex_array_object + OES_vertex_array_object.
|
||||
|
||||
Notice
|
||||
------
|
||||
|
|
|
@ -12,21 +12,21 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
inline float fmin(float _a, float _b)
|
||||
{
|
||||
return _a < _b ? _a : _b;
|
||||
}
|
||||
|
||||
inline float fmax(float _a, float _b)
|
||||
{
|
||||
return _a > _b ? _a : _b;
|
||||
}
|
||||
|
||||
inline float flerp(float _a, float _b, float _t)
|
||||
{
|
||||
return _a + (_b - _a) * _t;
|
||||
}
|
||||
|
||||
inline float fmin(float _a, float _b)
|
||||
{
|
||||
return _a < _b ? _a : _b;
|
||||
}
|
||||
|
||||
inline float fmax(float _a, float _b)
|
||||
{
|
||||
return _a > _b ? _a : _b;
|
||||
}
|
||||
|
||||
inline float flerp(float _a, float _b, float _t)
|
||||
{
|
||||
return _a + (_b - _a) * _t;
|
||||
}
|
||||
|
||||
inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
|
||||
{
|
||||
_result[0] = _a[0] + _b[0];
|
||||
|
@ -224,13 +224,13 @@ inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az)
|
|||
_result[ 0] = cy*cz;
|
||||
_result[ 1] = -cy*sz;
|
||||
_result[ 2] = sy;
|
||||
_result[ 4] = cz*sx*sy + cx*sz;
|
||||
_result[ 5] = cx*cz - sx*sy*sz;
|
||||
_result[ 4] = cz*sx*sy + cx*sz;
|
||||
_result[ 5] = cx*cz - sx*sy*sz;
|
||||
_result[ 6] = -cy*sx;
|
||||
_result[ 8] = -cx*cz*sy + sx*sz;
|
||||
_result[ 9] = cz*sx + cx*sy*sz;
|
||||
_result[10] = cx*cy;
|
||||
_result[15] = 1.0f;
|
||||
_result[ 8] = -cx*cz*sy + sx*sz;
|
||||
_result[ 9] = cz*sx + cx*sy*sz;
|
||||
_result[10] = cx*cy;
|
||||
_result[15] = 1.0f;
|
||||
}
|
||||
|
||||
inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
|
||||
|
@ -243,16 +243,16 @@ inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
|
|||
float cz = cosf(_az);
|
||||
|
||||
memset(_result, 0, sizeof(float)*16);
|
||||
_result[ 0] = cy*cz;
|
||||
_result[ 1] = cz*sx*sy-cx*sz;
|
||||
_result[ 2] = cx*cz*sy+sx*sz;
|
||||
_result[ 4] = cy*sz;
|
||||
_result[ 5] = cx*cz + sx*sy*sz;
|
||||
_result[ 6] = -cz*sx + cx*sy*sz;
|
||||
_result[ 8] = -sy;
|
||||
_result[ 9] = cy*sx;
|
||||
_result[10] = cx*cy;
|
||||
_result[15] = 1.0f;
|
||||
_result[ 0] = cy*cz;
|
||||
_result[ 1] = cz*sx*sy-cx*sz;
|
||||
_result[ 2] = cx*cz*sy+sx*sz;
|
||||
_result[ 4] = cy*sz;
|
||||
_result[ 5] = cx*cz + sx*sy*sz;
|
||||
_result[ 6] = -cz*sx + cx*sy*sz;
|
||||
_result[ 8] = -sy;
|
||||
_result[ 9] = cy*sx;
|
||||
_result[10] = cx*cy;
|
||||
_result[15] = 1.0f;
|
||||
};
|
||||
|
||||
inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
|
||||
|
|
|
@ -154,6 +154,10 @@ GL_IMPORT(true, PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC, glGetTranslatedShaderS
|
|||
GL_IMPORT(true, PFNGLGETPROGRAMBINARYOESPROC, glGetProgramBinaryOES);
|
||||
GL_IMPORT(true, PFNGLPROGRAMBINARYOESPROC, glProgramBinaryOES);
|
||||
|
||||
GL_IMPORT(true, PFNGLBINDVERTEXARRAYOESPROC, glBindVertexArray);
|
||||
GL_IMPORT(true, PFNGLDELETEVERTEXARRAYSOESPROC, glDeleteVertexArrays);
|
||||
GL_IMPORT(true, PFNGLGENVERTEXARRAYSOESPROC, glGenVertexArrays);
|
||||
|
||||
#endif // BGFX_CONFIG_RENDERER_
|
||||
|
||||
#if !BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
|
|
|
@ -10,20 +10,6 @@
|
|||
# include <bx/timer.h>
|
||||
# include <bx/uint32_t.h>
|
||||
|
||||
#if !BGFX_CONFIG_RENDERER_OPENGL
|
||||
# define glClearDepth glClearDepthf
|
||||
#endif // !BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGLES2
|
||||
# define glProgramBinary glProgramBinaryOES
|
||||
# define glGetProgramBinary glGetProgramBinaryOES
|
||||
# define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
|
||||
# define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
||||
# define GL_RGB10_A2 GL_RGB10_A2_EXT
|
||||
# define GL_UNSIGNED_INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
||||
# define GL_SAMPLER_3D GL_SAMPLER_3D_OES
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGLES2
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct Extension
|
||||
|
@ -64,6 +50,7 @@ namespace bgfx
|
|||
OES_vertex_type_10_10_10_2,
|
||||
EXT_occlusion_query_boolean,
|
||||
ARB_vertex_array_object,
|
||||
OES_vertex_array_object,
|
||||
ATI_meminfo,
|
||||
NVX_gpu_memory_info,
|
||||
|
||||
|
@ -111,6 +98,7 @@ namespace bgfx
|
|||
{ "GL_OES_vertex_type_10_10_10_2", false, true },
|
||||
{ "GL_EXT_occlusion_query_boolean", false, true },
|
||||
{ "GL_ARB_vertex_array_object", false, true },
|
||||
{ "OES_vertex_array_object", false, true },
|
||||
{ "GL_ATI_meminfo", false, true },
|
||||
{ "GL_NVX_gpu_memory_info", false, true },
|
||||
};
|
||||
|
@ -187,6 +175,7 @@ namespace bgfx
|
|||
, m_captureSize(0)
|
||||
, m_maxAnisotropy(0.0f)
|
||||
, m_dxtSupport(false)
|
||||
, m_vaoSupport(false)
|
||||
, m_programBinarySupport(false)
|
||||
, m_textureSwizzleSupport(false)
|
||||
, m_flip(false)
|
||||
|
@ -613,6 +602,11 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void invalidateCache()
|
||||
{
|
||||
m_vaoCache.invalidate();
|
||||
}
|
||||
|
||||
void updateCapture()
|
||||
{
|
||||
if (m_resolution.m_flags&BGFX_RESET_CAPTURE)
|
||||
|
@ -695,6 +689,8 @@ namespace bgfx
|
|||
|
||||
void shutdown()
|
||||
{
|
||||
invalidateCache();
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
m_queries.destroy();
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
@ -731,6 +727,8 @@ namespace bgfx
|
|||
Queries m_queries;
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
VaoCache m_vaoCache;
|
||||
|
||||
TextVideoMem m_textVideoMem;
|
||||
|
||||
Resolution m_resolution;
|
||||
|
@ -738,6 +736,7 @@ namespace bgfx
|
|||
uint32_t m_captureSize;
|
||||
float m_maxAnisotropy;
|
||||
bool m_dxtSupport;
|
||||
bool m_vaoSupport;
|
||||
bool m_programBinarySupport;
|
||||
bool m_textureSwizzleSupport;
|
||||
bool m_flip;
|
||||
|
@ -2054,6 +2053,11 @@ namespace bgfx
|
|||
|
||||
void TextVideoMemBlitter::setup()
|
||||
{
|
||||
if (s_renderCtx.m_vaoSupport)
|
||||
{
|
||||
GL_CHECK(glBindVertexArray(0) );
|
||||
}
|
||||
|
||||
uint32_t width = s_renderCtx.m_resolution.m_width;
|
||||
uint32_t height = s_renderCtx.m_resolution.m_height;
|
||||
|
||||
|
@ -2223,6 +2227,11 @@ namespace bgfx
|
|||
s_extension[Extension::EXT_texture_compression_s3tc].m_supported
|
||||
;
|
||||
|
||||
s_renderCtx.m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
|| s_extension[Extension::ARB_vertex_array_object].m_supported
|
||||
|| s_extension[Extension::OES_vertex_array_object].m_supported
|
||||
;
|
||||
|
||||
s_renderCtx.m_programBinarySupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
|| s_extension[Extension::ARB_get_program_binary].m_supported
|
||||
|| s_extension[Extension::OES_get_program_binary].m_supported
|
||||
|
@ -2903,57 +2912,124 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || programChanged)
|
||||
if (s_renderCtx.m_vaoSupport)
|
||||
{
|
||||
currentState.m_vertexBuffer = state.m_vertexBuffer;
|
||||
if (programChanged
|
||||
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx
|
||||
|| baseVertex != state.m_startVertex
|
||||
|| currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
|
||||
{
|
||||
uint64_t hash = (uint64_t(state.m_vertexBuffer.idx)<<48)
|
||||
| (uint64_t(state.m_indexBuffer.idx)<<32)
|
||||
| (uint64_t(state.m_instanceDataBuffer.idx)<<16)
|
||||
| programIdx
|
||||
;
|
||||
hash ^= state.m_startVertex;
|
||||
|
||||
uint16_t handle = state.m_vertexBuffer.idx;
|
||||
if (invalidHandle != handle)
|
||||
{
|
||||
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
|
||||
bindAttribs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
||||
currentState.m_vertexBuffer = state.m_vertexBuffer;
|
||||
currentState.m_indexBuffer = state.m_indexBuffer;
|
||||
baseVertex = state.m_startVertex;
|
||||
|
||||
GLuint id = s_renderCtx.m_vaoCache.find(hash);
|
||||
if (UINT32_MAX != id)
|
||||
{
|
||||
GL_CHECK(glBindVertexArray(id) );
|
||||
}
|
||||
else
|
||||
{
|
||||
id = s_renderCtx.m_vaoCache.add(hash);
|
||||
GL_CHECK(glBindVertexArray(id) );
|
||||
|
||||
if (invalidHandle != state.m_vertexBuffer.idx)
|
||||
{
|
||||
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
|
||||
|
||||
uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
|
||||
const Program& program = s_renderCtx.m_program[programIdx];
|
||||
program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
|
||||
|
||||
if (invalidHandle != state.m_instanceDataBuffer.idx)
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
|
||||
program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
||||
}
|
||||
|
||||
if (invalidHandle != state.m_indexBuffer.idx)
|
||||
{
|
||||
IndexBuffer& ib = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx];
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
|
||||
else
|
||||
{
|
||||
currentState.m_indexBuffer = state.m_indexBuffer;
|
||||
if (programChanged
|
||||
|| currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx)
|
||||
{
|
||||
currentState.m_vertexBuffer = state.m_vertexBuffer;
|
||||
|
||||
uint16_t handle = state.m_indexBuffer.idx;
|
||||
if (invalidHandle != handle)
|
||||
{
|
||||
IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
|
||||
uint16_t handle = state.m_vertexBuffer.idx;
|
||||
if (invalidHandle != handle)
|
||||
{
|
||||
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
|
||||
bindAttribs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
||||
currentState.m_indexBuffer = state.m_indexBuffer;
|
||||
|
||||
uint16_t handle = state.m_indexBuffer.idx;
|
||||
if (invalidHandle != handle)
|
||||
{
|
||||
IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidHandle != currentState.m_vertexBuffer.idx)
|
||||
{
|
||||
if (baseVertex != state.m_startVertex
|
||||
|| bindAttribs)
|
||||
{
|
||||
baseVertex = state.m_startVertex;
|
||||
const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
|
||||
uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
|
||||
const Program& program = s_renderCtx.m_program[programIdx];
|
||||
program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
|
||||
|
||||
if (invalidHandle != state.m_instanceDataBuffer.idx)
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
|
||||
program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidHandle != currentState.m_vertexBuffer.idx)
|
||||
{
|
||||
if (baseVertex != state.m_startVertex
|
||||
|| bindAttribs)
|
||||
{
|
||||
baseVertex = state.m_startVertex;
|
||||
const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
|
||||
uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
|
||||
const Program& program = s_renderCtx.m_program[programIdx];
|
||||
program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
|
||||
|
||||
if (invalidHandle != state.m_instanceDataBuffer.idx)
|
||||
{
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
|
||||
program.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t numVertices = state.m_numVertices;
|
||||
if (UINT32_C(0xffffffff) == numVertices)
|
||||
{
|
||||
|
|
|
@ -196,6 +196,23 @@ typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum z
|
|||
# define GL_APIENTRYP GL_APIENTRY*
|
||||
#endif // GL_APIENTRYP
|
||||
|
||||
#if !BGFX_CONFIG_RENDERER_OPENGL
|
||||
# define glClearDepth glClearDepthf
|
||||
#endif // !BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGLES2
|
||||
# define glProgramBinary glProgramBinaryOES
|
||||
# define glGetProgramBinary glGetProgramBinaryOES
|
||||
# define glBindVertexArray glBindVertexArrayOES
|
||||
# define glDeleteVertexArrays glDeleteVertexArraysOES
|
||||
# define glGenVertexArrays glGenVertexArraysOES
|
||||
# define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
|
||||
# define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
||||
# define GL_RGB10_A2 GL_RGB10_A2_EXT
|
||||
# define GL_UNSIGNED_INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
||||
# define GL_SAMPLER_3D GL_SAMPLER_3D_OES
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGLES2
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORBGFXPROC)(GLuint _index, GLuint _divisor);
|
||||
|
@ -331,6 +348,56 @@ namespace bgfx
|
|||
VertexDeclHandle m_decl;
|
||||
};
|
||||
|
||||
class VaoCache
|
||||
{
|
||||
public:
|
||||
GLuint add(uint64_t _hash)
|
||||
{
|
||||
invalidate(_hash);
|
||||
|
||||
GLuint arrayId;
|
||||
GL_CHECK(glGenVertexArrays(1, &arrayId) );
|
||||
|
||||
m_hashMap.insert(stl::make_pair(_hash, arrayId) );
|
||||
|
||||
return arrayId;
|
||||
}
|
||||
|
||||
GLuint find(uint64_t _hash)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_hash);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
void invalidate(uint64_t _hash)
|
||||
{
|
||||
HashMap::iterator it = m_hashMap.find(_hash);
|
||||
if (it != m_hashMap.end() )
|
||||
{
|
||||
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
||||
m_hashMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
|
||||
{
|
||||
GL_CHECK(glDeleteVertexArrays(1, &it->second) );
|
||||
}
|
||||
m_hashMap.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef stl::unordered_map<uint64_t, GLuint> HashMap;
|
||||
HashMap m_hashMap;
|
||||
};
|
||||
|
||||
struct Texture
|
||||
{
|
||||
Texture()
|
||||
|
|
Loading…
Reference in a new issue