Added LogVisor

This commit is contained in:
Jack Andersen 2015-10-29 20:26:02 -10:00
parent 2814da014f
commit b73ecde4aa
12 changed files with 277 additions and 81 deletions

3
.gitmodules vendored
View File

@ -0,0 +1,3 @@
[submodule "LogVisor"]
path = LogVisor
url = https://github.com/AxioDL/LogVisor.git

View File

@ -5,6 +5,12 @@ if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
endif() endif()
if (NOT TARGET LogVisor)
add_subdirectory(LogVisor)
set(LOG_VISOR_INCLUDE_DIR LogVisor/include)
endif()
include_directories(include ${LOG_VISOR_INCLUDE_DIR})
if(WIN32) if(WIN32)
list(APPEND PLAT_SRCS list(APPEND PLAT_SRCS
lib/win/ApplicationWin32.cpp lib/win/ApplicationWin32.cpp

1
LogVisor Submodule

@ -0,0 +1 @@
Subproject commit 189e047977b138b711259ad84d94471f5d006ffb

View File

@ -5,6 +5,8 @@
namespace boo namespace boo
{ {
struct IGraphicsCommandQueue;
struct IGraphicsDataFactory;
class IWindowCallback class IWindowCallback
{ {
@ -147,6 +149,12 @@ public:
}; };
virtual ETouchType getTouchType() const=0; virtual ETouchType getTouchType() const=0;
virtual IGraphicsCommandQueue* getCommandQueue()=0;
virtual IGraphicsDataFactory* getDataFactory()=0;
/* Creates a new context on current thread!! Call from client loading thread */
virtual IGraphicsDataFactory* getLoadContextDataFactory()=0;
}; };
} }

View File

