Added stencil support.

This commit is contained in:
bkaradzic 2012-11-10 19:59:23 -08:00
parent 3df2825243
commit e3a31a2efc
13 changed files with 2449 additions and 245 deletions

View file

@ -3,11 +3,21 @@ bgfx
Cross-platform rendering library.
Supports:
OpenGL 2.1, OpenGL ES 2.0, and Direct3D 9.0.
Supported rendering backends:
Platforms:
Windows, Linux, Android, and Native Client.
* OpenGL 2.1
* OpenGL ES 2
* OpenGL ES 3
* Direct3D 9
* Direct3D 11
Platforms:
* Windows
* Linux
* Android
* Native Client
* JavaScript (via Emscripten)
Dependencies
------------
@ -45,6 +55,30 @@ Configuration is <platform>-<debug/release><32/64>. For example:
linux-release32, nacl-debug64, android-release32, etc.
Examples
--------
### 00-helloworld
Initialization and debug text.
### 01-cubes
Rendering simple static mesh.
### 02-metaballs
Rendering with transient buffers.
### 03-raymarch
Updating shader uniforms.
### 04-mesh
Loading OpenCTM meshes.
### 05-instancing
Geometry instancing.
### 06-bump
Loading textures.
Notice
------

View file

@ -612,156 +612,147 @@ int _main_(int _argc, char** _argv)
// Allocate 32K vertices in transient vertex buffer.
uint32_t maxVertices = (32<<10);
const bgfx::TransientVertexBuffer* tvb = bgfx::allocTransientVertexBuffer(maxVertices, s_PosNormalColorDecl);
bgfx::TransientVertexBuffer tvb;
bgfx::allocTransientVertexBuffer(&tvb, maxVertices, s_PosNormalColorDecl);
// If there is no enough space in transient vertex buffer alloc will return NULL.
if (NULL != tvb)
const uint32_t numSpheres = 16;
float sphere[numSpheres][4];
for (uint32_t ii = 0; ii < numSpheres; ++ii)
{
const uint32_t numSpheres = 16;
float sphere[numSpheres][4];
for (uint32_t ii = 0; ii < numSpheres; ++ii)
{
sphere[ii][0] = sin(time*(ii*0.21f)+ii*0.37f) * (DIMS * 0.5f - 8.0f);
sphere[ii][1] = sin(time*(ii*0.37f)+ii*0.67f) * (DIMS * 0.5f - 8.0f);
sphere[ii][2] = cos(time*(ii*0.11f)+ii*0.13f) * (DIMS * 0.5f - 8.0f);
sphere[ii][3] = 1.0f/(2.0f + (sin(time*(ii*0.13f) )*0.5f+0.5f)*2.0f);
}
profUpdate = bx::getHPCounter();
for (uint32_t zz = 0; zz < DIMS; ++zz)
{
for (uint32_t yy = 0; yy < DIMS; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
for (uint32_t xx = 0; xx < DIMS; ++xx)
{
uint32_t xoffset = offset + xx;
float dist = 0.0f;
float prod = 1.0f;
for (uint32_t ii = 0; ii < numSpheres; ++ii)
{
const float* pos = sphere[ii];
float dx = pos[0] - (-DIMS*0.5f + float(xx) );
float dy = pos[1] - (-DIMS*0.5f + float(yy) );
float dz = pos[2] - (-DIMS*0.5f + float(zz) );
float invr = pos[3];
float dot = dx*dx + dy*dy + dz*dz;
dot *= invr*invr;
dist *= dot;
dist += prod;
prod *= dot;
}
grid[xoffset].m_val = dist / prod - 1.0f;
}
}
}
profUpdate = bx::getHPCounter() - profUpdate;
profNormal = bx::getHPCounter();
for (uint32_t zz = 1; zz < DIMS-1; ++zz)
{
for (uint32_t yy = 1; yy < DIMS-1; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
for (uint32_t xx = 1; xx < DIMS-1; ++xx)
{
uint32_t xoffset = offset + xx;
float normal[3] =
{
grid[xoffset-1 ].m_val - grid[xoffset+1 ].m_val,
grid[xoffset-ypitch].m_val - grid[xoffset+ypitch].m_val,
grid[xoffset-zpitch].m_val - grid[xoffset+zpitch].m_val,
};
vec3Norm(grid[xoffset].m_normal, normal);
}
}
}
profNormal = bx::getHPCounter() - profNormal;
profTriangulate = bx::getHPCounter();
PosNormalColorVertex* vertex = (PosNormalColorVertex*)tvb->data;
for (uint32_t zz = 0; zz < DIMS-1 && numVertices+12 < maxVertices; ++zz)
{
float rgb[6];
rgb[2] = zz*invdim;
rgb[5] = (zz+1)*invdim;
for (uint32_t yy = 0; yy < DIMS-1 && numVertices+12 < maxVertices; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
rgb[1] = yy*invdim;
rgb[4] = (yy+1)*invdim;
for (uint32_t xx = 0; xx < DIMS-1 && numVertices+12 < maxVertices; ++xx)
{
uint32_t xoffset = offset + xx;
rgb[0] = xx*invdim;
rgb[3] = (xx+1)*invdim;
float pos[3] =
{
-DIMS*0.5f + float(xx),
-DIMS*0.5f + float(yy),
-DIMS*0.5f + float(zz)
};
const Grid* val[8] = {
&grid[xoffset+zpitch+ypitch ],
&grid[xoffset+zpitch+ypitch+1],
&grid[xoffset+ypitch+1 ],
&grid[xoffset+ypitch ],
&grid[xoffset+zpitch ],
&grid[xoffset+zpitch+1 ],
&grid[xoffset+1 ],
&grid[xoffset ],
};
uint32_t num = triangulate( (uint8_t*)vertex, s_PosNormalColorDecl.m_stride, rgb, pos, val, 0.5f);
vertex += num;
numVertices += num;
}
}
}
profTriangulate = bx::getHPCounter() - profTriangulate;
float mtx[16];
mtxRotateXY(mtx, time*0.67f, time);
// Set model matrix for rendering.
bgfx::setTransform(mtx);
// Set vertex and fragment shaders.
bgfx::setProgram(program);
// Set vertex and index buffer.
bgfx::setVertexBuffer(tvb, numVertices);
// Set render states.
bgfx::setState(BGFX_STATE_RGB_WRITE
|BGFX_STATE_DEPTH_WRITE
|BGFX_STATE_DEPTH_TEST_LESS
);
// Submit primitive for rendering to view 0.
bgfx::submit(0);
sphere[ii][0] = sin(time*(ii*0.21f)+ii*0.37f) * (DIMS * 0.5f - 8.0f);
sphere[ii][1] = sin(time*(ii*0.37f)+ii*0.67f) * (DIMS * 0.5f - 8.0f);
sphere[ii][2] = cos(time*(ii*0.11f)+ii*0.13f) * (DIMS * 0.5f - 8.0f);
sphere[ii][3] = 1.0f/(2.0f + (sin(time*(ii*0.13f) )*0.5f+0.5f)*2.0f);
}
profUpdate = bx::getHPCounter();
for (uint32_t zz = 0; zz < DIMS; ++zz)
{
for (uint32_t yy = 0; yy < DIMS; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
for (uint32_t xx = 0; xx < DIMS; ++xx)
{
uint32_t xoffset = offset + xx;
float dist = 0.0f;
float prod = 1.0f;
for (uint32_t ii = 0; ii < numSpheres; ++ii)
{
const float* pos = sphere[ii];
float dx = pos[0] - (-DIMS*0.5f + float(xx) );
float dy = pos[1] - (-DIMS*0.5f + float(yy) );
float dz = pos[2] - (-DIMS*0.5f + float(zz) );
float invr = pos[3];
float dot = dx*dx + dy*dy + dz*dz;
dot *= invr*invr;
dist *= dot;
dist += prod;
prod *= dot;
}
grid[xoffset].m_val = dist / prod - 1.0f;
}
}
}
profUpdate = bx::getHPCounter() - profUpdate;
profNormal = bx::getHPCounter();
for (uint32_t zz = 1; zz < DIMS-1; ++zz)
{
for (uint32_t yy = 1; yy < DIMS-1; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
for (uint32_t xx = 1; xx < DIMS-1; ++xx)
{
uint32_t xoffset = offset + xx;
float normal[3] =
{
grid[xoffset-1 ].m_val - grid[xoffset+1 ].m_val,
grid[xoffset-ypitch].m_val - grid[xoffset+ypitch].m_val,
grid[xoffset-zpitch].m_val - grid[xoffset+zpitch].m_val,
};
vec3Norm(grid[xoffset].m_normal, normal);
}
}
}
profNormal = bx::getHPCounter() - profNormal;
profTriangulate = bx::getHPCounter();
PosNormalColorVertex* vertex = (PosNormalColorVertex*)tvb.data;
for (uint32_t zz = 0; zz < DIMS-1 && numVertices+12 < maxVertices; ++zz)
{
float rgb[6];
rgb[2] = zz*invdim;
rgb[5] = (zz+1)*invdim;
for (uint32_t yy = 0; yy < DIMS-1 && numVertices+12 < maxVertices; ++yy)
{
uint32_t offset = (zz*DIMS+yy)*DIMS;
rgb[1] = yy*invdim;
rgb[4] = (yy+1)*invdim;
for (uint32_t xx = 0; xx < DIMS-1 && numVertices+12 < maxVertices; ++xx)
{
uint32_t xoffset = offset + xx;
rgb[0] = xx*invdim;
rgb[3] = (xx+1)*invdim;
float pos[3] =
{
-DIMS*0.5f + float(xx),
-DIMS*0.5f + float(yy),
-DIMS*0.5f + float(zz)
};
const Grid* val[8] = {
&grid[xoffset+zpitch+ypitch ],
&grid[xoffset+zpitch+ypitch+1],
&grid[xoffset+ypitch+1 ],
&grid[xoffset+ypitch ],
&grid[xoffset+zpitch ],
&grid[xoffset+zpitch+1 ],
&grid[xoffset+1 ],
&grid[xoffset ],
};
uint32_t num = triangulate( (uint8_t*)vertex, s_PosNormalColorDecl.m_stride, rgb, pos, val, 0.5f);
vertex += num;
numVertices += num;
}
}
}
profTriangulate = bx::getHPCounter() - profTriangulate;
float mtx[16];
mtxRotateXY(mtx, time*0.67f, time);
// Set model matrix for rendering.
bgfx::setTransform(mtx);
// Set vertex and fragment shaders.
bgfx::setProgram(program);
// Set vertex and index buffer.
bgfx::setVertexBuffer(&tvb, numVertices);
// Submit primitive for rendering to view 0.
bgfx::submit(0);
// Display stats.
bgfx::dbgTextPrintf(1, 4, 0x0f, "Num vertices: %5d (%6.4f%%)", numVertices, float(numVertices)/maxVertices * 100);
bgfx::dbgTextPrintf(1, 5, 0x0f, " Update: % 7.3f[ms]", double(profUpdate)*toMs);

