Added OpenGL support for Windows build. Added Linux support (Thanks @MatthewEndsley for X window and GLX code). Fixed uniform size for D3D9.

This commit is contained in:
bkaradzic 2012-05-29 18:24:55 -07:00
parent 8199e07fa6
commit d9a08e3f81
11 changed files with 12287 additions and 90 deletions

6
.gitignore vendored
View File

@ -1,2 +1,4 @@
.build
.build/
.debug/
.svn/
tags

11813
3rdparty/glext/gl/glext.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
# define snprintf _snprintf
#endif // BX_COMPILER_MSVC
#if BX_PLATFORM_WINDOWS
#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
extern "C"
{
__declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str);
@ -59,7 +59,7 @@ void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...)
va_list argList;
va_start(argList, _format);
dbgPrintf(_format, argList);
dbgPrintfVargs(_format, argList);
va_end(argList);
dbgPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size);

View File

@ -145,6 +145,18 @@ namespace bgfx
D3D9_UnableToCreateInterface,
D3D9_UnableToCreateDevice,
D3D9_UnableToCreateRenderTarget,
OPENGL_UnableToCreateContext,
};
};
struct RendererType
{
enum Enum
{
Null = 0,
Direct3D9,
OpenGLES,
OpenGL,
};
};
@ -256,6 +268,9 @@ namespace bgfx
uint8_t m_attributes[Attrib::Count];
};
///
RendererType::Enum getRendererType();
///
void init(bool _createRenderThread = true, fatalFn _fatal = NULL, reallocFn _realloc = NULL, freeFn _free = NULL);

View File