@ -5,6 +5,11 @@
namespace boo namespace boo
{ {
enum Primitive
{
PrimitiveTriangles,
PrimitiveTriStrips
};
struct IGraphicsCommandQueue struct IGraphicsCommandQueue
{ {
@ -20,11 +25,6 @@ struct IGraphicsCommandQueue
virtual void setClearColor(const float rgba[4])=0; virtual void setClearColor(const float rgba[4])=0;
virtual void clearTarget(bool render=true, bool depth=true)=0; virtual void clearTarget(bool render=true, bool depth=true)=0;
enum Primitive
{
PrimitiveTriangles,
TrimitiveTriStrips
};
virtual void setDrawPrimitive(Primitive prim)=0; virtual void setDrawPrimitive(Primitive prim)=0;
virtual void draw(size_t start, size_t count)=0; virtual void draw(size_t start, size_t count)=0;
virtual void drawIndexed(size_t start, size_t count)=0; virtual void drawIndexed(size_t start, size_t count)=0;

View File

@ -35,6 +35,15 @@ protected:
IGraphicsBufferD() : IGraphicsBuffer(true) {} IGraphicsBufferD() : IGraphicsBuffer(true) {}
}; };
/** Supported buffer uses */
enum BufferUse
{
BufferUseNull,
BufferUseVertex,
BufferUseIndex,
BufferUseUniform
};
struct ITexture struct ITexture
{ {
bool dynamic() const {return m_dynamic;} bool dynamic() const {return m_dynamic;}
@ -61,11 +70,37 @@ protected:
ITextureD() : ITexture(true) {} ITextureD() : ITexture(true) {}
}; };
/** Supported texture formats */
enum TextureFormat
{
TextureFormatRGBA8,
TextureFormatDXT1,
TextureFormatPVRTC4
};
/** Opaque token for representing the data layout of a vertex /** Opaque token for representing the data layout of a vertex
* in a VBO. Also able to reference buffers for platforms like * in a VBO. Also able to reference buffers for platforms like
* OpenGL that cache object refs */ * OpenGL that cache object refs */
struct IVertexFormat {}; struct IVertexFormat {};
/** Types of vertex attributes */
enum VertexSemantic
{
VertexSemanticPosition,
VertexSemanticNormal,
VertexSemanticColor,
VertexSemanticUV,
VertexSemanticWeight
};
/** Used to create IVertexFormat */
struct VertexElementDescriptor
{
const IGraphicsBuffer* vertBuffer = nullptr;
const IGraphicsBuffer* indexBuffer = nullptr;
VertexSemantic semantic;
};
/** Opaque token for referencing a complete graphics pipeline state necessary /** Opaque token for referencing a complete graphics pipeline state necessary
* to rasterize geometry (shaders and blending modes mainly) */ * to rasterize geometry (shaders and blending modes mainly) */
struct IShaderPipeline {}; struct IShaderPipeline {};
@ -83,6 +118,21 @@ struct IGraphicsData
virtual ~IGraphicsData() {} virtual ~IGraphicsData() {}
}; };
/** Used by platform shader pipeline constructors */
enum BlendFactor
{
BlendFactorZero,
BlendFactorOne,
BlendFactorSrcColor,
BlendFactorInvSrcColor,
BlendFactorDstColor,
BlendFactorInvDstColor,
BlendFactorSrcAlpha,
BlendFactorInvSrcAlpha,
BlendFactorDstAlpha,
BlendFactorInvDstAlpha
};
/** Factory object for creating batches of resources as an IGraphicsData token */ /** Factory object for creating batches of resources as an IGraphicsData token */
struct IGraphicsDataFactory struct IGraphicsDataFactory
{ {
@ -101,60 +151,20 @@ struct IGraphicsDataFactory
virtual Platform platform() const=0; virtual Platform platform() const=0;
virtual const char* platformName() const=0; virtual const char* platformName() const=0;
enum BufferUse
{
BufferUseNull,
BufferUseVertex,
BufferUseIndex,
BufferUseUniform
};
virtual const IGraphicsBufferS* virtual const IGraphicsBufferS*
newStaticBuffer(BufferUse use, const void* data, size_t sz)=0; newStaticBuffer(BufferUse use, const void* data, size_t sz)=0;
virtual IGraphicsBufferD* virtual IGraphicsBufferD*
newDynamicBuffer(BufferUse use)=0; newDynamicBuffer(BufferUse use)=0;
enum TextureFormat
{
TextureFormatRGBA8,
TextureFormatDXT1,
TextureFormatPVRTC4
};
virtual const ITextureS* virtual const ITextureS*
newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt, newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
const void* data, size_t sz)=0; const void* data, size_t sz)=0;
virtual ITextureD* virtual ITextureD*
newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0; newDynamicTexture(size_t width, size_t height, TextureFormat fmt)=0;
struct VertexElementDescriptor
{
const IGraphicsBuffer* vertBuffer = nullptr;
const IGraphicsBuffer* indexBuffer = nullptr;
enum VertexSemantic
{
VertexSemanticPosition,
VertexSemanticNormal,
VertexSemanticColor,
VertexSemanticUV,
VertexSemanticWeight
} semantic;
};
virtual const IVertexFormat* virtual const IVertexFormat*
newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0; newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements)=0;
enum BlendFactor
{
BlendFactorZero,
BlendFactorOne,
BlendFactorSrcColor,
BlendFactorInvSrcColor,
BlendFactorDstColor,
BlendFactorInvDstColor,
BlendFactorSrcAlpha,
BlendFactorInvSrcAlpha,
BlendFactorDstAlpha,
BlendFactorInvDstAlpha
};
virtual const IShaderDataBinding* virtual const IShaderDataBinding*
newShaderDataBinding(const IShaderPipeline* pipeline, newShaderDataBinding(const IShaderPipeline* pipeline,
const IVertexFormat* vtxFormat, const IVertexFormat* vtxFormat,

View File

@ -1,14 +1,16 @@
#include "boo/graphicsdev/GLES3.hpp" #include "boo/graphicsdev/GLES3.hpp"
#include "boo/IGraphicsContext.hpp" #include "boo/IGraphicsContext.hpp"
#include <GLES3/gl3ext.h> #include <GLES3/gl3ext.h>
#include <stdio.h>
#include <vector> #include <vector>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <LogVisor/LogVisor.hpp>
namespace boo namespace boo
{ {
static LogVisor::LogModule Log("boo::GLES3");
struct GLES3Data : IGraphicsData struct GLES3Data : IGraphicsData
{ {
@ -35,7 +37,7 @@ class GLES3GraphicsBufferS : IGraphicsBufferS
friend struct GLES3CommandQueue; friend struct GLES3CommandQueue;
GLuint m_buf; GLuint m_buf;
GLenum m_target; GLenum m_target;
GLES3GraphicsBufferS(IGraphicsDataFactory::BufferUse use, const void* data, size_t sz) GLES3GraphicsBufferS(BufferUse use, const void* data, size_t sz)
{ {
m_target = USE_TABLE[use]; m_target = USE_TABLE[use];
glGenBuffers(1, &m_buf); glGenBuffers(1, &m_buf);
@ -62,7 +64,7 @@ class GLES3GraphicsBufferD : IGraphicsBufferD
GLenum m_target; GLenum m_target;
void* m_mappedBuf = nullptr; void* m_mappedBuf = nullptr;
size_t m_mappedSize = 0; size_t m_mappedSize = 0;
GLES3GraphicsBufferD(GLES3CommandQueue* q, IGraphicsDataFactory::BufferUse use) GLES3GraphicsBufferD(GLES3CommandQueue* q, BufferUse use)
: m_q(q) : m_q(q)
{ {
m_target = USE_TABLE[use]; m_target = USE_TABLE[use];
@ -93,13 +95,12 @@ class GLES3TextureS : ITextureS
friend class GLES3DataFactory; friend class GLES3DataFactory;
GLuint m_tex; GLuint m_tex;
GLES3TextureS(size_t width, size_t height, size_t mips, GLES3TextureS(size_t width, size_t height, size_t mips,
IGraphicsDataFactory::TextureFormat fmt, TextureFormat fmt, const void* data, size_t sz)
const void* data, size_t sz)
{ {
const uint8_t* dataIt = static_cast<const uint8_t*>(data); const uint8_t* dataIt = static_cast<const uint8_t*>(data);
glGenTextures(1, &m_tex); glGenTextures(1, &m_tex);
glBindTexture(GL_TEXTURE_2D, m_tex); glBindTexture(GL_TEXTURE_2D, m_tex);
if (fmt == IGraphicsDataFactory::TextureFormatRGBA8) if (fmt == TextureFormatRGBA8)
{ {
for (size_t i=0 ; i<mips ; ++i) for (size_t i=0 ; i<mips ; ++i)
{ {
@ -131,8 +132,7 @@ class GLES3TextureD : ITextureD
size_t m_mappedSize = 0; size_t m_mappedSize = 0;
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
GLES3TextureD(GLES3CommandQueue* q, size_t width, size_t height, GLES3TextureD(GLES3CommandQueue* q, size_t width, size_t height, TextureFormat fmt);
IGraphicsDataFactory::TextureFormat fmt);
public: public:
~GLES3TextureD(); ~GLES3TextureD();
@ -281,7 +281,7 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
GLES3ShaderPipeline shader; GLES3ShaderPipeline shader;
if (!shader.initObjects()) if (!shader.initObjects())
{ {
fprintf(stderr, "unable to create shader objects\n"); Log.report(LogVisor::Error, "unable to create shader objects\n");
return nullptr; return nullptr;
} }
shader.m_sfactor = BLEND_FACTOR_TABLE[srcFac]; shader.m_sfactor = BLEND_FACTOR_TABLE[srcFac];
@ -300,7 +300,7 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
glGetShaderiv(shader.m_vert, GL_INFO_LOG_LENGTH, &logLen); glGetShaderiv(shader.m_vert, GL_INFO_LOG_LENGTH, &logLen);
char* log = (char*)malloc(logLen); char* log = (char*)malloc(logLen);
glGetShaderInfoLog(shader.m_vert, logLen, nullptr, log); glGetShaderInfoLog(shader.m_vert, logLen, nullptr, log);
fprintf(stderr, "unable to compile vert source\n%s\n%s\n", log, vertSource); Log.report(LogVisor::Error, "unable to compile vert source\n%s\n%s\n", log, vertSource);
free(log); free(log);
return nullptr; return nullptr;
} }
@ -314,7 +314,7 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
glGetShaderiv(shader.m_frag, GL_INFO_LOG_LENGTH, &logLen); glGetShaderiv(shader.m_frag, GL_INFO_LOG_LENGTH, &logLen);
char* log = (char*)malloc(logLen); char* log = (char*)malloc(logLen);
glGetShaderInfoLog(shader.m_frag, logLen, nullptr, log); glGetShaderInfoLog(shader.m_frag, logLen, nullptr, log);
fprintf(stderr, "unable to compile frag source\n%s\n%s\n", log, fragSource); Log.report(LogVisor::Error, "unable to compile frag source\n%s\n%s\n", log, fragSource);
free(log); free(log);
return nullptr; return nullptr;
} }
@ -327,7 +327,7 @@ const IShaderPipeline* GLES3DataFactory::newShaderPipeline
glGetProgramiv(shader.m_prog, GL_INFO_LOG_LENGTH, &logLen); glGetProgramiv(shader.m_prog, GL_INFO_LOG_LENGTH, &logLen);
char* log = (char*)malloc(logLen); char* log = (char*)malloc(logLen);
glGetProgramInfoLog(shader.m_prog, logLen, nullptr, log); glGetProgramInfoLog(shader.m_prog, logLen, nullptr, log);
fprintf(stderr, "unable to link shader program\n%s\n", log); Log.report(LogVisor::Error, "unable to link shader program\n%s\n", log);
free(log); free(log);
return nullptr; return nullptr;
} }
@ -342,9 +342,9 @@ struct GLES3VertexFormat : IVertexFormat
GLES3CommandQueue* m_q; GLES3CommandQueue* m_q;
GLuint m_vao = 0; GLuint m_vao = 0;
size_t m_elementCount; size_t m_elementCount;
std::unique_ptr<GLES3DataFactory::VertexElementDescriptor[]> m_elements; std::unique_ptr<VertexElementDescriptor[]> m_elements;
GLES3VertexFormat(GLES3CommandQueue* q, size_t elementCount, GLES3VertexFormat(GLES3CommandQueue* q, size_t elementCount,
const GLES3DataFactory::VertexElementDescriptor* elements); const VertexElementDescriptor* elements);
~GLES3VertexFormat(); ~GLES3VertexFormat();
void bind() const {glBindVertexArray(m_vao);} void bind() const {glBindVertexArray(m_vao);}
}; };
@ -468,7 +468,7 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
const ITextureD* target; const ITextureD* target;
float rgba[4]; float rgba[4];
GLbitfield flags; GLbitfield flags;
Primitive prim; GLenum prim;
struct struct
{ {
size_t start; size_t start;
@ -500,7 +500,7 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
size_t stride = 0; size_t stride = 0;
for (size_t i=0 ; i<fmt->m_elementCount ; ++i) for (size_t i=0 ; i<fmt->m_elementCount ; ++i)
{ {
const IGraphicsDataFactory::VertexElementDescriptor* desc = &fmt->m_elements[i]; const VertexElementDescriptor* desc = &fmt->m_elements[i];
stride += SEMANTIC_SIZE_TABLE[desc->semantic]; stride += SEMANTIC_SIZE_TABLE[desc->semantic];
} }
@ -510,7 +510,7 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
const IGraphicsBuffer* lastEBO = nullptr; const IGraphicsBuffer* lastEBO = nullptr;
for (size_t i=0 ; i<fmt->m_elementCount ; ++i) for (size_t i=0 ; i<fmt->m_elementCount ; ++i)
{ {
const IGraphicsDataFactory::VertexElementDescriptor* desc = &fmt->m_elements[i]; const VertexElementDescriptor* desc = &fmt->m_elements[i];
if (desc->vertBuffer != lastVBO) if (desc->vertBuffer != lastVBO)
{ {
lastVBO = desc->vertBuffer; lastVBO = desc->vertBuffer;
@ -589,10 +589,7 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
glClear(cmd.flags); glClear(cmd.flags);
break; break;
case Command::OpSetDrawPrimitive: case Command::OpSetDrawPrimitive:
if (cmd.prim == PrimitiveTriangles) prim = cmd.prim;
prim = GL_TRIANGLES;
else if (cmd.prim == TrimitiveTriStrips)
prim = GL_TRIANGLE_STRIP;
break; break;
case Command::OpDraw: case Command::OpDraw:
glDrawArrays(prim, cmd.start, cmd.count); glDrawArrays(prim, cmd.start, cmd.count);
@ -661,7 +658,10 @@ struct GLES3CommandQueue : IGraphicsCommandQueue
{ {
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf]; std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
cmds.emplace_back(Command::OpSetDrawPrimitive); cmds.emplace_back(Command::OpSetDrawPrimitive);
cmds.back().prim = prim; if (prim == PrimitiveTriangles)
cmds.back().prim = GL_TRIANGLES;
else if (prim == PrimitiveTriStrips)
cmds.back().prim = GL_TRIANGLE_STRIP;
} }
void draw(size_t start, size_t count) void draw(size_t start, size_t count)
{ {
@ -772,8 +772,7 @@ GLES3DataFactory::newDynamicBuffer(BufferUse use)
return retval; return retval;
} }
GLES3TextureD::GLES3TextureD(GLES3CommandQueue* q, size_t width, size_t height, GLES3TextureD::GLES3TextureD(GLES3CommandQueue* q, size_t width, size_t height, TextureFormat fmt)
IGraphicsDataFactory::TextureFormat fmt)
: m_q(q) : m_q(q)
{ {
m_width = width; m_width = width;
@ -797,10 +796,10 @@ GLES3DataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat f
} }
GLES3VertexFormat::GLES3VertexFormat(GLES3CommandQueue* q, size_t elementCount, GLES3VertexFormat::GLES3VertexFormat(GLES3CommandQueue* q, size_t elementCount,
const GLES3DataFactory::VertexElementDescriptor* elements) const VertexElementDescriptor* elements)
: m_q(q), : m_q(q),
m_elementCount(elementCount), m_elementCount(elementCount),
m_elements(new GLES3DataFactory::VertexElementDescriptor[elementCount]) m_elements(new VertexElementDescriptor[elementCount])
{ {
for (size_t i=0 ; i<elementCount ; ++i) for (size_t i=0 ; i<elementCount ; ++i)
m_elements[i] = elements[i]; m_elements[i] = elements[i];

View File

@ -123,7 +123,8 @@ static xcb_window_t GetWindowOfEvent(xcb_generic_event_t* event, bool& windowEve
return 0; return 0;
} }
IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn); IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn,
xcb_glx_context_t lastCtx);
class ApplicationXCB final : public IApplication class ApplicationXCB final : public IApplication
{ {
@ -341,10 +342,18 @@ public:
std::unique_ptr<IWindow> newWindow(const std::string& title) std::unique_ptr<IWindow> newWindow(const std::string& title)
{ {
IWindow* newWindow = _WindowXCBNew(title, m_xcbConn); IWindow* newWindow = _WindowXCBNew(title, m_xcbConn, m_lastGlxCtx);
m_windows[(xcb_window_t)newWindow->getPlatformHandle()] = newWindow; m_windows[(xcb_window_t)newWindow->getPlatformHandle()] = newWindow;
return std::unique_ptr<IWindow>(newWindow); return std::unique_ptr<IWindow>(newWindow);
} }
/* Last GLX context */
xcb_glx_context_t m_lastGlxCtx = 0;
}; };
void _XCBUpdateLastGlxCtx(xcb_glx_context_t lastGlxCtx)
{
static_cast<ApplicationXCB*>(APP)->m_lastGlxCtx = lastGlxCtx;
}
} }

View File

@ -63,11 +63,29 @@ public:
{ {
} }
IGraphicsCommandQueue* getCommandQueue()
{
return nullptr;
}
IGraphicsDataFactory* getDataFactory()
{
return nullptr;
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return nullptr;
}
}; };
struct WindowWayland : IWindow struct WindowWayland : IWindow
{ {
GraphicsContextWayland m_gfxCtx;
WindowWayland(const std::string& title) WindowWayland(const std::string& title)
: m_gfxCtx(IGraphicsContext::API_OPENGL_3_3, this)
{ {
} }
@ -149,6 +167,22 @@ struct WindowWayland : IWindow
} }
IGraphicsCommandQueue* getCommandQueue()
{
return m_gfxCtx.getCommandQueue();
}
IGraphicsDataFactory* getDataFactory()
{
return m_gfxCtx.getDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_gfxCtx.getLoadContextDataFactory();
}
}; };
IWindow* _WindowWaylandNew(const std::string& title) IWindow* _WindowWaylandNew(const std::string& title)

View File

@ -29,6 +29,7 @@
namespace boo namespace boo
{ {
IGraphicsCommandQueue* _NewGLES3CommandQueue(IGraphicsContext* parent); IGraphicsCommandQueue* _NewGLES3CommandQueue(IGraphicsContext* parent);
void _XCBUpdateLastGlxCtx(xcb_glx_context_t lastGlxCtx);
extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI; extern PFNGLXGETVIDEOSYNCSGIPROC FglXGetVideoSyncSGI;
extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI; extern PFNGLXWAITVIDEOSYNCSGIPROC FglXWaitVideoSyncSGI;
@ -161,6 +162,7 @@ struct GraphicsContextXCB : IGraphicsContext
EPixelFormat m_pf; EPixelFormat m_pf;
IWindow* m_parentWindow; IWindow* m_parentWindow;
xcb_connection_t* m_xcbConn; xcb_connection_t* m_xcbConn;
xcb_glx_context_t m_lastCtx = 0;
xcb_glx_fbconfig_t m_fbconfig = 0; xcb_glx_fbconfig_t m_fbconfig = 0;
xcb_visualid_t m_visualid = 0; xcb_visualid_t m_visualid = 0;
@ -289,7 +291,8 @@ public:
m_parentWindow->getPlatformHandle(), m_parentWindow->getPlatformHandle(),
m_glxWindow, 0, NULL); m_glxWindow, 0, NULL);
m_glxCtx = xcb_generate_id(m_xcbConn); m_glxCtx = xcb_generate_id(m_xcbConn);
xcb_glx_create_context(m_xcbConn, m_glxCtx, m_visualid, 0, 0, 1); xcb_glx_create_context(m_xcbConn, m_glxCtx, m_visualid, 0, m_lastCtx, 1);
_XCBUpdateLastGlxCtx(m_glxCtx);
} }
void makeCurrent() void makeCurrent()
@ -357,7 +360,7 @@ struct WindowXCB : IWindow
public: public:
WindowXCB(const std::string& title, xcb_connection_t* conn) WindowXCB(const std::string& title, xcb_connection_t* conn, xcb_glx_context_t lastCtx)
: m_xcbConn(conn), m_callback(NULL), m_gfxCtx(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, m_visualId) : m_xcbConn(conn), m_callback(NULL), m_gfxCtx(IGraphicsContext::API_OPENGL_3_3, this, m_xcbConn, m_visualId)
{ {
if (!S_ATOMS) if (!S_ATOMS)
@ -952,11 +955,27 @@ public:
return m_touchType; return m_touchType;
} }
IGraphicsCommandQueue* getCommandQueue()
{
return m_gfxCtx.getCommandQueue();
}
IGraphicsDataFactory* getDataFactory()
{
return m_gfxCtx.getDataFactory();
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_gfxCtx.getLoadContextDataFactory();
}
}; };
IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn) IWindow* _WindowXCBNew(const std::string& title, xcb_connection_t* conn,
xcb_glx_context_t lastCtx)
{ {
return new WindowXCB(title, conn); return new WindowXCB(title, conn, lastCtx);
} }
} }

