mirror of https://github.com/bkaradzic/bgfx
Added 07-callback example.
This commit is contained in:
parent
ff41632999
commit
d4cd0ea4fa
|
@ -131,6 +131,10 @@ Loading textures.
|
|||
|
||||
![example-06-bump](https://github.com/bkaradzic/bgfx/raw/master/examples/06-bump/screenshot.png)
|
||||
|
||||
### 07-callback
|
||||
Implementing application specific callbacks for taking screen shots, caching
|
||||
OpenGL binary shaders, and video capture.
|
||||
|
||||
Internals
|
||||
---------
|
||||
|
||||
|
|
|
@ -7,14 +7,9 @@
|
|||
#include <bx/bx.h>
|
||||
#include "../common/dbg.h"
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
struct PosColorVertex
|
||||
{
|
||||
float m_x;
|
||||
|
@ -99,7 +94,7 @@ static const bgfx::Memory* loadShader(const char* _name)
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
|
||||
bgfx::VertexDecl s_PosNormalColorDecl;
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
struct PosNormalColorVertex
|
||||
{
|
||||
float m_pos[3];
|
||||
|
@ -499,7 +494,7 @@ uint32_t triangulate(uint8_t* _result, uint32_t _stride, const float* __restrict
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
struct PosColorTexCoord0Vertex
|
||||
{
|
||||
float m_x;
|
||||
|
@ -178,7 +173,7 @@ void renderScreenSpaceQuad(uint32_t _view, bgfx::ProgramHandle _program, float _
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
static const char* s_shaderPath = NULL;
|
||||
static bool s_flipV = false;
|
||||
|
||||
|
@ -279,7 +274,7 @@ struct Mesh
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
struct PosColorVertex
|
||||
{
|
||||
float m_x;
|
||||
|
@ -99,7 +94,7 @@ static const bgfx::Memory* loadShader(const char* _name)
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -13,11 +13,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
|
||||
{
|
||||
DBG("%x: %s", _code, _str);
|
||||
}
|
||||
|
||||
struct PosNormalTangentTexcoordVertex
|
||||
{
|
||||
float m_x;
|
||||
|
@ -255,7 +250,7 @@ void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices,
|
|||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
bgfx::init(fatalCb);
|
||||
bgfx::init();
|
||||
bgfx::reset(1280, 720);
|
||||
|
||||
// Enable debug text.
|
||||
|
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <bgfx.h>
|
||||
#include <bx/bx.h>
|
||||
#include <bx/timer.h>
|
||||
#include <bx/readerwriter.h>
|
||||
#include <bx/string.h>
|
||||
#include "../common/dbg.h"
|
||||
#include "../common/math.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct PosColorVertex
|
||||
{
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
uint32_t m_abgr;
|
||||
};
|
||||
|
||||
static bgfx::VertexDecl s_PosColorDecl;
|
||||
|
||||
static PosColorVertex s_cubeVertices[8] =
|
||||
{
|
||||
{-1.0f, 1.0f, 1.0f, 0xff000000 },
|
||||
{ 1.0f, 1.0f, 1.0f, 0xff0000ff },
|
||||
{-1.0f, -1.0f, 1.0f, 0xff00ff00 },
|
||||
{ 1.0f, -1.0f, 1.0f, 0xff00ffff },
|
||||
{-1.0f, 1.0f, -1.0f, 0xffff0000 },
|
||||
{ 1.0f, 1.0f, -1.0f, 0xffff00ff },
|
||||
{-1.0f, -1.0f, -1.0f, 0xffffff00 },
|
||||
{ 1.0f, -1.0f, -1.0f, 0xffffffff },
|
||||
};
|
||||
|
||||
static const uint16_t s_cubeIndices[36] =
|
||||
{
|
||||
0, 2, 1, // 0
|
||||
1, 2, 3,
|
||||
4, 5, 6, // 2
|
||||
5, 7, 6,
|
||||
0, 4, 2, // 4
|
||||
4, 6, 2,
|
||||
1, 3, 5, // 6
|
||||
5, 3, 7,
|
||||
0, 1, 4, // 8
|
||||
4, 1, 5,
|
||||
2, 6, 3, // 10
|
||||
6, 7, 3,
|
||||
};
|
||||
|
||||
static const char* s_shaderPath = NULL;
|
||||
|
||||
static void shaderFilePath(char* _out, const char* _name)
|
||||
{
|
||||
strcpy(_out, s_shaderPath);
|
||||
strcat(_out, _name);
|
||||
strcat(_out, ".bin");
|
||||
}
|
||||
|
||||
long int fsize(FILE* _file)
|
||||
{
|
||||
long int pos = ftell(_file);
|
||||
fseek(_file, 0L, SEEK_END);
|
||||
long int size = ftell(_file);
|
||||
fseek(_file, pos, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
static const bgfx::Memory* load(const char* _filePath)
|
||||
{
|
||||
FILE* file = fopen(_filePath, "rb");
|
||||
if (NULL != file)
|
||||
{
|
||||
uint32_t size = (uint32_t)fsize(file);
|
||||
const bgfx::Memory* mem = bgfx::alloc(size+1);
|
||||
size_t ignore = fread(mem->data, 1, size, file);
|
||||
BX_UNUSED(ignore);
|
||||
fclose(file);
|
||||
mem->data[mem->size-1] = '\0';
|
||||
return mem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const bgfx::Memory* loadShader(const char* _name)
|
||||
{
|
||||
char filePath[512];
|
||||
shaderFilePath(filePath, _name);
|
||||
return load(filePath);
|
||||
}
|
||||
|
||||
void saveTga(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip)
|
||||
{
|
||||
FILE* file = fopen(_filePath, "wb");
|
||||
if ( NULL != file )
|
||||
{
|
||||
uint8_t type = _grayscale ? 3 : 2;
|
||||
uint8_t bpp = _grayscale ? 8 : 32;
|
||||
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(type, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(0, file);
|
||||
putc(_width&0xff, file);
|
||||
putc( (_width>>8)&0xff, file);
|
||||
putc(_height&0xff, file);
|
||||
putc( (_height>>8)&0xff, file);
|
||||
putc(bpp, file);
|
||||
putc(32, file);
|
||||
|
||||
uint32_t dstPitch = _width*bpp/8;
|
||||
if (_yflip)
|
||||
{
|
||||
uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
|
||||
for (uint32_t yy = 0; yy < _height; ++yy)
|
||||
{
|
||||
fwrite(data, dstPitch, 1, file);
|
||||
data -= _srcPitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* data = (uint8_t*)_src;
|
||||
for (uint32_t yy = 0; yy < _height; ++yy)
|
||||
{
|
||||
fwrite(data, dstPitch, 1, file);
|
||||
data += _srcPitch;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
// Simple AVI writer. VideoLAN and VirtualDub can decode it.
|
||||
// Needs some bits to get jiggled to work with other players. But it's good
|
||||
// enough for an example.
|
||||
struct AviWriter
|
||||
{
|
||||
AviWriter()
|
||||
: m_frame(NULL)
|
||||
, m_frameSize(0)
|
||||
, m_width(0)
|
||||
, m_height(0)
|
||||
, m_yflip(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool open(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _fps, bool _yflip)
|
||||
{
|
||||
if (0 != m_writer.open(_filePath) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_frameSize = _width * _height * 3;
|
||||
m_frame = new uint8_t[m_frameSize + 8];
|
||||
m_width = _width;
|
||||
m_height = _height;
|
||||
|
||||
// Bgfx returns _yflip true for OpenGL since bottom left corner is 0, 0. In D3D top left corner
|
||||
// is 0, 0. DIB expect OpenGL style coordinates, so this is inverted logic for AVI writer.
|
||||
m_yflip = !_yflip;
|
||||
|
||||
bx::StaticMemoryBlockWriter mem(m_frame, 8);
|
||||
// Stream Data (LIST 'movi' Chunk) http://msdn.microsoft.com/en-us/library/ms899496.aspx
|
||||
bx::write(&mem, BX_MAKEFOURCC('0', '0', 'd', 'b') );
|
||||
bx::write(&mem, m_frameSize);
|
||||
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('R', 'I', 'F', 'F') );
|
||||
bx::write(&m_writer, UINT32_C(0) );
|
||||
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('A', 'V', 'I', ' ') );
|
||||
|
||||
// AVI RIFF Form http://msdn.microsoft.com/en-us/library/ms899422.aspx
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
|
||||
bx::write(&m_writer, UINT32_C(196) );
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('h', 'd', 'r', 'l') );
|
||||
|
||||
// AVI Main Header http://msdn.microsoft.com/en-us/library/ms779632.aspx
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('a', 'v', 'i', 'h') );
|
||||
bx::write(&m_writer, UINT32_C(56) );
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwMicroSecPerFrame
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwMaxBytesPerSec
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwPaddingGranularity
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwFlags
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwTotalFrames
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwInitialFrames
|
||||
bx::write(&m_writer, UINT32_C(1) ); // dwStreams
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwSuggestedBufferSize
|
||||
bx::write(&m_writer, _width); // dwWidth
|
||||
bx::write(&m_writer, _height); // dwHeight
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwReserved0
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwReserved1
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwReserved2
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwReserved3
|
||||
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
|
||||
bx::write(&m_writer, UINT32_C(120) );
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('s', 't', 'r', 'l') );
|
||||
|
||||
// AVISTREAMHEADER Structure http://msdn.microsoft.com/en-us/library/ms779638.aspx
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('s', 't', 'r', 'h') );
|
||||
bx::write(&m_writer, UINT32_C(56) );
|
||||
// AVI Stream Headers http://msdn.microsoft.com/en-us/library/ms899423.aspx
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('v', 'i', 'd', 's') ); // fccType
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('D', 'I', 'B', ' ') ); // fccHandler
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwFlags
|
||||
bx::write(&m_writer, UINT16_C(0) ); // wPriority
|
||||
bx::write(&m_writer, UINT16_C(0) ); // wLanguage
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwInitialFrames
|
||||
bx::write(&m_writer, UINT32_C(1000) ); // dwScale
|
||||
bx::write(&m_writer, 1000*_fps); // dwRate
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwStart
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwLength
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwSuggestedBufferSize
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwQuality
|
||||
bx::write(&m_writer, UINT32_C(0) ); // dwSampleSize
|
||||
bx::write(&m_writer, INT16_C(0) ); // rcFrame.left
|
||||
bx::write(&m_writer, INT16_C(0) ); // rcFrame.top
|
||||
bx::write(&m_writer, INT16_C(0) ); // rcFrame.right
|
||||
bx::write(&m_writer, INT16_C(0) ); // rcFrame.bottom
|
||||
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('s', 't', 'r', 'f') );
|
||||
bx::write(&m_writer, UINT32_C(44) );
|
||||
|
||||
// BITMAPINFOHEADER structure http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229%28v=vs.85%29.aspx
|
||||
bx::write(&m_writer, UINT32_C(40) ); // biSize
|
||||
bx::write(&m_writer, _width); // biWidth
|
||||
bx::write(&m_writer, _height); // biHeight
|
||||
bx::write(&m_writer, UINT16_C(1) ); // biPlanes
|
||||
bx::write(&m_writer, UINT16_C(24) ); // biBitCount
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biCompression
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biSizeImage
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biXPelsPerMeter
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biYPelsPerMeter
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biClrUsed
|
||||
bx::write(&m_writer, UINT32_C(0) ); // biClrImportant
|
||||
bx::write(&m_writer, UINT32_C(0) );
|
||||
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('L', 'I', 'S', 'T') );
|
||||
bx::write(&m_writer, UINT32_C(0) );
|
||||
bx::write(&m_writer, BX_MAKEFOURCC('m', 'o', 'v', 'i') );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if (NULL != m_frame)
|
||||
{
|
||||
m_writer.close();
|
||||
|
||||
delete [] m_frame;
|
||||
m_frame = NULL;
|
||||
m_frameSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void frame(const void* _data)
|
||||
{
|
||||
if (NULL != m_frame)
|
||||
{
|
||||
uint32_t width = m_width;
|
||||
uint32_t height = m_height;
|
||||
|
||||
uint8_t* bgr = &m_frame[8];
|
||||
|
||||
if (m_yflip)
|
||||
{
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
const uint8_t* bgra = (const uint8_t*)_data + (height-1-yy)*width*4;
|
||||
|
||||
for (uint32_t ii = 0; ii < width; ++ii)
|
||||
{
|
||||
bgr[0] = bgra[0];
|
||||
bgr[1] = bgra[1];
|
||||
bgr[2] = bgra[2];
|
||||
bgr += 3;
|
||||
bgra += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t* bgra = (const uint8_t*)_data;
|
||||
for (uint32_t ii = 0, num = m_frameSize/3; ii < num; ++ii)
|
||||
{
|
||||
bgr[0] = bgra[0];
|
||||
bgr[1] = bgra[1];
|
||||
bgr[2] = bgra[2];
|
||||
bgr += 3;
|
||||
bgra += 4;
|
||||
}
|
||||
}
|
||||
|
||||
bx::write(&m_writer, m_frame, m_frameSize+8);
|
||||
}
|
||||
}
|
||||
|
||||
bx::CrtFileWriter m_writer;
|
||||
uint8_t* m_frame;
|
||||
uint32_t m_frameSize;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
bool m_yflip;
|
||||
};
|
||||
|
||||
struct BgfxCallback : public bgfx::CallbackI
|
||||
{
|
||||
virtual ~BgfxCallback()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void fatal(bgfx::Fatal::Enum _code, const char* _str) BX_OVERRIDE
|
||||
{
|
||||
dbgPrintf("Fatal error: 0x%08x: %s", _code, _str);
|
||||
abort();
|
||||
}
|
||||
|
||||
virtual uint32_t cacheReadSize(uint64_t _id) BX_OVERRIDE
|
||||
{
|
||||
char filePath[256];
|
||||
bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id);
|
||||
FILE* file = fopen(filePath, "rb");
|
||||
if (NULL != file)
|
||||
{
|
||||
uint32_t size = fsize(file);
|
||||
fclose(file);
|
||||
return size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) BX_OVERRIDE
|
||||
{
|
||||
char filePath[256];
|
||||
bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id);
|
||||
FILE* file = fopen(filePath, "rb");
|
||||
if (NULL != file)
|
||||
{
|
||||
size_t result = fread(_data, 1, _size, file);
|
||||
fclose(file);
|
||||
return result == _size;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) BX_OVERRIDE
|
||||
{
|
||||
char filePath[256];
|
||||
bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id);
|
||||
|
||||
FILE* file = fopen(filePath, "wb");
|
||||
if (NULL != file)
|
||||
{
|
||||
fwrite(_data, 1, _size, file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) BX_OVERRIDE
|
||||
{
|
||||
saveTga(_filePath, _width, _height, _pitch, _data, false, _yflip);
|
||||
}
|
||||
|
||||
virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx::TextureFormat::Enum /*_format*/, bool _yflip) BX_OVERRIDE
|
||||
{
|
||||
m_writer = new AviWriter;
|
||||
if (!m_writer->open("capture.avi", _width, _height, 60, _yflip) )
|
||||
{
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void captureEnd() BX_OVERRIDE
|
||||
{
|
||||
if (NULL != m_writer)
|
||||
{
|
||||
m_writer->close();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void captureFrame(const void* _data, uint32_t /*_size*/) BX_OVERRIDE
|
||||
{
|
||||
if (NULL != m_writer)
|
||||
{
|
||||
m_writer->frame(_data);
|
||||
}
|
||||
}
|
||||
|
||||
AviWriter* m_writer;
|
||||
};
|
||||
|
||||
int _main_(int _argc, char** _argv)
|
||||
{
|
||||
BgfxCallback callback;
|
||||
|
||||
bgfx::init(&callback);
|
||||
bgfx::reset(1280, 720, BGFX_RESET_CAPTURE);
|
||||
|
||||
// Enable debug text.
|
||||
bgfx::setDebug(BGFX_DEBUG_TEXT);
|
||||
|
||||
// Set view 0 default viewport.
|
||||
bgfx::setViewRect(0, 0, 0, 1280, 720);
|
||||
|
||||
// Set view 0 clear state.
|
||||
bgfx::setViewClear(0
|
||||
, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
|
||||
, 0x303030ff
|
||||
, 1.0f
|
||||
, 0
|
||||
);
|
||||
|
||||
// Setup root path for binary shaders. Shader binaries are different
|
||||
// for each renderer.
|
||||
switch (bgfx::getRendererType() )
|
||||
{
|
||||
default:
|
||||
case bgfx::RendererType::Direct3D9:
|
||||
s_shaderPath = "shaders/dx9/";
|
||||
break;
|
||||
|
||||
case bgfx::RendererType::Direct3D11:
|
||||
s_shaderPath = "shaders/dx11/";
|
||||
break;
|
||||
|
||||
case bgfx::RendererType::OpenGL:
|
||||
s_shaderPath = "shaders/glsl/";
|
||||
break;
|
||||
|
||||
case bgfx::RendererType::OpenGLES2:
|
||||
case bgfx::RendererType::OpenGLES3:
|
||||
s_shaderPath = "shaders/gles/";
|
||||
break;
|
||||
}
|
||||
|
||||
// Create vertex stream declaration.
|
||||
s_PosColorDecl.begin();
|
||||
s_PosColorDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
|
||||
s_PosColorDecl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
|
||||
s_PosColorDecl.end();
|
||||
|
||||
const bgfx::Memory* mem;
|
||||
|
||||
// Create static vertex buffer.
|
||||
mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) );
|
||||
bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosColorDecl);
|
||||
|
||||
// Create static index buffer.
|
||||
mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) );
|
||||
bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem);
|
||||
|
||||
// Load vertex shader.
|
||||
mem = loadShader("vs_callback");
|
||||
bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
|
||||
|
||||
// Load fragment shader.
|
||||
mem = loadShader("fs_callback");
|
||||
bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
|
||||
|
||||
// Create program from shaders.
|
||||
bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh);
|
||||
|
||||
// We can destroy vertex and fragment shader here since
|
||||
// their reference is kept inside bgfx after calling createProgram.
|
||||
// Vertex and fragment shader will be destroyed once program is
|
||||
// destroyed.
|
||||
bgfx::destroyVertexShader(vsh);
|
||||
bgfx::destroyFragmentShader(fsh);
|
||||
|
||||
float time = 0.0f;
|
||||
|
||||
// 5 second 60Hz video
|
||||
for (uint32_t frame = 0; frame < 300; ++frame)
|
||||
{
|
||||
// This dummy draw call is here to make sure that view 0 is cleared
|
||||
// if no other draw calls are submitted to view 0.
|
||||
bgfx::submit(0);
|
||||
|
||||
int64_t now = bx::getHPCounter();
|
||||
static int64_t last = now;
|
||||
const int64_t frameTime = now - last;
|
||||
last = now;
|
||||
const double freq = double(bx::getHPFrequency() );
|
||||
const double toMs = 1000.0/freq;
|
||||
|
||||
// Use debug font to print information about this example.
|
||||
bgfx::dbgTextClear();
|
||||
bgfx::dbgTextPrintf( 0, 1, 0x4f, "bgfx/examples/07-callback");
|
||||
bgfx::dbgTextPrintf( 0, 2, 0x6f, "Description: Implementing application specific callbacks for taking screen shots,");
|
||||
bgfx::dbgTextPrintf(13, 3, 0x6f, "caching OpenGL binary shaders, and video capture.");
|
||||
bgfx::dbgTextPrintf( 0, 4, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
|
||||
|
||||
float at[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float eye[3] = { 0.0f, 0.0f, -35.0f };
|
||||
|
||||
float view[16];
|
||||
float proj[16];
|
||||
mtxLookAt(view, eye, at);
|
||||
mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f);
|
||||
|
||||
// Set view and projection matrix for view 0.
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
|
||||
time += 1.0f/60.0f;
|
||||
|
||||
// Submit 11x11 cubes.
|
||||
for (uint32_t yy = 0; yy < 11; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < 11-yy; ++xx)
|
||||
{
|
||||
float mtx[16];
|
||||
mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f);
|
||||
mtx[12] = -15.0f + float(xx)*3.0f;
|
||||
mtx[13] = -15.0f + float(yy)*3.0f;
|
||||
mtx[14] = 0.0f;
|
||||
|
||||
// Set model matrix for rendering.
|
||||
bgfx::setTransform(mtx);
|
||||
|
||||
// Set vertex and fragment shaders.
|
||||
bgfx::setProgram(program);
|
||||
|
||||
// Set vertex and index buffer.
|
||||
bgfx::setVertexBuffer(vbh);
|
||||
bgfx::setIndexBuffer(ibh);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Take screenshot at frame 150.
|
||||
if (150 == frame)
|
||||
{
|
||||
bgfx::saveScreenShot("frame150.tga");
|
||||
}
|
||||
|
||||
// Advance to next frame. Rendering thread will be kicked to
|
||||
// process submitted rendering primitives.
|
||||
bgfx::frame();
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
bgfx::destroyIndexBuffer(ibh);
|
||||
bgfx::destroyVertexBuffer(vbh);
|
||||
bgfx::destroyProgram(program);
|
||||
|
||||
// Shutdown bgfx.
|
||||
bgfx::shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
$input v_world, v_color0
|
||||
|
||||
/*
|
||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "../common/common.sh"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = normalize(cross(dFdx(v_world), dFdy(v_world) ) );
|
||||
vec3 lightDir = vec3(0.0, 0.0, 1.0);
|
||||
float ndotl = max(dot(normal, lightDir), 0.0);
|
||||
float spec = pow(ndotl, 30.0);
|
||||
gl_FragColor = pow(pow(v_color0, vec4_splat(2.2) ) * ndotl + spec, vec4_splat(1.0/2.2) );
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
# License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
#
|
||||
|
||||
BGFX_DIR=../..
|
||||
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
|
||||
BUILD_DIR=../../.build
|
||||
|
||||
include $(BGFX_DIR)/premake/shader.mk
|
||||
|
||||
rebuild:
|
||||
@make -s --no-print-directory TARGET=0 clean all
|
||||
@make -s --no-print-directory TARGET=1 clean all
|
||||
@make -s --no-print-directory TARGET=2 clean all
|
||||
@make -s --no-print-directory TARGET=3 clean all
|
||||
@make -s --no-print-directory TARGET=4 clean all
|
|
@ -0,0 +1,5 @@
|
|||
vec3 v_world : TEXCOORD0 = vec3(0.0, 0.0, 0.0);
|
||||
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
vec3 a_position : POSITION;
|
||||
vec4 a_color0 : COLOR0;
|
|
@ -0,0 +1,16 @@
|
|||
$input a_position, a_color0
|
||||
$output v_world, v_color0
|
||||
|
||||
/*
|
||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "../common/common.sh"
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
|
||||
v_world = mul(u_model, vec4(a_position, 1.0) ).xyz;
|
||||
v_color0 = a_color0;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -220,6 +220,7 @@
|
|||
#define BGFX_RESET_MSAA_SHIFT 4
|
||||
#define BGFX_RESET_MSAA_MASK UINT32_C(0x00000070)
|
||||
#define BGFX_RESET_VSYNC UINT32_C(0x00000080)
|
||||
#define BGFX_RESET_CAPTURE UINT32_C(0x00000100)
|
||||
|
||||
///
|
||||
#define BGFX_HANDLE(_name) struct _name { uint16_t idx; }
|
||||
|
@ -301,9 +302,9 @@ namespace bgfx
|
|||
Dxt5,
|
||||
Unknown,
|
||||
L8,
|
||||
XRGB8,
|
||||
ARGB8,
|
||||
ABGR16,
|
||||
BGRX8,
|
||||
BGRA8,
|
||||
RGBA16,
|
||||
R5G6B5,
|
||||
RGBA4,
|
||||
RGB5A1,
|
||||
|
@ -347,10 +348,47 @@ namespace bgfx
|
|||
BGFX_HANDLE(VertexDeclHandle);
|
||||
BGFX_HANDLE(VertexShaderHandle);
|
||||
|
||||
typedef void (*FatalFn)(Fatal::Enum _code, const char* _str);
|
||||
typedef void* (*ReallocFn)(void* _ptr, size_t _size);
|
||||
typedef void (*FreeFn)(void* _ptr);
|
||||
typedef void (*CacheFn)(uint64_t _id, bool _store, void* _data, uint32_t& _length);
|
||||
|
||||
/// Callback interface to implement application specific behavior.
|
||||
/// Cached items are currently used only when for OpenGL binary shaders.
|
||||
///
|
||||
/// NOTE: Callback functions can be called from any thread.
|
||||
struct CallbackI
|
||||
{
|
||||
virtual ~CallbackI() = 0;
|
||||
|
||||
/// Called on unrecoverable error. It's not safe to continue, inform
|
||||
/// user and terminate application from this call.
|
||||
virtual void fatal(Fatal::Enum _code, const char* _str) = 0;
|
||||
|
||||
/// Return size of for cached item. Return 0 if no cached item was
|
||||
/// found.
|
||||
virtual uint32_t cacheReadSize(uint64_t _id) = 0;
|
||||
|
||||
/// Read cached item.
|
||||
virtual bool cacheRead(uint64_t _id, void* _data, uint32_t _size) = 0;
|
||||
|
||||
/// Write cached item.
|
||||
virtual void cacheWrite(uint64_t _id, const void* _data, uint32_t _size) = 0;
|
||||
|
||||
/// Screenshot captured. Screenshot format is always 4-byte BGRA.
|
||||
virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t _size, bool _yflip) = 0;
|
||||
|
||||
/// Called when capture begins.
|
||||
virtual void captureBegin(uint32_t _width, uint32_t _height, uint32_t _pitch, bgfx::TextureFormat::Enum _format, bool _yflip) = 0;
|
||||
|
||||
/// Called when capture ends.
|
||||
virtual void captureEnd() = 0;
|
||||
|
||||
/// Captured frame.
|
||||
virtual void captureFrame(const void* _data, uint32_t _size) = 0;
|
||||
};
|
||||
|
||||
inline CallbackI::~CallbackI()
|
||||
{
|
||||
}
|
||||
|
||||
struct Memory
|
||||
{
|
||||
|
@ -394,6 +432,7 @@ namespace bgfx
|
|||
uint16_t depth;
|
||||
};
|
||||
|
||||
/// Vertex declaration.
|
||||
struct VertexDecl
|
||||
{
|
||||
/// Start VertexDecl.
|
||||
|
@ -430,7 +469,7 @@ namespace bgfx
|
|||
RendererType::Enum getRendererType();
|
||||
|
||||
/// Initialize bgfx library.
|
||||
void init(FatalFn _fatal = NULL, ReallocFn _realloc = NULL, FreeFn _free = NULL, CacheFn _cache = NULL);
|
||||
void init(CallbackI* _callback = NULL, ReallocFn _realloc = NULL, FreeFn _free = NULL);
|
||||
|
||||
/// Shutdown bgfx library.
|
||||
void shutdown();
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
project "example-07-callback"
|
||||
uuid "acc53bbc-52f0-11e2-9781-ad8edd4b7d02"
|
||||
kind "WindowedApp"
|
||||
|
||||
debugdir (BGFX_DIR .. "examples/runtime/")
|
||||
|
||||
includedirs {
|
||||
BX_DIR .. "include",
|
||||
BGFX_DIR .. "include",
|
||||
}
|
||||
|
||||
files {
|
||||
BGFX_DIR .. "examples/common/**.cpp",
|
||||
BGFX_DIR .. "examples/common/**.h",
|
||||
BGFX_DIR .. "examples/07-callback/**.cpp",
|
||||
BGFX_DIR .. "examples/07-callback/**.h",
|
||||
}
|
||||
|
||||
links {
|
||||
"bgfx",
|
||||
}
|
||||
|
||||
configuration { "nacl" }
|
||||
targetextension ".nexe"
|
||||
|
||||
configuration { "nacl", "Release" }
|
||||
postbuildcommands {
|
||||
"@echo Stripping symbols.",
|
||||
"@$(NACL)/bin/x86_64-nacl-strip -s \"$(TARGET)\""
|
||||
}
|
||||
|
||||
configuration { "linux" }
|
||||
links {
|
||||
"GL",
|
||||
"pthread",
|
||||
}
|
|
@ -40,3 +40,4 @@ dofile "example-03-raymarch.lua"
|
|||
dofile "example-04-mesh.lua"
|
||||
dofile "example-05-instancing.lua"
|
||||
dofile "example-06-bump.lua"
|
||||
dofile "example-07-callback.lua"
|
||||
|
|
82
src/bgfx.cpp
82
src/bgfx.cpp
|
@ -37,14 +37,56 @@ namespace bgfx
|
|||
# define BGFX_CHECK_RENDER_THREAD()
|
||||
#endif // BGFX_CONFIG_MULTITHREADED
|
||||
|
||||
void fatalStub(Fatal::Enum _code, const char* _str)
|
||||
struct CallbackStub : public CallbackI
|
||||
{
|
||||
BX_TRACE("0x%08x: %s", _code, _str);
|
||||
BX_UNUSED(_code);
|
||||
BX_UNUSED(_str);
|
||||
}
|
||||
virtual ~CallbackStub()
|
||||
{
|
||||
}
|
||||
|
||||
void* reallocStub(void* _ptr, size_t _size)
|
||||
virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
|
||||
{
|
||||
BX_TRACE("0x%08x: %s", _code, _str);
|
||||
BX_UNUSED(_code);
|
||||
BX_UNUSED(_str);
|
||||
abort();
|
||||
}
|
||||
|
||||
virtual uint32_t cacheReadSize(uint64_t /*_id*/) BX_OVERRIDE
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool cacheRead(uint64_t /*_id*/, void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void cacheWrite(uint64_t /*_id*/, const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) BX_OVERRIDE
|
||||
{
|
||||
saveTga(_filePath, _width, _height, _pitch, _data, false, _yflip);
|
||||
}
|
||||
|
||||
virtual void captureBegin(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t /*_pitch*/, bgfx::TextureFormat::Enum /*_format*/, bool /*_yflip*/) BX_OVERRIDE
|
||||
{
|
||||
BX_TRACE("Warning: using capture without callback (a.k.a. pointless).");
|
||||
}
|
||||
|
||||
virtual void captureEnd() BX_OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
virtual void captureFrame(const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static CallbackStub s_callbackStub;
|
||||
|
||||
static void* reallocStub(void* _ptr, size_t _size)
|
||||
{
|
||||
void* ptr = ::realloc(_ptr, _size);
|
||||
BX_CHECK(NULL != ptr, "Out of memory!");
|
||||
|
@ -52,21 +94,15 @@ namespace bgfx
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void freeStub(void* _ptr)
|
||||
static void freeStub(void* _ptr)
|
||||
{
|
||||
// BX_TRACE("free %p", _ptr);
|
||||
::free(_ptr);
|
||||
}
|
||||
|
||||
void cacheStub(uint64_t /*_id*/, bool /*_store*/, void* /*_data*/, uint32_t& _length)
|
||||
{
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
FatalFn g_fatal = fatalStub;
|
||||
CallbackI* g_callback = &s_callbackStub;
|
||||
ReallocFn g_realloc = reallocStub;
|
||||
FreeFn g_free = freeStub;
|
||||
CacheFn g_cache = cacheStub;
|
||||
|
||||
static BX_THREAD uint32_t s_threadIndex = 0;
|
||||
static Context s_ctx;
|
||||
|
@ -82,7 +118,7 @@ namespace bgfx
|
|||
|
||||
temp[sizeof(temp)-1] = '\0';
|
||||
|
||||
g_fatal(_code, temp);
|
||||
g_callback->fatal(_code, temp);
|
||||
}
|
||||
|
||||
inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
|
||||
|
@ -150,7 +186,7 @@ namespace bgfx
|
|||
uint32_t dstPitch = _width*bpp/8;
|
||||
if (_yflip)
|
||||
{
|
||||
uint8_t* data = (uint8_t*)_src + dstPitch*_height - _srcPitch;
|
||||
uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
|
||||
for (uint32_t yy = 0; yy < _height; ++yy)
|
||||
{
|
||||
fwrite(data, dstPitch, 1, file);
|
||||
|
@ -520,11 +556,11 @@ namespace bgfx
|
|||
#endif // BGFX_CONFIG_RENDERER_
|
||||
}
|
||||
|
||||
void init(FatalFn _fatal, ReallocFn _realloc, FreeFn _free, CacheFn _cache)
|
||||
void init(CallbackI* _callback, ReallocFn _realloc, FreeFn _free)
|
||||
{
|
||||
if (NULL != _fatal)
|
||||
if (NULL != _callback)
|
||||
{
|
||||
g_fatal = _fatal;
|
||||
g_callback = _callback;
|
||||
}
|
||||
|
||||
if (NULL != _realloc
|
||||
|
@ -534,11 +570,6 @@ namespace bgfx
|
|||
g_free = _free;
|
||||
}
|
||||
|
||||
if (NULL != _cache)
|
||||
{
|
||||
g_cache = _cache;
|
||||
}
|
||||
|
||||
s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
|
||||
|
||||
// On NaCl renderer is on the main thread.
|
||||
|
@ -551,10 +582,9 @@ namespace bgfx
|
|||
s_ctx.shutdown();
|
||||
|
||||
s_threadIndex = 0;
|
||||
g_fatal = fatalStub;
|
||||
g_callback = &s_callbackStub;
|
||||
g_realloc = reallocStub;
|
||||
g_free = freeStub;
|
||||
g_cache = cacheStub;
|
||||
}
|
||||
|
||||
void reset(uint32_t _width, uint32_t _height, uint32_t _flags)
|
||||
|
|
|
@ -177,10 +177,9 @@ namespace bgfx
|
|||
};
|
||||
|
||||
extern const uint32_t g_uniformTypeSize[UniformType::Count];
|
||||
extern FatalFn g_fatal;
|
||||
extern CallbackI* g_callback;
|
||||
extern ReallocFn g_realloc;
|
||||
extern FreeFn g_free;
|
||||
extern CacheFn g_cache;
|
||||
|
||||
void fatal(Fatal::Enum _code, const char* _format, ...);
|
||||
void release(const Memory* _mem);
|
||||
|
|
|
@ -437,7 +437,7 @@ bool parseDds(Dds& _dds, const Memory* _mem)
|
|||
break;
|
||||
|
||||
case D3DFMT_A16B16G16R16F:
|
||||
type = TextureFormat::ABGR16;
|
||||
type = TextureFormat::RGBA16;
|
||||
blockSize = 8;
|
||||
bpp = 64;
|
||||
break;
|
||||
|
@ -448,13 +448,13 @@ bool parseDds(Dds& _dds, const Memory* _mem)
|
|||
switch (pixelFlags)
|
||||
{
|
||||
case DDPF_RGB:
|
||||
type = TextureFormat::XRGB8;
|
||||
type = TextureFormat::BGRX8;
|
||||
blockSize = 3;
|
||||
bpp = 24;
|
||||
break;
|
||||
|
||||
case DDPF_RGB|DDPF_ALPHAPIXELS:
|
||||
type = TextureFormat::ARGB8;
|
||||
type = TextureFormat::BGRA8;
|
||||
blockSize = 4;
|
||||
bpp = 32;
|
||||
break;
|
||||
|
|
|
@ -18,6 +18,7 @@ GL_IMPORT(false, PFNGLTEXIMAGE2DPROC, glTexImage2D);
|
|||
GL_IMPORT(false, PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
|
||||
GL_IMPORT(false, PFNGLPIXELSTOREI, glPixelStorei);
|
||||
GL_IMPORT(false, PFNGLTEXPARAMETERIPROC, glTexParameteri);
|
||||
GL_IMPORT(false, PFNGLTEXPARAMETERIVPROC, glTexParameteriv);
|
||||
GL_IMPORT(false, PFNGLTEXPARAMETERFPROC, glTexParameterf);
|
||||
GL_IMPORT(false, PFNGLBINDTEXTUREPROC, glBindTexture);
|
||||
GL_IMPORT(false, PFNGLGENTEXTURESPROC, glGenTextures);
|
||||
|
|
|
@ -405,6 +405,8 @@ namespace bgfx
|
|||
DX_RELEASE(m_backBufferColor, 0);
|
||||
|
||||
// invalidateCache();
|
||||
|
||||
capturePreReset();
|
||||
}
|
||||
|
||||
void postReset()
|
||||
|
@ -436,6 +438,8 @@ namespace bgfx
|
|||
|
||||
m_currentColor = m_backBufferColor;
|
||||
m_currentDepthStencil = m_backBufferDepthStencil;
|
||||
|
||||
capturePostReset();
|
||||
}
|
||||
|
||||
void flip()
|
||||
|
@ -761,6 +765,18 @@ namespace bgfx
|
|||
commitTextureStage();
|
||||
}
|
||||
|
||||
void capturePreReset()
|
||||
{
|
||||
}
|
||||
|
||||
void capturePostReset()
|
||||
{
|
||||
}
|
||||
|
||||
void capture()
|
||||
{
|
||||
}
|
||||
|
||||
void saveScreenShot(Memory* _mem)
|
||||
{
|
||||
ID3D11Texture2D* backBuffer;
|
||||
|
@ -801,7 +817,14 @@ namespace bgfx
|
|||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) );
|
||||
saveTga( (const char*)_mem->data, backBufferDesc.Width, backBufferDesc.Height, mapped.RowPitch, mapped.pData);
|
||||
g_callback->screenShot( (const char*)_mem->data
|
||||
, backBufferDesc.Width
|
||||
, backBufferDesc.Height
|
||||
, mapped.RowPitch
|
||||
, mapped.pData
|
||||
, backBufferDesc.Height*mapped.RowPitch
|
||||
, false
|
||||
);
|
||||
m_deviceCtx->Unmap(texture, 0);
|
||||
|
||||
DX_RELEASE(texture, 0);
|
||||
|
@ -1354,7 +1377,7 @@ namespace bgfx
|
|||
D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D11_SUBRESOURCE_DATA) );
|
||||
|
||||
uint32_t kk = 0;
|
||||
bool convert = TextureFormat::XRGB8 == dds.m_type;
|
||||
bool convert = false;
|
||||
|
||||
m_numMips = dds.m_numMips;
|
||||
|
||||
|
@ -1362,6 +1385,7 @@ namespace bgfx
|
|||
|| TextureFormat::Unknown < dds.m_type)
|
||||
{
|
||||
uint32_t bpp = s_textureFormat[dds.m_type].m_bpp;
|
||||
convert = TextureFormat::BGRX8 == dds.m_type;
|
||||
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
|
@ -1380,7 +1404,7 @@ namespace bgfx
|
|||
{
|
||||
if (convert)
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*bpp*mip.m_height/8);
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*bpp/8);
|
||||
mip.decode(temp);
|
||||
|
||||
srd[kk].pSysMem = temp;
|
||||
|
|
|
@ -656,6 +656,8 @@ namespace bgfx
|
|||
DX_RELEASE(m_backBufferColor, 0);
|
||||
DX_RELEASE(m_backBufferDepthStencil, 0);
|
||||
|
||||
capturePreReset();
|
||||
|
||||
for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
|
||||
{
|
||||
m_indexBuffers[ii].preReset();
|
||||
|
@ -677,6 +679,8 @@ namespace bgfx
|
|||
DX_CHECK(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
|
||||
DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) );
|
||||
|
||||
capturePostReset();
|
||||
|
||||
for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
|
||||
{
|
||||
m_indexBuffers[ii].postReset();
|
||||
|
@ -693,6 +697,89 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void capturePreReset()
|
||||
{
|
||||
if (NULL != m_captureSurface)
|
||||
{
|
||||
g_callback->captureEnd();
|
||||
}
|
||||
DX_RELEASE(m_captureSurface, 1);
|
||||
DX_RELEASE(m_captureTexture, 0);
|
||||
DX_RELEASE(m_captureResolve, 0);
|
||||
}
|
||||
|
||||
void capturePostReset()
|
||||
{
|
||||
if (m_flags&BGFX_RESET_CAPTURE)
|
||||
{
|
||||
uint32_t width = m_params.BackBufferWidth;
|
||||
uint32_t height = m_params.BackBufferHeight;
|
||||
D3DFORMAT fmt = m_params.BackBufferFormat;
|
||||
|
||||
DX_CHECK(m_device->CreateTexture(width
|
||||
, height
|
||||
, 1
|
||||
, 0
|
||||
, fmt
|
||||
, D3DPOOL_SYSTEMMEM
|
||||
, &m_captureTexture
|
||||
, NULL
|
||||
) );
|
||||
|
||||
DX_CHECK(m_captureTexture->GetSurfaceLevel(0
|
||||
, &m_captureSurface
|
||||
) );
|
||||
|
||||
if (m_params.MultiSampleType != D3DMULTISAMPLE_NONE)
|
||||
{
|
||||
DX_CHECK(m_device->CreateRenderTarget(width
|
||||
, height
|
||||
, fmt
|
||||
, D3DMULTISAMPLE_NONE
|
||||
, 0
|
||||
, false
|
||||
, &m_captureResolve
|
||||
, NULL
|
||||
) );
|
||||
}
|
||||
|
||||
g_callback->captureBegin(width, height, width*4, TextureFormat::BGRA8, false);
|
||||
}
|
||||
}
|
||||
|
||||
void capture()
|
||||
{
|
||||
if (NULL != m_captureSurface)
|
||||
{
|
||||
IDirect3DSurface9* resolve = m_backBufferColor;
|
||||
|
||||
if (NULL != m_captureResolve)
|
||||
{
|
||||
resolve = m_captureResolve;
|
||||
DX_CHECK(m_device->StretchRect(m_backBufferColor
|
||||
, 0
|
||||
, m_captureResolve
|
||||
, NULL
|
||||
, D3DTEXF_NONE
|
||||
) );
|
||||
}
|
||||
|
||||
HRESULT hr = m_device->GetRenderTargetData(resolve, m_captureSurface);
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
D3DLOCKED_RECT rect;
|
||||
DX_CHECK(m_captureSurface->LockRect(&rect
|
||||
, NULL
|
||||
, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY
|
||||
) );
|
||||
|
||||
g_callback->captureFrame(rect.pBits, m_params.BackBufferHeight*rect.Pitch);
|
||||
|
||||
DX_CHECK(m_captureSurface->UnlockRect() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void saveScreenShot(Memory* _mem)
|
||||
{
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
|
@ -727,7 +814,15 @@ namespace bgfx
|
|||
ClientToScreen(g_bgfxHwnd, &point);
|
||||
uint8_t* data = (uint8_t*)rect.pBits;
|
||||
uint32_t bytesPerPixel = rect.Pitch/dm.Width;
|
||||
saveTga( (const char*)_mem->data, m_params.BackBufferWidth, m_params.BackBufferHeight, rect.Pitch, &data[point.y*rect.Pitch+point.x*bytesPerPixel]);
|
||||
|
||||
g_callback->screenShot( (const char*)_mem->data
|
||||
, m_params.BackBufferWidth
|
||||
, m_params.BackBufferHeight
|
||||
, rect.Pitch
|
||||
, &data[point.y*rect.Pitch+point.x*bytesPerPixel]
|
||||
, m_params.BackBufferHeight*rect.Pitch
|
||||
, false
|
||||
);
|
||||
|
||||
DX_CHECK(surface->UnlockRect() );
|
||||
DX_RELEASE(surface, 0);
|
||||
|
@ -752,6 +847,11 @@ namespace bgfx
|
|||
|
||||
IDirect3DSurface9* m_backBufferColor;
|
||||
IDirect3DSurface9* m_backBufferDepthStencil;
|
||||
|
||||
IDirect3DTexture9* m_captureTexture;
|
||||
IDirect3DSurface9* m_captureSurface;
|
||||
IDirect3DSurface9* m_captureResolve;
|
||||
|
||||
IDirect3DVertexDeclaration9* m_instanceDataDecls[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
|
||||
|
||||
HMODULE m_d3d9dll;
|
||||
|
@ -2490,6 +2590,10 @@ namespace bgfx
|
|||
int64_t now = bx::getHPCounter();
|
||||
elapsed += now;
|
||||
|
||||
int64_t captureElapsed = -bx::getHPCounter();
|
||||
s_renderCtx.capture();
|
||||
captureElapsed += bx::getHPCounter();
|
||||
|
||||
static int64_t last = now;
|
||||
int64_t frameTime = now - last;
|
||||
last = now;
|
||||
|
@ -2513,7 +2617,6 @@ namespace bgfx
|
|||
|
||||
double freq = double(bx::getHPFrequency() );
|
||||
double toMs = 1000.0/freq;
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
|
||||
tvm.clear();
|
||||
uint16_t pos = 10;
|
||||
|
@ -2524,6 +2627,8 @@ namespace bgfx
|
|||
, double(max)*toMs
|
||||
, freq/frameTime
|
||||
);
|
||||
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms]"
|
||||
, m_render->m_num
|
||||
, elapsedCpuMs
|
||||
|
@ -2533,6 +2638,9 @@ namespace bgfx
|
|||
, statsNumInstances
|
||||
, statsNumPrimsSubmitted
|
||||
);
|
||||
|
||||
double captureMs = double(captureElapsed)*toMs;
|
||||
tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs);
|
||||
tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
|
||||
tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
|
||||
tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);
|
||||
|
|
|
@ -26,6 +26,97 @@
|
|||
|
||||
namespace bgfx
|
||||
{
|
||||
struct Extension
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
EXT_texture_filter_anisotropic,
|
||||
EXT_texture_format_BGRA8888,
|
||||
EXT_texture_compression_s3tc,
|
||||
EXT_texture_compression_dxt1,
|
||||
CHROMIUM_texture_compression_dxt3,
|
||||
CHROMIUM_texture_compression_dxt5,
|
||||
ARB_texture_float,
|
||||
OES_texture_float,
|
||||
OES_texture_float_linear,
|
||||
OES_texture_half_float,
|
||||
OES_texture_half_float_linear,
|
||||
EXT_texture_type_2_10_10_10_REV,
|
||||
EXT_texture_sRGB,
|
||||
ARB_texture_swizzle,
|
||||
EXT_texture_swizzle,
|
||||
OES_standard_derivatives,
|
||||
ARB_get_program_binary,
|
||||
OES_get_program_binary,
|
||||
EXT_framebuffer_blit,
|
||||
ARB_timer_query,
|
||||
EXT_timer_query,
|
||||
ARB_framebuffer_sRGB,
|
||||
EXT_framebuffer_sRGB,
|
||||
ARB_multisample,
|
||||
CHROMIUM_framebuffer_multisample,
|
||||
ANGLE_translated_shader_source,
|
||||
ARB_instanced_arrays,
|
||||
ANGLE_instanced_arrays,
|
||||
ARB_half_float_vertex,
|
||||
OES_vertex_half_float,
|
||||
ARB_vertex_type_2_10_10_10_rev,
|
||||
OES_vertex_type_10_10_10_2,
|
||||
EXT_occlusion_query_boolean,
|
||||
ARB_vertex_array_object,
|
||||
ATI_meminfo,
|
||||
NVX_gpu_memory_info,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
const char* m_name;
|
||||
bool m_supported;
|
||||
bool m_initialize;
|
||||
};
|
||||
|
||||
static Extension s_extension[Extension::Count] =
|
||||
{
|
||||
{ "GL_EXT_texture_filter_anisotropic", false, true },
|
||||
// Nvidia BGRA on Linux bug:
|
||||
// https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
|
||||
{ "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
|
||||
{ "GL_EXT_texture_compression_s3tc", false, true },
|
||||
{ "GL_EXT_texture_compression_dxt1", false, true },
|
||||
{ "GL_CHROMIUM_texture_compression_dxt3", false, true },
|
||||
{ "GL_CHROMIUM_texture_compression_dxt5", false, true },
|
||||
{ "GL_ARB_texture_float", false, true },
|
||||
{ "GL_OES_texture_float", false, true },
|
||||
{ "GL_OES_texture_float_linear", false, true },
|
||||
{ "GL_OES_texture_half_float", false, true },
|
||||
{ "GL_OES_texture_half_float_linear", false, true },
|
||||
{ "GL_EXT_texture_type_2_10_10_10_REV", false, true },
|
||||
{ "GL_EXT_texture_sRGB", false, true },
|
||||
{ "GL_ARB_texture_swizzle", false, true },
|
||||
{ "GL_EXT_texture_swizzle", false, true },
|
||||
{ "GL_OES_standard_derivatives", false, true },
|
||||
{ "GL_ARB_get_program_binary", false, true },
|
||||
{ "GL_OES_get_program_binary", false, false },
|
||||
{ "GL_EXT_framebuffer_blit", false, true },
|
||||
{ "GL_ARB_timer_query", false, true },
|
||||
{ "GL_EXT_timer_query", false, true },
|
||||
{ "GL_ARB_framebuffer_sRGB", false, true },
|
||||
{ "GL_EXT_framebuffer_sRGB", false, true },
|
||||
{ "GL_ARB_multisample", false, true },
|
||||
{ "GL_CHROMIUM_framebuffer_multisample", false, true },
|
||||
{ "GL_ANGLE_translated_shader_source", false, true },
|
||||
{ "GL_ARB_instanced_arrays", false, true },
|
||||
{ "GL_ANGLE_instanced_arrays", false, true },
|
||||
{ "GL_ARB_half_float_vertex", false, true },
|
||||
{ "GL_OES_vertex_half_float", false, true },
|
||||
{ "GL_ARB_vertex_type_2_10_10_10_rev", false, true },
|
||||
{ "GL_OES_vertex_type_10_10_10_2", false, true },
|
||||
{ "GL_EXT_occlusion_query_boolean", false, true },
|
||||
{ "GL_ARB_vertex_array_object", false, true },
|
||||
{ "GL_ATI_meminfo", false, true },
|
||||
{ "GL_NVX_gpu_memory_info", false, true },
|
||||
};
|
||||
|
||||
#if BGFX_USE_WGL
|
||||
PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
|
||||
PFNWGLMAKECURRENTPROC wglMakeCurrent;
|
||||
|
@ -74,10 +165,29 @@ namespace bgfx
|
|||
};
|
||||
#endif // BX_PLATFORM_NACL
|
||||
|
||||
static void rgbaToBgra(uint8_t* _data, uint32_t _width, uint32_t _height)
|
||||
{
|
||||
uint32_t dstpitch = _width*4;
|
||||
for (uint32_t yy = 0; yy < _height; ++yy)
|
||||
{
|
||||
uint8_t* dst = &_data[yy*dstpitch];
|
||||
|
||||
for (uint32_t xx = 0; xx < _width; ++xx)
|
||||
{
|
||||
uint8_t tmp = dst[0];
|
||||
dst[0] = dst[2];
|
||||
dst[2] = tmp;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RendererContext
|
||||
{
|
||||
RendererContext()
|
||||
: m_maxAnisotropy(0.0f)
|
||||
: m_capture(NULL)
|
||||
, m_captureSize(0)
|
||||
, m_maxAnisotropy(0.0f)
|
||||
, m_dxtSupport(false)
|
||||
, m_programBinarySupport(false)
|
||||
, m_flip(false)
|
||||
|
@ -116,6 +226,7 @@ namespace bgfx
|
|||
|
||||
m_resolution = _resolution;
|
||||
setRenderContextSize(_resolution.m_width, _resolution.m_height);
|
||||
updateCapture();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,6 +309,19 @@ namespace bgfx
|
|||
|
||||
DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||
|
||||
BX_TRACE("Pixel format:\n"
|
||||
"\tiPixelType %d\n"
|
||||
"\tcColorBits %d\n"
|
||||
"\tcAlphaBits %d\n"
|
||||
"\tcDepthBits %d\n"
|
||||
"\tcStencilBits %d\n"
|
||||
, pfd.iPixelType
|
||||
, pfd.cColorBits
|
||||
, pfd.cAlphaBits
|
||||
, pfd.cDepthBits
|
||||
, pfd.cStencilBits
|
||||
);
|
||||
|
||||
int result;
|
||||
result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
|
||||
BGFX_FATAL(0 != result, Fatal::UnableToInitialize, "SetPixelFormat failed!");
|
||||
|
@ -464,21 +588,75 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void updateCapture()
|
||||
{
|
||||
if (m_resolution.m_flags&BGFX_RESET_CAPTURE)
|
||||
{
|
||||
m_captureSize = m_resolution.m_width*m_resolution.m_height*4;
|
||||
m_capture = g_realloc(m_capture, m_captureSize);
|
||||
g_callback->captureBegin(m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, TextureFormat::BGRA8, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != m_capture)
|
||||
{
|
||||
g_callback->captureEnd();
|
||||
g_free(m_capture);
|
||||
m_capture = NULL;
|
||||
m_captureSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void capture()
|
||||
{
|
||||
if (NULL != m_capture)
|
||||
{
|
||||
GLint fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
|
||||
GL_CHECK(glReadPixels(0
|
||||
, 0
|
||||
, m_resolution.m_width
|
||||
, m_resolution.m_height
|
||||
, fmt
|
||||
, GL_UNSIGNED_BYTE
|
||||
, m_capture
|
||||
) );
|
||||
|
||||
g_callback->captureFrame(m_capture, m_captureSize);
|
||||
}
|
||||
}
|
||||
|
||||
void saveScreenShot(Memory* _mem)
|
||||
{
|
||||
void* data = g_realloc(NULL, m_resolution.m_width*m_resolution.m_height*4);
|
||||
glReadPixels(0, 0, m_resolution.m_width, m_resolution.m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
uint32_t length = m_resolution.m_width*m_resolution.m_height*4;
|
||||
uint8_t* data = (uint8_t*)g_realloc(NULL, length);
|
||||
GLint fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
|
||||
|
||||
uint8_t* rgba = (uint8_t*)data;
|
||||
for (uint32_t ii = 0, num = m_resolution.m_width*m_resolution.m_height; ii < num; ++ii)
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t height = m_resolution.m_height;
|
||||
|
||||
GL_CHECK(glReadPixels(0
|
||||
, 0
|
||||
, width
|
||||
, height
|
||||
, fmt
|
||||
, GL_UNSIGNED_BYTE
|
||||
, data
|
||||
) );
|
||||
|
||||
if (GL_RGBA == fmt)
|
||||
{
|
||||
uint8_t temp = rgba[0];
|
||||
rgba[0] = rgba[2];
|
||||
rgba[2] = temp;
|
||||
rgba += 4;
|
||||
rgbaToBgra(data, width, height);
|
||||
}
|
||||
|
||||
saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data, false, true);
|
||||
g_callback->screenShot( (const char*)_mem->data
|
||||
, width
|
||||
, height
|
||||
, width*4
|
||||
, data
|
||||
, length
|
||||
, true
|
||||
);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
|
@ -531,6 +709,8 @@ namespace bgfx
|
|||
TextVideoMem m_textVideoMem;
|
||||
|
||||
Resolution m_resolution;
|
||||
void* m_capture;
|
||||
uint32_t m_captureSize;
|
||||
float m_maxAnisotropy;
|
||||
bool m_dxtSupport;
|
||||
bool m_programBinarySupport;
|
||||
|
@ -613,93 +793,6 @@ namespace bgfx
|
|||
}
|
||||
#endif // BX_PLATFORM_
|
||||
|
||||
struct Extension
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
EXT_texture_filter_anisotropic,
|
||||
EXT_texture_format_BGRA8888,
|
||||
EXT_texture_compression_s3tc,
|
||||
EXT_texture_compression_dxt1,
|
||||
CHROMIUM_texture_compression_dxt3,
|
||||
CHROMIUM_texture_compression_dxt5,
|
||||
ARB_texture_float,
|
||||
OES_texture_float,
|
||||
OES_texture_float_linear,
|
||||
OES_texture_half_float,
|
||||
OES_texture_half_float_linear,
|
||||
EXT_texture_type_2_10_10_10_REV,
|
||||
EXT_texture_sRGB,
|
||||
OES_standard_derivatives,
|
||||
ARB_get_program_binary,
|
||||
OES_get_program_binary,
|
||||
EXT_framebuffer_blit,
|
||||
ARB_timer_query,
|
||||
EXT_timer_query,
|
||||
ARB_framebuffer_sRGB,
|
||||
EXT_framebuffer_sRGB,
|
||||
ARB_multisample,
|
||||
CHROMIUM_framebuffer_multisample,
|
||||
ANGLE_translated_shader_source,
|
||||
ARB_instanced_arrays,
|
||||
ANGLE_instanced_arrays,
|
||||
ARB_half_float_vertex,
|
||||
OES_vertex_half_float,
|
||||
ARB_vertex_type_2_10_10_10_rev,
|
||||
OES_vertex_type_10_10_10_2,
|
||||
EXT_occlusion_query_boolean,
|
||||
ARB_vertex_array_object,
|
||||
ATI_meminfo,
|
||||
NVX_gpu_memory_info,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
const char* m_name;
|
||||
bool m_supported;
|
||||
bool m_initialize;
|
||||
};
|
||||
|
||||
static Extension s_extension[Extension::Count] =
|
||||
{
|
||||
{ "GL_EXT_texture_filter_anisotropic", false, true },
|
||||
// Nvidia BGRA on Linux bug:
|
||||
// https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
|
||||
{ "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
|
||||
{ "GL_EXT_texture_compression_s3tc", false, true },
|
||||
{ "GL_EXT_texture_compression_dxt1", false, true },
|
||||
{ "GL_CHROMIUM_texture_compression_dxt3", false, true },
|
||||
{ "GL_CHROMIUM_texture_compression_dxt5", false, true },
|
||||
{ "GL_ARB_texture_float", false, true },
|
||||
{ "GL_OES_texture_float", false, true },
|
||||
{ "GL_OES_texture_float_linear", false, true },
|
||||
{ "GL_OES_texture_half_float", false, true },
|
||||
{ "GL_OES_texture_half_float_linear", false, true },
|
||||
{ "GL_EXT_texture_type_2_10_10_10_REV", false, true },
|
||||
{ "GL_EXT_texture_sRGB", false, true },
|
||||
{ "GL_OES_standard_derivatives", false, true },
|
||||
{ "GL_ARB_get_program_binary", false, true },
|
||||
{ "GL_OES_get_program_binary", false, false },
|
||||
{ "GL_EXT_framebuffer_blit", false, true },
|
||||
{ "GL_ARB_timer_query", false, true },
|
||||
{ "GL_EXT_timer_query", false, true },
|
||||
{ "GL_ARB_framebuffer_sRGB", false, true },
|
||||
{ "GL_EXT_framebuffer_sRGB", false, true },
|
||||
{ "GL_ARB_multisample", false, true },
|
||||
{ "GL_CHROMIUM_framebuffer_multisample", false, true },
|
||||
{ "GL_ANGLE_translated_shader_source", false, true },
|
||||
{ "GL_ARB_instanced_arrays", false, true },
|
||||
{ "GL_ANGLE_instanced_arrays", false, true },
|
||||
{ "GL_ARB_half_float_vertex", false, true },
|
||||
{ "GL_OES_vertex_half_float", false, true },
|
||||
{ "GL_ARB_vertex_type_2_10_10_10_rev", false, true },
|
||||
{ "GL_OES_vertex_type_10_10_10_2", false, true },
|
||||
{ "GL_EXT_occlusion_query_boolean", false, true },
|
||||
{ "GL_ARB_vertex_array_object", false, true },
|
||||
{ "GL_ATI_meminfo", false, true },
|
||||
{ "GL_NVX_gpu_memory_info", false, true },
|
||||
};
|
||||
|
||||
static const GLenum s_primType[] =
|
||||
{
|
||||
GL_TRIANGLES,
|
||||
|
@ -966,21 +1059,21 @@ namespace bgfx
|
|||
|
||||
if (s_renderCtx.m_programBinarySupport)
|
||||
{
|
||||
uint32_t length;
|
||||
g_cache(id, false, NULL, length);
|
||||
uint32_t length = g_callback->cacheReadSize(id);
|
||||
cached = length > 0;
|
||||
|
||||
if (cached)
|
||||
{
|
||||
void* data = g_realloc(NULL, length);
|
||||
g_cache(id, false, data, length);
|
||||
if (g_callback->cacheRead(id, data, length) )
|
||||
{
|
||||
bx::MemoryReader reader(data, length);
|
||||
|
||||
bx::MemoryReader reader(data, length);
|
||||
GLenum format;
|
||||
bx::read(&reader, format);
|
||||
|
||||
GLenum format;
|
||||
bx::read(&reader, format);
|
||||
|
||||
GL_CHECK(glProgramBinary(m_id, format, reader.getDataPtr(), (GLsizei)reader.remaining() ) );
|
||||
GL_CHECK(glProgramBinary(m_id, format, reader.getDataPtr(), (GLsizei)reader.remaining() ) );
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
}
|
||||
|
@ -1022,7 +1115,7 @@ namespace bgfx
|
|||
GL_CHECK(glGetProgramBinary(m_id, programLength, NULL, &format, &data[4]) );
|
||||
*(uint32_t*)data = format;
|
||||
|
||||
g_cache(id, true, data, length);
|
||||
g_callback->cacheWrite(id, data, length);
|
||||
|
||||
g_free(data);
|
||||
}
|
||||
|
@ -1344,16 +1437,30 @@ namespace bgfx
|
|||
if (GL_RGBA == internalFmt
|
||||
|| decompress)
|
||||
{
|
||||
internalFmt = GL_RGBA;
|
||||
m_fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
|
||||
|
||||
}
|
||||
|
||||
bool swizzle = GL_RGBA == m_fmt;
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (swizzle
|
||||
&& (s_extension[Extension::ARB_texture_swizzle].m_supported || s_extension[Extension::EXT_texture_swizzle].m_supported) )
|
||||
{
|
||||
swizzle = false;
|
||||
GLint swizzleMask[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
GL_CHECK(glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask) );
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
m_type = tfi.m_type;
|
||||
if (decompress)
|
||||
{
|
||||
m_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*tfi.m_bpp/8);
|
||||
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*4);
|
||||
|
||||
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
|
@ -1372,21 +1479,9 @@ namespace bgfx
|
|||
{
|
||||
mip.decode(bits);
|
||||
|
||||
if (GL_RGBA == internalFmt)
|
||||
if (swizzle)
|
||||
{
|
||||
uint32_t dstpitch = width*4;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
uint8_t tmp = dst[0];
|
||||
dst[0] = dst[2];
|
||||
dst[2] = tmp;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
rgbaToBgra(bits, width, height);
|
||||
}
|
||||
|
||||
texImage(target+side
|
||||
|
@ -2881,6 +2976,10 @@ namespace bgfx
|
|||
int64_t now = bx::getHPCounter();
|
||||
elapsed += now;
|
||||
|
||||
int64_t captureElapsed = -bx::getHPCounter();
|
||||
s_renderCtx.capture();
|
||||
captureElapsed += bx::getHPCounter();
|
||||
|
||||
static int64_t last = now;
|
||||
int64_t frameTime = now - last;
|
||||
last = now;
|
||||
|
@ -2908,7 +3007,6 @@ namespace bgfx
|
|||
next = now + bx::getHPFrequency();
|
||||
double freq = double(bx::getHPFrequency() );
|
||||
double toMs = 1000.0/freq;
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
|
||||
tvm.clear();
|
||||
uint16_t pos = 10;
|
||||
|
@ -2919,6 +3017,8 @@ namespace bgfx
|
|||
, double(max)*toMs
|
||||
, freq/frameTime
|
||||
);
|
||||
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms] %c GPU %3.4f [ms]"
|
||||
, m_render->m_num
|
||||
, elapsedCpuMs
|
||||
|
@ -2930,6 +3030,10 @@ namespace bgfx
|
|||
, statsNumInstances
|
||||
, statsNumPrimsSubmitted
|
||||
);
|
||||
|
||||
double captureMs = double(captureElapsed)*toMs;
|
||||
tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs);
|
||||
|
||||
tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
|
||||
tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
|
||||
tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);
|
||||
|
|
|
@ -158,6 +158,7 @@ typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, G
|
|||
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
|
||||
typedef void (APIENTRYP PFNGLPIXELSTOREI) (GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||
|
|
Loading…
Reference in New Issue