View file

@ -97,13 +97,13 @@ static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
return program;
}
bool allocTransientBuffers(const bgfx::TransientVertexBuffer*& _vb, const bgfx::VertexDecl& _decl, uint16_t _numVertices, const bgfx::TransientIndexBuffer*& _ib, uint16_t _numIndices)
bool allocTransientBuffers(const bgfx::TransientVertexBuffer*& _vb, const bgfx::VertexDecl& _decl, uint16_t _numVertices, bgfx::TransientIndexBuffer* _ib, uint16_t _numIndices)
{
if (bgfx::checkAvailTransientVertexBuffer(_numVertices, _decl)
&& bgfx::checkAvailTransientIndexBuffer(_numIndices) )
{
_vb = bgfx::allocTransientVertexBuffer(_numVertices, _decl);
_ib = bgfx::allocTransientIndexBuffer(_numIndices);
bgfx::allocTransientIndexBuffer(&_ib, _numIndices);
return true;
}
@ -113,9 +113,9 @@ bool allocTransientBuffers(const bgfx::TransientVertexBuffer*& _vb, const bgfx::
void renderScreenSpaceQuad(uint32_t _view, bgfx::ProgramHandle _program, float _x, float _y, float _width, float _height)
{
const bgfx::TransientVertexBuffer* vb;
const bgfx::TransientIndexBuffer* ib;
const bgfx::TransientIndexBuffer ib;
if (allocTransientBuffers(vb, s_PosColorTexCoord0Decl, 4, ib, 6) )
if (allocTransientBuffers(vb, s_PosColorTexCoord0Decl, 4, &ib, 6) )
{
PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb->data;
@ -252,7 +252,7 @@ int _main_(int _argc, char** _argv)
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/03-raymarch");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating uniforms.");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating shader uniforms.");
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
float at[3] = { 0.0f, 0.0f, 0.0f };

View file

@ -9,6 +9,7 @@
#include <stdint.h> // uint32_t
#include <stdlib.h> // size_t
///
#define BGFX_STATE_DEPTH_WRITE UINT64_C(0x0000000000000001)
#define BGFX_STATE_ALPHA_TEST UINT64_C(0x0000000000000004)
@ -88,17 +89,77 @@
#define BGFX_STATE_ALPHA_REF(_ref) ( (uint64_t(_ref)<<BGFX_STATE_ALPHA_REF_SHIFT)&BGFX_STATE_ALPHA_REF_MASK)
#define BGFX_STATE_POINT_SIZE(_size) ( (uint64_t(_size)<<BGFX_STATE_POINT_SIZE_SHIFT)&BGFX_STATE_POINT_SIZE_MASK)
///
#define BGFX_STENCIL_FUNC_REF_SHIFT 0
#define BGFX_STENCIL_FUNC_REF_MASK UINT32_C(0x000000ff)
#define BGFX_STENCIL_FUNC_RMASK_SHIFT 8
#define BGFX_STENCIL_FUNC_RMASK_MASK UINT32_C(0x0000ff00)
#define BGFX_STENCIL_TEST_LESS UINT32_C(0x00010000)
#define BGFX_STENCIL_TEST_LEQUAL UINT32_C(0x00020000)
#define BGFX_STENCIL_TEST_EQUAL UINT32_C(0x00030000)
#define BGFX_STENCIL_TEST_GEQUAL UINT32_C(0x00040000)
#define BGFX_STENCIL_TEST_GREATER UINT32_C(0x00050000)
#define BGFX_STENCIL_TEST_NOTEQUAL UINT32_C(0x00060000)
#define BGFX_STENCIL_TEST_NEVER UINT32_C(0x00070000)
#define BGFX_STENCIL_TEST_ALWAYS UINT32_C(0x00080000)
#define BGFX_STENCIL_TEST_SHIFT 16
#define BGFX_STENCIL_TEST_MASK UINT32_C(0x000f0000)
#define BGFX_STENCIL_OP_FAIL_S_ZERO UINT32_C(0x00000000)
#define BGFX_STENCIL_OP_FAIL_S_KEEP UINT32_C(0x00100000)
#define BGFX_STENCIL_OP_FAIL_S_REPLACE UINT32_C(0x00200000)
#define BGFX_STENCIL_OP_FAIL_S_INCR UINT32_C(0x00300000)
#define BGFX_STENCIL_OP_FAIL_S_INCRSAT UINT32_C(0x00400000)
#define BGFX_STENCIL_OP_FAIL_S_DECR UINT32_C(0x00500000)
#define BGFX_STENCIL_OP_FAIL_S_DECRSAT UINT32_C(0x00600000)
#define BGFX_STENCIL_OP_FAIL_S_INVERT UINT32_C(0x00700000)
#define BGFX_STENCIL_OP_FAIL_S_SHIFT 20
#define BGFX_STENCIL_OP_FAIL_S_MASK UINT32_C(0x00f00000)
#define BGFX_STENCIL_OP_FAIL_Z_ZERO UINT32_C(0x00000000)
#define BGFX_STENCIL_OP_FAIL_Z_KEEP UINT32_C(0x01000000)
#define BGFX_STENCIL_OP_FAIL_Z_REPLACE UINT32_C(0x02000000)
#define BGFX_STENCIL_OP_FAIL_Z_INCR UINT32_C(0x03000000)
#define BGFX_STENCIL_OP_FAIL_Z_INCRSAT UINT32_C(0x04000000)
#define BGFX_STENCIL_OP_FAIL_Z_DECR UINT32_C(0x05000000)
#define BGFX_STENCIL_OP_FAIL_Z_DECRSAT UINT32_C(0x06000000)
#define BGFX_STENCIL_OP_FAIL_Z_INVERT UINT32_C(0x07000000)
#define BGFX_STENCIL_OP_FAIL_Z_SHIFT 24
#define BGFX_STENCIL_OP_FAIL_Z_MASK UINT32_C(0x0f000000)
#define BGFX_STENCIL_OP_PASS_Z_ZERO UINT32_C(0x00000000)
#define BGFX_STENCIL_OP_PASS_Z_KEEP UINT32_C(0x10000000)
#define BGFX_STENCIL_OP_PASS_Z_REPLACE UINT32_C(0x20000000)
#define BGFX_STENCIL_OP_PASS_Z_INCR UINT32_C(0x30000000)
#define BGFX_STENCIL_OP_PASS_Z_INCRSAT UINT32_C(0x40000000)
#define BGFX_STENCIL_OP_PASS_Z_DECR UINT32_C(0x50000000)
#define BGFX_STENCIL_OP_PASS_Z_DECRSAT UINT32_C(0x60000000)
#define BGFX_STENCIL_OP_PASS_Z_INVERT UINT32_C(0x70000000)
#define BGFX_STENCIL_OP_PASS_Z_SHIFT 28
#define BGFX_STENCIL_OP_PASS_Z_MASK UINT32_C(0xf0000000)
#define BGFX_STENCIL_NONE UINT32_C(0x00000000)
#define BGFX_STENCIL_MASK UINT32_C(0xffffffff)
#define BGFX_STENCIL_DEFAULT UINT32_C(0x00000000)
#define BGFX_STENCIL_FUNC_REF(_ref) ( (uint32_t(_ref)<<BGFX_STENCIL_FUNC_REF_SHIFT)&BGFX_STENCIL_FUNC_REF_MASK)
#define BGFX_STENCIL_FUNC_RMASK(_mask) ( (uint32_t(_mask)<<BGFX_STENCIL_FUNC_RMASK_SHIFT)&BGFX_STENCIL_FUNC_RMASK_MASK)
///
#define BGFX_CLEAR_NONE UINT8_C(0x00)
#define BGFX_CLEAR_COLOR_BIT UINT8_C(0x01)
#define BGFX_CLEAR_DEPTH_BIT UINT8_C(0x02)
#define BGFX_CLEAR_STENCIL_BIT UINT8_C(0x04)
///
#define BGFX_DEBUG_NONE UINT32_C(0x00000000)
#define BGFX_DEBUG_WIREFRAME UINT32_C(0x00000001)
#define BGFX_DEBUG_IFH UINT32_C(0x00000002)
#define BGFX_DEBUG_STATS UINT32_C(0x00000004)
#define BGFX_DEBUG_TEXT UINT32_C(0x00000008)
///
#define BGFX_TEXTURE_NONE UINT32_C(0x00000000)
#define BGFX_TEXTURE_U_REPEAT UINT32_C(0x00000000)
#define BGFX_TEXTURE_U_MIRROR UINT32_C(0x00000001)
@ -126,6 +187,7 @@
#define BGFX_TEXTURE_MIP_MASK UINT32_C(0x00100000)
#define BGFX_TEXTURE_SRGB UINT32_C(0x00200000)
///
#define BGFX_RENDER_TARGET_NONE UINT32_C(0x00000000)
#define BGFX_RENDER_TARGET_COLOR_RGBA UINT32_C(0x00000001)
#define BGFX_RENDER_TARGET_COLOR_R32F UINT32_C(0x00000002)
@ -142,6 +204,7 @@
#define BGFX_RENDER_TARGET_MSAA_MASK UINT32_C(0x00070000)
#define BGFX_RENDER_TARGET_SRGBWRITE UINT32_C(0x00080000)
///
#define BGFX_RESET_NONE UINT32_C(0x00000000)
#define BGFX_RESET_FULLSCREEN UINT32_C(0x00000001)
#define BGFX_RESET_FULLSCREEN_FAKE UINT32_C(0x00000002)
@ -155,9 +218,11 @@
#define BGFX_RESET_MSAA_MASK UINT32_C(0x00000070)
#define BGFX_RESET_VSYNC UINT32_C(0x00000080)
///
#define BGFX_HANDLE(_name) struct _name { uint16_t idx; }
#define BGFX_INVALID_HANDLE { bgfx::invalidHandle }
/// BGFX
namespace bgfx
{
struct Fatal
@ -384,11 +449,11 @@ namespace bgfx
/// Set debug flags.
///
/// Available flags:
/// @param _debug Available flags:
///
/// BGFX_DEBUG_IFH - Infinitely fast hardware. When this flag is set
/// all rendering calls will be skipped. It's useful for quickly
/// assessing bottleneck between CPU and GPU.
/// all rendering calls will be skipped. It's useful when profiling
/// to quickly assess bottleneck between CPU and GPU.
///
/// BGFX_DEBUG_STATS - Display internal statistics.
///
@ -444,14 +509,23 @@ namespace bgfx
/// Returns true if internal transient index buffer has enough space.
bool checkAvailTransientIndexBuffer(uint16_t _num);
/// Allocate transient index buffer.
///
const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num);
/// @param[out] _tib is valid for the duration of frame, and it can be reused for
/// multiple draw calls.
/// @param _num number of indices to allocate.
void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint16_t _num);
/// Returns true if internal transient vertex buffer has enough space.
bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl);
/// Allocate transient vertex buffer.
///
const TransientVertexBuffer* allocTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl);
/// @param[out] _tvb is valid for the duration of frame, and it can be reused for
/// multiple draw calls.
/// @param _num number of vertices to allocate.
/// @param _decl vertex declaration.
void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint16_t _num, const VertexDecl& _decl);
///
const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride);
@ -549,14 +623,26 @@ namespace bgfx
/// BGFX_STATE_*
void setState(uint64_t _state);
/// Set stencil test state.
///
/// @param _fstencil Front stencil state.
/// @param _bstencil Back stencil state. If back is set to BGFX_STENCIL_NONE
/// _fstencil is applied to both front and back facing primitives.
void setStencil(uint32_t _fstencil, uint32_t _bstencil = BGFX_STENCIL_NONE);
/// Set model matrix for draw primitive. If it is not called model will
/// be rendered with identity model matrix.
///
/// Returns index into matrix cache in case the same model matrix has to
/// @param _mtx pointer to first matrix in array.
/// @param _num number of matrices in array.
/// @returns index into matrix cache in case the same model matrix has to
/// be used for other draw primitive call.
uint32_t setTransform(const void* _mtx, uint16_t _num = 1);
/// Set model matrix from matrix cache for draw primitive.
///
/// @param _cache index in matrix cache.
/// @param _num number of matrices from cache.
void setTransform(uint32_t _cache, uint16_t _num = 1);
///
@ -575,7 +661,7 @@ namespace bgfx
void setIndexBuffer(DynamicIndexBufferHandle _handle);
///
void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices = UINT32_MAX);
void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices = UINT32_MAX);
///
void setVertexBuffer(VertexBufferHandle _handle, uint32_t _numVertices = UINT32_MAX);
@ -584,7 +670,7 @@ namespace bgfx
void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices = UINT32_MAX);
///
void setVertexBuffer(const TransientVertexBuffer* _vb, uint32_t _numVertices = UINT32_MAX);
void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices = UINT32_MAX);
///
void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num = UINT16_MAX);