@ -468,6 +468,19 @@ namespace bgfx
radixSort(m_sortKeys, s_ctx.m_tempKeys, m_sortValues, s_ctx.m_tempValues, m_num);
}
RendererType::Enum getRendererType()
{
#if BGFX_CONFIG_RENDERER_DIRECT3D
return RendererType::Direct3D9;
#elif BGFX_CONFIG_RENDERER_OPENGL
return RendererType::OpenGL;
#elif BGFX_CONFIG_RENDERER_OPENGLES
return RendererType::OpenGLES;
#else
return RendererType::Null;
#endif // BGFX_CONFIG_RENDERER_
}
void init(bool _createRenderThread, fatalFn _fatal, reallocFn _realloc, freeFn _free)
{
if (NULL != _fatal)
@ -647,16 +660,18 @@ namespace bgfx
#if BX_PLATFORM_WINDOWS
m_window.init();
#endif // BX_PLATFORM_WINDOWS
#endif // BX_PLATFORM_
#if BGFX_CONFIG_MULTITHREADED
m_renderThread = NULL;
m_renderThread = 0;
if (_createRenderThread)
{
# if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
m_renderThread = CreateThread(NULL, 16<<10, renderThread, NULL, 0, NULL);
# endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
# elif BX_PLATFORM_LINUX
pthread_create(&m_renderThread, NULL, renderThread, NULL);
# endif // BX_PLATFORM_
}
#endif // BGFX_CONFIG_MULTITHREADED
@ -688,12 +703,15 @@ namespace bgfx
frame();
#if BGFX_CONFIG_MULTITHREADED
if (NULL != m_renderThread)
if (0 != m_renderThread)
{
# if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
WaitForSingleObject(m_renderThread, INFINITE);
m_renderThread = NULL;
# endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
# elif BX_PLATFORM_LINUX
pthread_join(m_renderThread, NULL);
m_renderThread = 0;
# endif // BX_PLATFORM_*
}
#endif // BGFX_CONFIG_MULTITHREADED

View File

@ -75,36 +75,31 @@ extern HWND g_bgfxHwnd;
#define BGFX_MAGIC MAKEFOURCC('B','G','F','X')
namespace std
{
namespace tr1
{
}
using namespace tr1;
} // namespace std
namespace std { namespace tr1 {} using namespace tr1; } // namespace std
#include <string>
#include <unordered_map>
#ifndef BGFX_CONFIG_RENDERER_DIRECT3D
# define BGFX_CONFIG_RENDERER_DIRECT3D (BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360)
#endif // BGFX_CONFIG_RENDERER_DIRECT3D
#if !defined(BGFX_CONFIG_RENDERER_DIRECT3D) && !defined(BGFX_CONFIG_RENDERER_OPENGL) && !defined(BGFX_CONFIG_RENDERER_OPENGLES) && !defined(BGFX_CONFIG_RENDERER_NULL)
# ifndef BGFX_CONFIG_RENDERER_DIRECT3D
# define BGFX_CONFIG_RENDERER_DIRECT3D (BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360)
# endif // BGFX_CONFIG_RENDERER_DIRECT3D
#ifndef BGFX_CONFIG_RENDERER_OPENGL
# define BGFX_CONFIG_RENDERER_OPENGL 0
#endif // BGFX_CONFIG_RENDERER_OPENGL
# ifndef BGFX_CONFIG_RENDERER_OPENGL
# define BGFX_CONFIG_RENDERER_OPENGL (BX_PLATFORM_LINUX)
# endif // BGFX_CONFIG_RENDERER_OPENGL
#ifndef BGFX_CONFIG_RENDERER_OPENGLES
# define BGFX_CONFIG_RENDERER_OPENGLES (BX_PLATFORM_NACL|BX_PLATFORM_ANDROID|BX_PLATFORM_LINUX)
#endif // BGFX_CONFIG_RENDERER_OPENGLES
# ifndef BGFX_CONFIG_RENDERER_OPENGLES
# define BGFX_CONFIG_RENDERER_OPENGLES (BX_PLATFORM_NACL|BX_PLATFORM_ANDROID)
# endif // BGFX_CONFIG_RENDERER_OPENGLES
#ifndef BGFX_CONFIG_RENDERER_NULL
# define BGFX_CONFIG_RENDERER_NULL (!(BGFX_CONFIG_RENDERER_DIRECT3D|BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES) )
#endif // BGFX_CONFIG_RENDERER_NULL
# ifndef BGFX_CONFIG_RENDERER_NULL
# define BGFX_CONFIG_RENDERER_NULL (!(BGFX_CONFIG_RENDERER_DIRECT3D|BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES) )
# endif // BGFX_CONFIG_RENDERER_NULL
#endif // !defined...
#ifndef BGFX_CONFIG_MULTITHREADED
# define BGFX_CONFIG_MULTITHREADED ( (BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360|BX_PLATFORM_NACL|BX_PLATFORM_LINUX)&(!BGFX_CONFIG_RENDERER_NULL) )
# define BGFX_CONFIG_MULTITHREADED ( (BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360|BX_PLATFORM_NACL)&(!BGFX_CONFIG_RENDERER_NULL) )
#endif // BGFX_CONFIG_MULTITHREADED
#ifndef BGFX_CONFIG_MAX_DRAW_CALLS
@ -1390,6 +1385,8 @@ namespace bgfx
#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
DWORD WINAPI renderThread(LPVOID _arg);
#elif BX_PLATFORM_LINUX
void* renderThread(void*);
#endif // BX_PLATFORM_
struct Context
@ -2385,7 +2382,7 @@ namespace bgfx
# if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
HANDLE m_renderThread;
# else
void* m_renderThread;
pthread_t m_renderThread;
# endif // BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
#else

59
src/glimports.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#ifndef GL_IMPORT
# error GL_IMPORT must be defined!
#endif // GL_IMPORT
GL_IMPORT(PFNGLACTIVETEXTUREPROC, glActiveTexture);
GL_IMPORT(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D);
GL_IMPORT(PFNGLBINDBUFFERPROC, glBindBuffer);
GL_IMPORT(PFNGLDELETEBUFFERSPROC, glDeleteBuffers);
GL_IMPORT(PFNGLGENBUFFERSPROC, glGenBuffers);
GL_IMPORT(PFNGLBUFFERDATAPROC, glBufferData);
GL_IMPORT(PFNGLBUFFERSUBDATAPROC, glBufferSubData);
GL_IMPORT(PFNGLCREATEPROGRAMPROC, glCreateProgram);
GL_IMPORT(PFNGLCREATESHADERPROC, glCreateShader);
GL_IMPORT(PFNGLDELETEPROGRAMPROC, glDeleteProgram);
GL_IMPORT(PFNGLDELETESHADERPROC, glDeleteShader);
GL_IMPORT(PFNGLATTACHSHADERPROC, glAttachShader);
GL_IMPORT(PFNGLCOMPILESHADERPROC, glCompileShader);
GL_IMPORT(PFNGLSHADERSOURCEPROC, glShaderSource);
GL_IMPORT(PFNGLGETSHADERIVPROC, glGetShaderiv);
GL_IMPORT(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog);
GL_IMPORT(PFNGLLINKPROGRAMPROC, glLinkProgram);
GL_IMPORT(PFNGLGETPROGRAMIVPROC, glGetProgramiv);
GL_IMPORT(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog);
GL_IMPORT(PFNGLUSEPROGRAMPROC, glUseProgram);
GL_IMPORT(PFNGLGETACTIVEATTRIBPROC, glGetActiveAttrib);
GL_IMPORT(PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation);
GL_IMPORT(PFNGLGETACTIVEUNIFORMPROC, glGetActiveUniform);
GL_IMPORT(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation);
GL_IMPORT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray);
GL_IMPORT(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray);
GL_IMPORT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer);
GL_IMPORT(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f);
GL_IMPORT(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f);
GL_IMPORT(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f);
GL_IMPORT(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f);
GL_IMPORT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer);
GL_IMPORT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers);
GL_IMPORT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers);
GL_IMPORT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus);
GL_IMPORT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer);
GL_IMPORT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D);
GL_IMPORT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer);
GL_IMPORT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers);
GL_IMPORT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers);
GL_IMPORT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage);
GL_IMPORT(PFNGLUNIFORM1IPROC, glUniform1i);
GL_IMPORT(PFNGLUNIFORM1IVPROC, glUniform1iv);
GL_IMPORT(PFNGLUNIFORM1FPROC, glUniform1f);
GL_IMPORT(PFNGLUNIFORM1FVPROC, glUniform1fv);
GL_IMPORT(PFNGLUNIFORM2FVPROC, glUniform2fv);
GL_IMPORT(PFNGLUNIFORM3FVPROC, glUniform3fv);
GL_IMPORT(PFNGLUNIFORM4FVPROC, glUniform4fv);
GL_IMPORT(PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv);
GL_IMPORT(PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv);