View File

@ -1,2 +1,2 @@
add_executable(booTest main.cpp) add_executable(booTest main.cpp)
target_link_libraries(booTest Boo ${BOO_SYS_LIBS}) target_link_libraries(booTest Boo LogVisor ${BOO_SYS_LIBS})

View File

@ -1,5 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <boo/boo.hpp> #include <boo/boo.hpp>
#include <boo/graphicsdev/GLES3.hpp>
#include <thread>
#include <mutex>
#include <condition_variable>
namespace boo namespace boo
{ {
@ -166,13 +170,104 @@ struct CTestWindowCallback : IWindowCallback
}; };
struct TestApplicationCallback : IApplicationCallback struct TestApplicationCallback : IApplicationCallback
{ {
std::unique_ptr<IWindow> mainWindow; std::unique_ptr<IWindow> mainWindow;
boo::TestDeviceFinder devFinder; boo::TestDeviceFinder devFinder;
CTestWindowCallback windowCallback; CTestWindowCallback windowCallback;
bool running = true; bool running = true;
const IShaderDataBinding* m_binding = nullptr;
std::mutex m_mt;
std::condition_variable m_cv;
static void LoaderProc(TestApplicationCallback* self)
{
GLES3DataFactory* factory =
dynamic_cast<GLES3DataFactory*>(self->mainWindow->getLoadContextDataFactory());
/* Make Tri-strip VBO */
struct Vert
{
float pos[3];
float uv[2];
};
static const Vert quad[4] =
{
{{1.0,1.0},{1.0,1.0}},
{{-1.0,1.0},{0.0,1.0}},
{{1.0,-1.0},{1.0,0.0}},
{{-1.0,-1.0},{0.0,0.0}}
};
const IGraphicsBuffer* vbo =
factory->newStaticBuffer(BufferUseVertex, quad, sizeof(quad));
/* Make vertex format */
const VertexElementDescriptor descs[2] =
{
{vbo, nullptr, VertexSemanticPosition},
{vbo, nullptr, VertexSemanticUV}
};
const IVertexFormat* vfmt = factory->newVertexFormat(2, descs);
/* Make ramp texture */
using Pixel = uint8_t[4];
static Pixel tex[256][256];
for (int i=0 ; i<256 ; ++i)
for (int j=0 ; j<256 ; ++j)
{
tex[i][j][0] = i;
tex[i][j][1] = j;
tex[i][j][2] = 0;
tex[i][j][3] = 0xff;
}
const ITexture* texture =
factory->newStaticTexture(256, 256, 1, TextureFormatRGBA8, tex, 256*256*4);
/* Make shader pipeline */
static const char* VS =
"#version 300\n"
"layout(location=0) in vec3 in_pos;\n"
"layout(location=1) in vec2 in_uv;\n"
"out vec2 out_uv;\n"
"void main()\n"
"{\n"
" gl_Position = in_pos;\n"
" out_uv = in_uv;\n"
"}\n";
static const char* FS =
"#version 300\n"
"layout(binding=0) uniform sampler2D tex;\n"
"layout(location=0) out vec4 out_frag;\n"
"in vec2 out_uv;\n"
"void main()\n"
"{\n"
" out_frag = texture(tex, out_uv);\n"
"}\n";
const IShaderPipeline* pipeline =
factory->newShaderPipeline(VS, FS, BlendFactorOne, BlendFactorZero, true, true, false);
/* Make shader data binding */
self->m_binding =
factory->newShaderDataBinding(pipeline, vfmt, vbo, nullptr, 0, nullptr, 1, &texture);
/* Commit objects */
std::unique_ptr<IGraphicsData> data = factory->commit();
/* Wait for exit */
while (self->running)
{
{
std::unique_lock<std::mutex> lk(self->m_mt);
self->m_cv.wait(lk);
if (!self->running)
break;
}
}
}
int appMain(IApplication* app) int appMain(IApplication* app)
{ {
mainWindow = app->newWindow(_S("YAY!")); mainWindow = app->newWindow(_S("YAY!"));
@ -180,13 +275,25 @@ struct TestApplicationCallback : IApplicationCallback
mainWindow->showWindow(); mainWindow->showWindow();
devFinder.startScanning(); devFinder.startScanning();
IGraphicsCommandQueue* gfxQ = mainWindow->getCommandQueue();
std::thread loaderThread(LoaderProc, this);
size_t retraceCount = 0; size_t retraceCount = 0;
while (running) while (running)
{ {
retraceCount = mainWindow->waitForRetrace(retraceCount); retraceCount = mainWindow->waitForRetrace(retraceCount);
if (m_binding)
{
gfxQ->setDrawPrimitive(PrimitiveTriStrips);
gfxQ->clearTarget();
gfxQ->setShaderDataBinding(m_binding);
gfxQ->draw(0, 4);
gfxQ->execute();
}
} }
m_cv.notify_one();
loaderThread.join();
return 0; return 0;
} }
void appQuitting(IApplication*) void appQuitting(IApplication*)