View file

@ -5,6 +5,7 @@
all:
premake --file=premake/premake4.lua vs2008
premake --file=premake/premake4.lua vs2010
premake --file=premake/premake4.lua --gcc=nacl gmake
premake --file=premake/premake4.lua --gcc=mingw gmake
premake --file=premake/premake4.lua --gcc=linux gmake
@ -40,3 +41,7 @@ nacl-debug64:
nacl-release64:
make -C .build/projects/gmake-nacl config=release64
nacl: nacl-debug32 nacl-release32 nacl-debug64 nacl-release64
docs:
doxygen premake/bgfx.doxygen
upskirt readme.md > .build/docs/readme.html

1808
premake/bgfx.doxygen Normal file

File diff suppressed because it is too large Load diff

View file

@ -513,7 +513,7 @@ namespace bgfx
#elif BGFX_CONFIG_RENDERER_OPENGLES3
return RendererType::OpenGLES3;
#else
return RendererType::Null;
return RendererType::Count;
#endif // BGFX_CONFIG_RENDERER_
}
@ -927,9 +927,10 @@ namespace bgfx
return s_ctx.m_submit->checkAvailTransientIndexBuffer(_num);
}
const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num)
void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint16_t _num)
{
return s_ctx.allocTransientIndexBuffer(_num);
BX_CHECK(NULL != _tib, "_tib can't be NULL");
return s_ctx.allocTransientIndexBuffer(_tib, _num);
}
bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl)
@ -937,9 +938,10 @@ namespace bgfx
return s_ctx.m_submit->checkAvailTransientVertexBuffer(_num, _decl.m_stride);
}
const TransientVertexBuffer* allocTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl)
void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint16_t _num, const VertexDecl& _decl)
{
return s_ctx.allocTransientVertexBuffer(_num, _decl);
BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
return s_ctx.allocTransientVertexBuffer(_tvb, _num, _decl);
}
const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride)
@ -1177,6 +1179,11 @@ namespace bgfx
s_ctx.m_submit->setState(_state);
}
void setStencil(uint32_t _fstencil, uint32_t _bstencil)
{
s_ctx.m_submit->setStencil(_fstencil, _bstencil);
}
uint32_t setTransform(const void* _mtx, uint16_t _num)
{
return s_ctx.m_submit->setTransform(_mtx, _num);
@ -1217,10 +1224,11 @@ namespace bgfx
s_ctx.m_submit->setIndexBuffer(s_ctx.m_dynamicIndexBuffers[_handle.idx].m_handle, BGFX_DRAW_WHOLE_INDEX_BUFFER, 0);
}
void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices)
void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices)
{
uint32_t numIndices = uint32_min(_numIndices, _ib->size/2);
s_ctx.m_submit->setIndexBuffer(_ib, numIndices);
BX_CHECK(NULL != _tib, "_tib can't be NULL");
uint32_t numIndices = uint32_min(_numIndices, _tib->size/2);
s_ctx.m_submit->setIndexBuffer(_tib, numIndices);
}
void setVertexBuffer(VertexBufferHandle _handle, uint32_t _numVertices)
@ -1233,9 +1241,10 @@ namespace bgfx
s_ctx.m_submit->setVertexBuffer(s_ctx.m_dynamicVertexBuffers[_handle.idx], _numVertices);
}
void setVertexBuffer(const TransientVertexBuffer* _vb, uint32_t _numVertices)
void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices)
{
s_ctx.m_submit->setVertexBuffer(_vb, _numVertices);
BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
s_ctx.m_submit->setVertexBuffer(_tvb, _numVertices);
}
void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)