View File

@ -1391,7 +1391,7 @@ namespace bgfx
void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
{
uint32_t size = g_constantTypeSize[_type]*_num;
uint32_t size = BX_ALIGN_16(g_constantTypeSize[_type]*_num);
void* data = g_realloc(NULL, size);
s_renderCtx.m_uniforms[_handle.idx] = data;
s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
@ -1837,7 +1837,7 @@ namespace bgfx
}
}
if (bgfx::invalidHandle != state.m_indexBuffer.idx)
if (bgfx::invalidHandle != currentState.m_vertexBuffer.idx)
{
uint32_t numVertices = state.m_numVertices;
if (UINT32_C(0xffffffff) == numVertices)
@ -1848,34 +1848,45 @@ namespace bgfx
numVertices = vb.m_size/vertexDecl.m_decl.m_stride;
}
uint32_t numIndices;
uint32_t numIndices = 0;
uint32_t numPrims = 0;
if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
if (bgfx::invalidHandle != state.m_indexBuffer.idx)
{
numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
numPrims = numIndices/primNumVerts;
if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
{
numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
numPrims = numIndices/primNumVerts;
DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(primType
DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(primType
, state.m_startVertex
, 0
, numVertices
, 0
, numPrims
) );
}
else if (primNumVerts <= state.m_numIndices)
{
numIndices = state.m_numIndices;
numPrims = numIndices/primNumVerts;
}
else if (primNumVerts <= state.m_numIndices)
{
numIndices = state.m_numIndices;
numPrims = numIndices/primNumVerts;
DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(primType
DX_CHECK(s_renderCtx.m_device->DrawIndexedPrimitive(primType
, state.m_startVertex
, 0
, numVertices
, state.m_startIndex
, numPrims
) );
}
}
else
{
numPrims = numVertices/primNumVerts;
DX_CHECK(s_renderCtx.m_device->DrawPrimitive(primType
, state.m_startVertex
, numPrims
) );
}
statsNumPrims += numPrims;

View File

@ -5,7 +5,7 @@
#include "bgfx_p.h"
#if BGFX_CONFIG_RENDERER_OPENGLES
#if (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL)
# include "renderer_gl.h"
# include <bx/timer.h>
# include <bx/uint32_t.h>
@ -16,6 +16,12 @@
namespace bgfx
{
#if BX_PLATFORM_WINDOWS
#define GL_IMPORT(_proto, _func) _proto _func
#include "glimports.h"
#undef GL_IMPORT
#endif // BX_PLATFORM_WINDOWS
typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
#if BX_PLATFORM_NACL
@ -33,6 +39,7 @@ namespace bgfx
{
RendererContext()
: m_dxtSupport(false)
, m_flip(false)
, m_postSwapBuffers(NULL)
#if BX_PLATFORM_NACL
, m_context(0)
@ -40,8 +47,12 @@ namespace bgfx
, m_instInterface(NULL)
, m_graphicsInterface(NULL)
#elif BX_PLATFORM_WINDOWS
, m_context(NULL)
, m_hdc(NULL)
, m_hglrc(NULL)
#elif BX_PLATFORM_LINUX
, m_context(0)
, m_window(0)
, m_display(NULL)
#endif // BX_PLATFORM_
{
memset(&m_resolution, 0, sizeof(m_resolution) );
@ -57,9 +68,9 @@ namespace bgfx
m_textVideoMem.clear();
m_resolution = _resolution;
#if BX_PLATFORM_NACL
#if BX_PLATFORM_NACL || BX_PLATFORM_LINUX
setRenderContextSize(_resolution.m_width, _resolution.m_height);
#endif // BX_PLATFORM_NACL
#endif // BX_PLATFORM_
}
}
@ -105,7 +116,7 @@ namespace bgfx
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, 0, 0,
24, 0, 0,
PFD_MAIN_PLANE,
0, 0, 0, 0
};
@ -119,25 +130,162 @@ namespace bgfx
result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
BX_CHECK(0 != result, "SetPixelFormat failed!");
m_hglrc = wglCreateContext(m_hdc);
BX_CHECK(NULL != g_hglrc, "wglCreateContext failed!");
result = wglMakeCurrent(m_hdc, m_hglrc);
m_context = wglCreateContext(m_hdc);
BX_CHECK(NULL != m_context, "wglCreateContext failed!");
result = wglMakeCurrent(m_hdc, m_context);
BX_CHECK(0 != result, "wglMakeCurrent failed!");
# define GL_IMPORT(_proto, _func) \
{ \
_func = (_proto)wglGetProcAddress(#_func); \
BGFX_FATAL(NULL != _func, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. wglGetProcAddress %s", #_func); \
}
# include "glimports.h"
# undef GL_IMPORT
}
#elif BX_PLATFORM_LINUX
if (0 == m_display)
{
Display* display = XOpenDisplay(0);
XLockDisplay(display);
BGFX_FATAL(display, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to open X display (0).");
int glxMajor, glxMinor;
if (!glXQueryVersion(display, &glxMajor, &glxMinor))
{
BGFX_FATAL(false, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to query GLX version");
}
BGFX_FATAL((glxMajor == 1 && glxMinor >= 3) || glxMajor > 1, bgfx::Fatal::OPENGL_UnableToCreateContext, "GLX version is not >=1.3 (%d.%d).", glxMajor, glxMinor);
const int glxAttribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
None,
};
// Find suitable config
GLXFBConfig bestconfig;
int nconfigs;
GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), glxAttribs, &nconfigs);
XVisualInfo* visualInfo = 0;
for (int ii = 0; ii < nconfigs; ++ii)
{
visualInfo = glXGetVisualFromFBConfig(display, configs[ii]);
if (visualInfo)
{
// Check if meets min spec
bool validconfig = true;
for (int attridx = 0; attridx < countof(glxAttribs) && glxAttribs[attridx] != None; attridx += 2)
{
int value;
glXGetFBConfigAttrib(display, configs[ii], glxAttribs[attridx], &value);
if (value < glxAttribs[attridx + 1])
{
validconfig = false;
break;
}
}
if (validconfig)
{
bestconfig = configs[ii];
break;
}
}
XFree(visualInfo);
visualInfo = 0;
}
XFree(configs);
BGFX_FATAL(visualInfo, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to find a suitable X11 display configuration.");
// Generate colormaps
XSetWindowAttributes windowAttrs;
windowAttrs.colormap = XCreateColormap(display, RootWindow(display, visualInfo->screen), visualInfo->visual, AllocNone);
windowAttrs.background_pixmap = None;
windowAttrs.border_pixel = 0;
Window window = XCreateWindow(
display
, RootWindow(display, visualInfo->screen)
, 0, 0
, _width, _height, 0, visualInfo->depth
, InputOutput
, visualInfo->visual
, CWBorderPixel|CWColormap
, &windowAttrs
);
BGFX_FATAL(window, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to create X11 window.");
XMapRaised(display, window);
XFlush(display);
XFree(visualInfo);
BX_TRACE("create context");
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
BGFX_FATAL(glXCreateContextAttribsARB, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to get glXCreateContextAttribsARB.");
const int contextArrib[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
None,
};
m_context = glXCreateContextAttribsARB(display, bestconfig, 0, True, contextArrib);
BGFX_FATAL(m_context, bgfx::Fatal::OPENGL_UnableToCreateContext, "Failed to create GLX context.");
glXMakeCurrent(display, window, m_context);
glClearColor(0, 0.5, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glXSwapBuffers(display, window);
m_display = display;
m_window = window;
XUnlockDisplay(display);
}
else
{
XResizeWindow(m_display, m_window, _width, _height);
}
#endif // BX_PLATFORM_
}
m_flip = true;
}
void flip()
{
if (m_flip)
{
#if BX_PLATFORM_NACL
glSetCurrentContextPPAPI(m_context);
m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
glSetCurrentContextPPAPI(m_context);
m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
#elif BX_PLATFORM_WINDOWS
wglMakeCurrent(m_hdc, m_hglrc);
SwapBuffers(m_hdc);
wglMakeCurrent(m_hdc, m_context);
SwapBuffers(m_hdc);
#elif BX_PLATFORM_LINUX
glXSwapBuffers(m_display, m_window);
#endif // BX_PLATFORM_
}
if (NULL != m_postSwapBuffers)
{
@ -150,6 +298,16 @@ namespace bgfx
setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
}
void saveScreenShot(Memory* _mem)
{
#if BGFX_CONFIG_RENDERER_OPENGL
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);
saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data);
g_free(data);
#endif // BGFX_CONFIG_RENDERER_OPENGL
}
IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
@ -165,6 +323,7 @@ namespace bgfx
Resolution m_resolution;
bool m_dxtSupport;
bool m_flip;
PostSwapBuffersFn m_postSwapBuffers;
@ -174,8 +333,12 @@ namespace bgfx
const PPB_Instance* m_instInterface;
const PPB_Graphics3D* m_graphicsInterface;
#elif BX_PLATFORM_WINDOWS
HGLRC m_context;
HDC m_hdc;
HGLRC m_hglrc;
#elif BX_PLATFORM_LINUX
GLXContext m_context;
Window m_window;
Display* m_display;
#endif // BX_PLATFORM_NACL
};
@ -195,7 +358,25 @@ namespace bgfx
{
renderFrame();
}
#endif // BX_PLATFORM_NACL
#elif BX_PLATFORM_LINUX
static void linuxInitDisplay()
{
s_renderCtx.setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
}
bool linuxGetDisplay(Display** _display, Window* _window)
{
if (!s_renderCtx.m_display)
{
return false;
}
*_display = s_renderCtx.m_display;
*_window = s_renderCtx.m_window;
return true;
}
#endif // BX_PLATFORM_
struct Extension
{
@ -212,15 +393,18 @@ namespace bgfx
const char* m_name;
bool m_supported;
bool m_initialize;
};
static Extension s_extension[Extension::Count] =
{
{ "GL_EXT_texture_format_BGRA8888", false },
{ "GL_EXT_texture_compression_dxt1", false },
{ "GL_CHROMIUM_texture_compression_dxt3", false },
{ "GL_CHROMIUM_texture_compression_dxt5", false },
{ "GL_OES_standard_derivatives", false },
// 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_dxt1", false, true },
{ "GL_CHROMIUM_texture_compression_dxt3", false, true },
{ "GL_CHROMIUM_texture_compression_dxt5", false, true },
{ "GL_OES_standard_derivatives", false, true },
};
static const GLenum s_primType[] =
@ -1117,7 +1301,7 @@ namespace bgfx
}
else
{
len = uint32_min(sizeof(name), strlen(pos) );
len = uint32_min(sizeof(name), (uint32_t)strlen(pos) );
}
strncpy(name, pos, len);
@ -1127,7 +1311,8 @@ namespace bgfx
for (uint32_t ii = 0; ii < Extension::Count; ++ii)
{
Extension& extension = s_extension[ii];
if (!extension.m_supported)
if (!extension.m_supported
&& extension.m_initialize)
{
if (0 == strcmp(name, extension.m_name) )
{
@ -1272,7 +1457,7 @@ namespace bgfx
void Context::rendererSaveScreenShot(Memory* _mem)
{
// glReadPixels(0, 0, m_render->m_width, m_render->m_height, GL_RGBA, GL_UNSIGNED_BYTE, temp);
s_renderCtx.saveScreenShot(_mem);
}
void Context::rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size)
@ -1466,6 +1651,7 @@ namespace bgfx
if (BGFX_STATE_ALPHA_TEST & newFlags)
{
GL_CHECK(glEnable(GL_ALPHA_TEST) );
}
else
{
GL_CHECK(glDisable(GL_ALPHA_TEST) );
@ -1744,7 +1930,7 @@ namespace bgfx
}
}
if (bgfx::invalidHandle != state.m_indexBuffer.idx)
if (bgfx::invalidHandle != currentState.m_vertexBuffer.idx)
{
if (baseVertex != state.m_startVertex
|| bindAttribs)
@ -1755,26 +1941,41 @@ namespace bgfx
s_renderCtx.m_materials[materialIdx].bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
}
uint32_t numIndices = state.m_numIndices;
uint32_t numIndices = 0;
uint32_t numPrims = 0;
if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
if (bgfx::invalidHandle != state.m_indexBuffer.idx)
{
numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
numPrims = numIndices/primNumVerts;
if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
{
numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
numPrims = numIndices/primNumVerts;
GL_CHECK(glDrawElements(primType
, s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2
, GL_UNSIGNED_SHORT
, (void*)0
) );
GL_CHECK(glDrawElements(primType
, s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2
, GL_UNSIGNED_SHORT
, (void*)0
) );
}
else if (primNumVerts <= state.m_numIndices)
{
numIndices = state.m_numIndices;
numPrims = numIndices/primNumVerts;
GL_CHECK(glDrawElements(primType
, numIndices
, GL_UNSIGNED_SHORT
, (void*)(uintptr_t)(state.m_startIndex*2)
) );
}
}
else if (primNumVerts <= state.m_numIndices)
else
{
GL_CHECK(glDrawElements(primType
, numIndices
, GL_UNSIGNED_SHORT
, (void*)(uintptr_t)(state.m_startIndex*2)
numPrims = state.m_numVertices/primNumVerts;
GL_CHECK(glDrawArrays(primType
, 0
, state.m_numVertices
) );
}
@ -1789,7 +1990,7 @@ namespace bgfx
elapsed += now;
static int64_t last = now;
double frameTime = now - last;
int64_t frameTime = now - last;
last = now;
if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
@ -1829,6 +2030,26 @@ namespace bgfx
GL_CHECK(glFlush() );
}
#if BX_PLATFORM_WINDOWS
DWORD WINAPI renderThread(LPVOID)
#else
void* renderThread(void*)
#endif // BX_PLATFORM_WINDOWS
{
#if BX_PLATFORM_LINUX
linuxInitDisplay();
#endif // BX_PLATFORM_LINUX
while (!s_exit)
{
renderFrame();
}
s_exit = false;
return 0;
}
}
#endif // BGFX_CONFIG_RENDERER_OPENGLES
#endif // (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL)

View File

@ -16,11 +16,12 @@
# include <GLES2/gl2.h>
#elif BX_PLATFORM_WINDOWS
# include <windows.h>
# define GLEW_STATIC
# include <GL/glew.h>
# include <gl/GL.h>
# include <gl/glext.h>
#elif BX_PLATFORM_LINUX
# include <GL3/gl3.h>
# include <GL/glx.h>
# include <X11/Xlib.h>
#endif // BX_PLATFORM_
#ifndef GL_BGRA_EXT
@ -62,8 +63,14 @@ namespace bgfx
#else
# define GL_CHECK(_call) _call
#endif // BGFX_CONFIG_DEBUG
#if BX_PLATFORM_WINDOWS
#define GL_IMPORT(_proto, _func) extern _proto _func
#include "glimports.h"
#undef GL_IMPORT
#endif // BX_PLATFORM_WINDOWS
struct ConstantBuffer;
class ConstantBuffer;
struct IndexBuffer
{

View File

@ -157,6 +157,21 @@ public:
m_file = NULL;
}
void writef(const char* _format, ...)
{
if (NULL != m_file)
{
va_list argList;
va_start(argList, _format);
char temp[2048];
int len = vsnprintf(temp, sizeof(temp), _format, argList);
fwrite(temp, len, 1, m_file);
va_end(argList);
}
}
void write(const char* _str)
{
if (NULL != m_file)
@ -212,7 +227,19 @@ bool compileGLSLShader(CommandLine& _cmdLine, const std::string& _code, const ch
}
Stream stream(out);
stream.write("precision highp float;\n\n");
const char* profile = _cmdLine.findOption('p');
if (NULL == profile)
{
stream.write("#ifdef GL_ES\n");
stream.write("precision highp float;\n");
stream.write("#endif // GL_ES\n\n");
}
else
{
stream.writef("#version %s\n\n", profile);
}
stream.write(optimizedShader, strlen(optimizedShader) );
uint8_t nul = 0;
stream.write(nul);
@ -534,6 +561,16 @@ struct Preprocessor
uint32_t m_fgetsPos;
};
// OpenGL #version Features Direct3D Features Shader Model
// 2.1 120 vf 9.0 vf 2.0
// 3.0 130
// 3.1 140
// 3.2 150 vgf
// 3.3 330 10.0 vgf 4.0
// 4.0 400 vhdgf
// 4.1 410
// 4.2 420 11.0 vhdgf 5.0
int main(int _argc, const char* _argv[])
{
CommandLine cmdLine(_argc, _argv);
@ -574,6 +611,7 @@ int main(int _argc, const char* _argv[])
preprocessor.setDefaultDefine("BX_PLATFORM_NACL");
preprocessor.setDefaultDefine("BX_PLATFORM_WINDOWS");
preprocessor.setDefaultDefine("BX_PLATFORM_XBOX360");
preprocessor.setDefaultDefine("BX_PLATFORM_LINUX");
preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_GLSL");
preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_HLSL");
preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_FRAGMENT");
@ -593,6 +631,12 @@ int main(int _argc, const char* _argv[])
preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
glsl = true;
}
else if (0 == _stricmp(platform, "linux"))
{
preprocessor.setDefine("BX_PLATFORM_LINUX=1");
preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
glsl = true;
}
else if (0 == _stricmp(platform, "windows") )
{
preprocessor.setDefine("BX_PLATFORM_WINDOWS=1");
@ -641,7 +685,17 @@ int main(int _argc, const char* _argv[])
Stream stream(out);
if (glsl)
{
stream.write("precision highp float;\n\n");
const char* profile = cmdLine.findOption('p');
if (NULL == profile)
{
stream.write("#ifdef GL_ES\n");
stream.write("precision highp float;\n");
stream.write("#endif // GL_ES\n\n");
}
else
{
stream.writef("#version %s\n\n", profile);
}
}
stream.write(preprocessor.m_preprocessed.c_str(), preprocessor.m_preprocessed.size() );
stream.close();