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.
|
||||
|
579
examples/07-callback/callback.cpp
Normal file
579
examples/07-callback/callback.cpp
Normal file
@ -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;
|
||||
}
|
17
examples/07-callback/fs_callback.sc
Normal file
17
examples/07-callback/fs_callback.sc
Normal file
@ -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) );
|
||||
}
|
17
examples/07-callback/makefile
Normal file
17
examples/07-callback/makefile
Normal file
@ -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
|
5
examples/07-callback/varying.def.sc
Normal file
5
examples/07-callback/varying.def.sc
Normal file
@ -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;
|
16
examples/07-callback/vs_callback.sc
Normal file
16
examples/07-callback/vs_callback.sc
Normal file
@ -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;
|
||||
}
|
BIN
examples/runtime/shaders/dx11/fs_callback.bin
Normal file
BIN
examples/runtime/shaders/dx11/fs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/dx11/vs_callback.bin
Normal file
BIN
examples/runtime/shaders/dx11/vs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/dx9/fs_callback.bin
Normal file
BIN
examples/runtime/shaders/dx9/fs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/dx9/vs_callback.bin
Normal file
BIN
examples/runtime/shaders/dx9/vs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/gles/fs_callback.bin
Normal file
BIN
examples/runtime/shaders/gles/fs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/gles/vs_callback.bin
Normal file
BIN
examples/runtime/shaders/gles/vs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/glsl/fs_callback.bin
Normal file
BIN
examples/runtime/shaders/glsl/fs_callback.bin
Normal file
Binary file not shown.
BIN
examples/runtime/shaders/glsl/vs_callback.bin
Normal file
BIN
examples/runtime/shaders/glsl/vs_callback.bin
Normal file
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();
|
||||
|
36
premake/example-07-callback.lua
Normal file
36
premake/example-07-callback.lua
Normal file
@ -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
Block a user