View file

@ -257,6 +257,16 @@ namespace bgfx
return un.ui;
}
inline uint64_t packStencil(uint32_t _fstencil, uint32_t _bstencil)
{
return (uint64_t(_bstencil)<<32)|uint64_t(_fstencil);
}
inline uint32_t unpackStencil(uint8_t _0or1, uint64_t _stencil)
{
return uint32_t( (_stencil >> (32*_0or1) ) );
}
void dump(const VertexDecl& _decl);
struct TextVideoMem
@ -911,6 +921,7 @@ namespace bgfx
{
m_constBegin = m_constEnd;
m_flags = BGFX_STATE_DEFAULT;
m_stencil = packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT);
m_matrix = 0;
m_startIndex = BGFX_DRAW_WHOLE_INDEX_BUFFER;
m_numIndices = 0;
@ -933,6 +944,7 @@ namespace bgfx
}
uint64_t m_flags;
uint64_t m_stencil;
uint32_t m_constBegin;
uint32_t m_constEnd;
uint32_t m_matrix;
@ -1086,6 +1098,11 @@ namespace bgfx
m_state.m_flags = _state;
}
void setStencil(uint32_t _fstencil, uint32_t _bstencil)
{
m_state.m_stencil = packStencil(_fstencil, _bstencil);
}
uint32_t setTransform(const void* _mtx, uint16_t _num)
{
m_state.m_matrix = m_matrixCache.add(_mtx, _num);
@ -1107,13 +1124,12 @@ namespace bgfx
m_state.m_indexBuffer = _handle;
}
void setIndexBuffer(const TransientIndexBuffer* _ib, uint32_t _numIndices)
void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices)
{
m_state.m_indexBuffer = _ib->handle;
m_state.m_startIndex = _ib->startIndex;
m_state.m_indexBuffer = _tib->handle;
m_state.m_startIndex = _tib->startIndex;
m_state.m_numIndices = _numIndices;
m_discard = 0 == _numIndices;
g_free(const_cast<TransientIndexBuffer*>(_ib) );
}
void setVertexBuffer(VertexBufferHandle _handle, uint32_t _numVertices)
@ -1124,33 +1140,29 @@ namespace bgfx
m_state.m_vertexBuffer = _handle;
}
void setVertexBuffer(const DynamicVertexBuffer& dvb, uint32_t _numVertices)
void setVertexBuffer(const DynamicVertexBuffer& _dvb, uint32_t _numVertices)
{
m_state.m_startVertex = dvb.m_startVertex;
m_state.m_numVertices = uint32_min(dvb.m_numVertices, _numVertices);
m_state.m_vertexBuffer = dvb.m_handle;
m_state.m_vertexDecl = dvb.m_decl;
m_state.m_startVertex = _dvb.m_startVertex;
m_state.m_numVertices = uint32_min(_dvb.m_numVertices, _numVertices);
m_state.m_vertexBuffer = _dvb.m_handle;
m_state.m_vertexDecl = _dvb.m_decl;
}
void setVertexBuffer(const TransientVertexBuffer* _vb, uint32_t _numVertices)
void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices)
{
m_state.m_startVertex = _vb->startVertex;
m_state.m_numVertices = uint32_min(_vb->size/_vb->stride, _numVertices);
m_state.m_vertexBuffer = _vb->handle;
m_state.m_vertexDecl = _vb->decl;
g_free(const_cast<TransientVertexBuffer*>(_vb) );
m_state.m_startVertex = _tvb->startVertex;
m_state.m_numVertices = uint32_min(_tvb->size/_tvb->stride, _numVertices);
m_state.m_vertexBuffer = _tvb->handle;
m_state.m_vertexDecl = _tvb->decl;
}
void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)
{
#if BGFX_CONFIG_RENDERER_OPENGLES2
#else
m_state.m_instanceDataOffset = _idb->offset;
m_state.m_instanceDataStride = _idb->stride;
m_state.m_numInstances = uint16_min(_idb->num, _num);
m_state.m_instanceDataBuffer = _idb->handle;
g_free(const_cast<InstanceDataBuffer*>(_idb) );
#endif // BGFX_CONFIG_RENDERER_OPENGLES
}
void setProgram(ProgramHandle _handle)
@ -1821,19 +1833,16 @@ namespace bgfx
g_free(const_cast<TransientIndexBuffer*>(_ib) );
}
const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num)
void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint16_t _num)
{
uint32_t offset = m_submit->allocTransientIndexBuffer(_num);
TransientIndexBuffer& dib = *m_submit->m_transientIb;
TransientIndexBuffer* ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer) );
ib->data = &dib.data[offset];
ib->size = _num * sizeof(uint16_t);
ib->handle = dib.handle;
ib->startIndex = offset/sizeof(uint16_t);
return ib;
_tib->data = &dib.data[offset];
_tib->size = _num * sizeof(uint16_t);
_tib->handle = dib.handle;
_tib->startIndex = offset/sizeof(uint16_t);
}
TransientVertexBuffer* createTransientVertexBuffer(uint32_t _size, const VertexDecl* _decl = NULL)
@ -1875,7 +1884,7 @@ namespace bgfx
g_free(const_cast<TransientVertexBuffer*>(_vb) );
}
const TransientVertexBuffer* allocTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl)
void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint16_t _num, const VertexDecl& _decl)
{
VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
@ -1893,22 +1902,16 @@ namespace bgfx
uint32_t offset = m_submit->allocTransientVertexBuffer(_num, _decl.m_stride);
TransientVertexBuffer* vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer) );
vb->data = &dvb.data[offset];
vb->size = _num * _decl.m_stride;
vb->startVertex = offset/_decl.m_stride;
vb->stride = _decl.m_stride;
vb->handle = dvb.handle;
vb->decl = declHandle;
return vb;
_tvb->data = &dvb.data[offset];
_tvb->size = _num * _decl.m_stride;
_tvb->startVertex = offset/_decl.m_stride;
_tvb->stride = _decl.m_stride;
_tvb->handle = dvb.handle;
_tvb->decl = declHandle;
}
const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride)
{
#if BGFX_CONFIG_RENDERER_OPENGLES2
return NULL;
#else
uint16_t stride = BX_ALIGN_16(_stride);
uint32_t offset = m_submit->allocTransientVertexBuffer(_num, stride);
@ -1922,7 +1925,6 @@ namespace bgfx
idb->handle = dvb.handle;
return idb;
#endif // BGFX_CONFIG_RENDERER_OPENGLES
}
VertexShaderHandle createVertexShader(const Memory* _mem)

View file

@ -39,6 +39,9 @@ GL_IMPORT(false, PFNGLCLEARSTENCILPROC, glClearStencil);
GL_IMPORT(false, PFNGLDEPTHMASKPROC, glDepthMask);
GL_IMPORT(false, PFNGLCLEARDEPTHPROC, glClearDepth);
GL_IMPORT(false, PFNGLCLEARCOLORPROC, glClearColor);
GL_IMPORT(false, PFNGLSTENCILFUNCPROC, glStencilFunc);
GL_IMPORT(false, PFNGLSTENCILMASKPROC, glStencilMask);
GL_IMPORT(false, PFNGLSTENCILOPPROC, glStencilOp);
#endif // BX_PLATFORM_WINDOWS
GL_IMPORT(false, PFNGLACTIVETEXTUREPROC, glActiveTexture);
@ -124,6 +127,10 @@ GL_IMPORT(true, PFNGLBINDVERTEXARRAYPROC, glBindVertexArray);
GL_IMPORT(true, PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays);
GL_IMPORT(true, PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays);
GL_IMPORT(true, PFNGLSTENCILFUNCSEPARATEPROC, glStencilFuncSeparate);
GL_IMPORT(true, PFNGLSTENCILMASKSEPARATEPROC, glStencilMaskSeparate);
GL_IMPORT(true, PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate);
#if BGFX_CONFIG_DEBUG_GREMEDY
GL_IMPORT(true, PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY);
GL_IMPORT(true, PFNGLFRAMETERMINATORGREMEDYPROC, glFrameTerminatorGREMEDY);

View file

@ -53,6 +53,31 @@ namespace bgfx
D3D11_COMPARISON_ALWAYS,
};
static const D3D11_COMPARISON_FUNC s_stencilFunc[] =
{
D3D11_COMPARISON_LESS, // ignored
D3D11_COMPARISON_LESS,
D3D11_COMPARISON_LESS_EQUAL,
D3D11_COMPARISON_EQUAL,
D3D11_COMPARISON_GREATER_EQUAL,
D3D11_COMPARISON_GREATER,
D3D11_COMPARISON_NOT_EQUAL,
D3D11_COMPARISON_NEVER,
D3D11_COMPARISON_ALWAYS,
};
static const D3D11_STENCIL_OP s_stencilOp[] =
{
D3D11_STENCIL_OP_ZERO,
D3D11_STENCIL_OP_KEEP,
D3D11_STENCIL_OP_REPLACE,
D3D11_STENCIL_OP_INCR,
D3D11_STENCIL_OP_INCR_SAT,
D3D11_STENCIL_OP_DECR,
D3D11_STENCIL_OP_DECR_SAT,
D3D11_STENCIL_OP_INVERT,
};
static const D3D11_CULL_MODE s_cullMode[] =
{
D3D11_CULL_NONE,
@ -571,11 +596,21 @@ namespace bgfx
m_deviceCtx->OMSetBlendState(bs, NULL, 0xffffffff);
}
void setDepthStencilState(uint64_t _state)
void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)
{
_state &= BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK;
ID3D11DepthStencilState* dss = m_depthStencilStateCache.find(_state);
uint32_t fstencil = unpackStencil(0, _stencil);
uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
_stencil &= packStencil(BGFX_STENCIL_FUNC_REF_MASK, BGFX_STENCIL_MASK);
HashMurmur2A murmur;
murmur.begin();
murmur.add(_state);
murmur.add(_stencil);
uint32_t hash = murmur.end();
ID3D11DepthStencilState* dss = m_depthStencilStateCache.find(hash);
if (NULL == dss)
{
D3D11_DEPTH_STENCIL_DESC desc;
@ -585,12 +620,28 @@ namespace bgfx
desc.DepthWriteMask = !!(BGFX_STATE_DEPTH_WRITE & _state) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = s_depthFunc[func];
uint32_t bstencil = unpackStencil(1, _stencil);
uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
bstencil = frontAndBack ? bstencil : fstencil;
desc.StencilEnable = 0 != _stencil;
desc.StencilReadMask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
desc.StencilWriteMask = 0xff;
desc.FrontFace.StencilFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
desc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
desc.FrontFace.StencilPassOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
desc.FrontFace.StencilFunc = s_stencilFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
desc.BackFace.StencilFailOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];
desc.BackFace.StencilDepthFailOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];
desc.BackFace.StencilPassOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];
desc.BackFace.StencilFunc = s_stencilFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];
DX_CHECK(m_device->CreateDepthStencilState(&desc, &dss) );
m_depthStencilStateCache.add(_state, dss);
}
m_deviceCtx->OMSetDepthStencilState(dss, 0);
m_deviceCtx->OMSetDepthStencilState(dss, ref);
}
void setDebugWireframe(bool _wireframe)
@ -1743,6 +1794,7 @@ namespace bgfx
RenderState currentState;
currentState.reset();
currentState.m_flags = BGFX_STATE_NONE;
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
@ -1780,11 +1832,17 @@ namespace bgfx
uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
currentState.m_flags = newFlags;
const uint64_t newStencil = state.m_stencil;
uint64_t changedStencil = currentState.m_stencil ^ state.m_stencil;
currentState.m_stencil = newStencil;
if (key.m_view != view)
{
currentState.clear();
changedFlags = BGFX_STATE_MASK;
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
currentState.m_flags = newFlags;
currentState.m_stencil = newStencil;
view = key.m_view;
programIdx = invalidHandle;
@ -1813,7 +1871,7 @@ namespace bgfx
}
s_renderCtx.setBlendState(BGFX_STATE_DEFAULT);
s_renderCtx.setDepthStencilState(BGFX_STATE_DEFAULT);
s_renderCtx.setDepthStencilState(BGFX_STATE_DEFAULT, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
s_renderCtx.setRasterizerState(BGFX_STATE_DEFAULT, wireframe);
uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
@ -1825,16 +1883,17 @@ namespace bgfx
}
}
if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
if ( (BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK) & changedFlags
|| 0 != changedStencil)
{
s_renderCtx.setDepthStencilState(newFlags, newStencil);
}
if ( (BGFX_STATE_CULL_MASK
|BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
|BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK
|BGFX_STATE_POINT_SIZE_MASK|BGFX_STATE_SRGBWRITE|BGFX_STATE_MSAA) & changedFlags)
{
if ( (BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK) & changedFlags)
{
s_renderCtx.setDepthStencilState(newFlags);
}
if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
{
s_renderCtx.setBlendState(newFlags);

View file

@ -71,6 +71,55 @@ namespace bgfx
D3DCMP_ALWAYS,
};
static const D3DCMPFUNC s_stencilFunc[] =
{
(D3DCMPFUNC)0, // ignored
D3DCMP_LESS,
D3DCMP_LESSEQUAL,
D3DCMP_EQUAL,
D3DCMP_GREATEREQUAL,
D3DCMP_GREATER,
D3DCMP_NOTEQUAL,
D3DCMP_NEVER,
D3DCMP_ALWAYS,
};
static const D3DSTENCILOP s_stencilOp[] =
{
D3DSTENCILOP_ZERO,
D3DSTENCILOP_KEEP,
D3DSTENCILOP_REPLACE,
D3DSTENCILOP_INCR,
D3DSTENCILOP_INCRSAT,
D3DSTENCILOP_DECR,
D3DSTENCILOP_DECRSAT,
D3DSTENCILOP_INVERT,
};
static const D3DRENDERSTATETYPE s_stencilFuncRs[] =
{
D3DRS_STENCILFUNC,
D3DRS_CCW_STENCILFUNC,
};
static const D3DRENDERSTATETYPE s_stencilFailRs[] =
{
D3DRS_STENCILFAIL,
D3DRS_CCW_STENCILFAIL,
};
static const D3DRENDERSTATETYPE s_stencilZFailRs[] =
{
D3DRS_STENCILZFAIL,
D3DRS_CCW_STENCILZFAIL,
};
static const D3DRENDERSTATETYPE s_stencilZPassRs[] =
{
D3DRS_STENCILPASS,
D3DRS_CCW_STENCILPASS,
};
static const D3DCULL s_cullMode[] =
{
D3DCULL_NONE,
@ -1363,19 +1412,20 @@ namespace bgfx
void Texture::commit(uint8_t _stage)
{
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) );
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) );
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) );
IDirect3DDevice9* device = s_renderCtx.m_device;
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_MINFILTER, m_minFilter) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_MAGFILTER, m_magFilter) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_MIPFILTER, m_mipFilter) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_ADDRESSU, m_tau) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_ADDRESSV, m_tav) );
if (m_type == Texture3D)
{
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_ADDRESSW, m_taw) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_ADDRESSW, m_taw) );
}
#if BX_PLATFORM_WINDOWS
DX_CHECK(s_renderCtx.m_device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) );
DX_CHECK(device->SetSamplerState(_stage, D3DSAMP_SRGBTEXTURE, m_srgb) );
#endif // BX_PLATFORM_WINDOWS
DX_CHECK(s_renderCtx.m_device->SetTexture(_stage, m_ptr) );
DX_CHECK(device->SetTexture(_stage, m_ptr) );
}
void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
@ -1624,27 +1674,29 @@ namespace bgfx
vp.Height = height;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
DX_CHECK(s_renderCtx.m_device->SetViewport(&vp) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZENABLE, FALSE) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) );
DX_CHECK(s_renderCtx.m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) );
IDirect3DDevice9* device = s_renderCtx.m_device;
DX_CHECK(device->SetViewport(&vp) );
DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) );
DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, FALSE) );
DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS) );
DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
DX_CHECK(device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) );
DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) );
Program& program = s_renderCtx.m_program[m_program.idx];
s_renderCtx.m_device->SetVertexShader( (IDirect3DVertexShader9*)program.m_vsh->m_ptr);
s_renderCtx.m_device->SetPixelShader( (IDirect3DPixelShader9*)program.m_fsh->m_ptr);
device->SetVertexShader( (IDirect3DVertexShader9*)program.m_vsh->m_ptr);
device->SetPixelShader( (IDirect3DPixelShader9*)program.m_fsh->m_ptr);
VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx];
VertexDeclaration& vertexDecl = s_renderCtx.m_vertexDecls[m_vb->decl.idx];
DX_CHECK(s_renderCtx.m_device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
DX_CHECK(s_renderCtx.m_device->SetVertexDeclaration(vertexDecl.m_ptr) );
DX_CHECK(device->SetStreamSource(0, vb.m_ptr, 0, vertexDecl.m_decl.m_stride) );
DX_CHECK(device->SetVertexDeclaration(vertexDecl.m_ptr) );
IndexBuffer& ib = s_renderCtx.m_indexBuffers[m_ib->handle.idx];
DX_CHECK(s_renderCtx.m_device->SetIndices(ib.m_ptr) );
DX_CHECK(device->SetIndices(ib.m_ptr) );
float proj[16];
mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
@ -1853,6 +1905,7 @@ namespace bgfx
RenderState currentState;
currentState.reset();
currentState.m_flags = BGFX_STATE_NONE;
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
@ -1887,11 +1940,17 @@ namespace bgfx
uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
currentState.m_flags = newFlags;
const uint64_t newStencil = state.m_stencil;
uint64_t changedStencil = currentState.m_stencil ^ state.m_stencil;
currentState.m_stencil = newStencil;
if (key.m_view != view)
{
currentState.clear();
changedFlags = BGFX_STATE_MASK;
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
currentState.m_flags = newFlags;
currentState.m_stencil = newStencil;
PIX_ENDEVENT();
PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), "view");
@ -1957,13 +2016,69 @@ namespace bgfx
}
}
DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, FALSE) );
DX_CHECK(device->SetRenderState(D3DRS_ZENABLE, TRUE) );
DX_CHECK(device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS) );
DX_CHECK(device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE) );
DX_CHECK(device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE) );
DX_CHECK(device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER) );
}
if (0 != changedStencil)
{
bool enable = 0 != newStencil;
DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, enable) );
if (0 != newStencil)
{
uint32_t fstencil = unpackStencil(0, newStencil);
uint32_t bstencil = unpackStencil(1, newStencil);
uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
DX_CHECK(device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, 0 != frontAndBack) );
uint32_t fchanged = unpackStencil(0, changedStencil);
if ( (BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK) & fchanged)
{
uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
DX_CHECK(device->SetRenderState(D3DRS_STENCILREF, ref) );
uint32_t rmask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
DX_CHECK(device->SetRenderState(D3DRS_STENCILMASK, rmask) );
}
// uint32_t bchanged = unpackStencil(1, changedStencil);
// if (BGFX_STENCIL_FUNC_RMASK_MASK & bchanged)
// {
// uint32_t wmask = (bstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
// DX_CHECK(device->SetRenderState(D3DRS_STENCILWRITEMASK, wmask) );
// }
for (uint32_t ii = 0, num = frontAndBack+1; ii < num; ++ii)
{
uint32_t stencil = unpackStencil(ii, newStencil);
uint32_t changed = unpackStencil(ii, changedStencil);
if ( (BGFX_STENCIL_TEST_MASK|BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK) & changed)
{
uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT;
DX_CHECK(device->SetRenderState(s_stencilFuncRs[ii], s_stencilFunc[func]) );
}
if ( (BGFX_STENCIL_OP_FAIL_S_MASK|BGFX_STENCIL_OP_FAIL_Z_MASK|BGFX_STENCIL_OP_PASS_Z_MASK) & changed)
{
uint32_t sfail = (stencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT;
DX_CHECK(device->SetRenderState(s_stencilFailRs[ii], s_stencilOp[sfail]) );
uint32_t zfail = (stencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT;
DX_CHECK(device->SetRenderState(s_stencilZFailRs[ii], s_stencilOp[zfail]) );
uint32_t zpass = (stencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT;
DX_CHECK(device->SetRenderState(s_stencilZPassRs[ii], s_stencilOp[zpass]) );
}
}
}
}
if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
|BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
|BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK

View file

@ -770,6 +770,38 @@ namespace bgfx
GL_ALWAYS,
};
static const GLenum s_stencilFunc[] =
{
0, // ignored
GL_LESS,
GL_LEQUAL,
GL_EQUAL,
GL_GEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_NEVER,
GL_ALWAYS,
};
static const GLenum s_stencilOp[] =
{
GL_ZERO,
GL_KEEP,
GL_REPLACE,
GL_INCR_WRAP,
GL_INCR,
GL_DECR_WRAP,
GL_DECR,
GL_INVERT,
};
static const GLenum s_stencilFace[] =
{
GL_FRONT_AND_BACK,
GL_FRONT,
GL_BACK,
};
// Specifies the internal format of the texture.
// Must be one of the following symbolic constants:
// GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA.
@ -1821,6 +1853,7 @@ namespace bgfx
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
GL_CHECK(glViewport(0, 0, width, height) );
GL_CHECK(glDisable(GL_STENCIL_TEST) );
GL_CHECK(glDisable(GL_DEPTH_TEST) );
GL_CHECK(glDepthFunc(GL_ALWAYS) );
GL_CHECK(glDisable(GL_CULL_FACE) );
@ -2164,6 +2197,7 @@ namespace bgfx
RenderState currentState;
currentState.reset();
currentState.m_flags = BGFX_STATE_NONE;
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
@ -2199,10 +2233,15 @@ namespace bgfx
uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
currentState.m_flags = newFlags;
const uint64_t newStencil = state.m_stencil;
uint64_t changedStencil = currentState.m_stencil ^ state.m_stencil;
currentState.m_stencil = newStencil;
if (key.m_view != view)
{
currentState.clear();
changedFlags = BGFX_STATE_MASK;
changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);
currentState.m_flags = newFlags;
GREMEDY_SETMARKER("view");
@ -2270,12 +2309,58 @@ namespace bgfx
}
}
GL_CHECK(glDisable(GL_STENCIL_TEST) );
GL_CHECK(glEnable(GL_DEPTH_TEST) );
GL_CHECK(glDepthFunc(GL_LESS) );
GL_CHECK(glEnable(GL_CULL_FACE) );
GL_CHECK(glDisable(GL_BLEND) );
}
if (0 != changedStencil)
{
if (0 != newStencil)
{
GL_CHECK(glEnable(GL_STENCIL_TEST) );
uint32_t bstencil = unpackStencil(1, newStencil);
uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != unpackStencil(0, newStencil);
// uint32_t bchanged = unpackStencil(1, changedStencil);
// if (BGFX_STENCIL_FUNC_RMASK_MASK & bchanged)
// {
// uint32_t wmask = (bstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
// BX_CHECK(glStencilMask(wmask) );
// }
for (uint32_t ii = 0, num = frontAndBack+1; ii < num; ++ii)
{
uint32_t stencil = unpackStencil(ii, newStencil);
uint32_t changed = unpackStencil(ii, changedStencil);
GLenum face = s_stencilFace[frontAndBack+ii];
if ( (BGFX_STENCIL_TEST_MASK|BGFX_STENCIL_FUNC_REF_MASK|BGFX_STENCIL_FUNC_RMASK_MASK) & changed)
{
GLint ref = (stencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
GLint mask = (stencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
uint32_t func = (stencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT;
GL_CHECK(glStencilFuncSeparate(face, s_stencilFunc[func], ref, mask));
}
if ( (BGFX_STENCIL_OP_FAIL_S_MASK|BGFX_STENCIL_OP_FAIL_Z_MASK|BGFX_STENCIL_OP_PASS_Z_MASK) & changed)
{
uint32_t sfail = (stencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT;
uint32_t zfail = (stencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT;
uint32_t zpass = (stencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT;
GL_CHECK(glStencilOpSeparate(face, s_stencilOp[sfail], s_stencilOp[zfail], s_stencilOp[zpass]) );
}
}
}
else
{
GL_CHECK(glDisable(GL_STENCIL_TEST) );
}
}
if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
|BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
|BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK

View file

@ -172,6 +172,9 @@ typedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
typedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
typedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth);
typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
typedef void (APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
#endif // BGFX_USE_WGL
#ifndef GL_APIENTRY