From a429bf3ab94a8bbc2dd67daabcd093194c8b2d74 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 1 Nov 2014 17:14:23 +0000 Subject: [PATCH] OpenGL in-app text overlay --- renderdoc/data/glsl/debuguniforms.h | 10 + renderdoc/data/glsl/text.frag | 50 ++++ renderdoc/data/glsl/text.vert | 64 +++++ renderdoc/data/renderdoc.rc | 2 + renderdoc/data/resource.h | 2 + renderdoc/driver/d3d11/d3d11_debug.cpp | 2 +- renderdoc/driver/gl/gl_driver.cpp | 330 ++++++++++++++++++++++++- renderdoc/driver/gl/gl_driver.h | 31 +++ renderdoc/renderdoc.vcxproj | 6 +- renderdoc/renderdoc.vcxproj.filters | 6 + 10 files changed, 495 insertions(+), 8 deletions(-) create mode 100644 renderdoc/data/glsl/text.frag create mode 100644 renderdoc/data/glsl/text.vert diff --git a/renderdoc/data/glsl/debuguniforms.h b/renderdoc/data/glsl/debuguniforms.h index d25c95326..7d61fd059 100644 --- a/renderdoc/data/glsl/debuguniforms.h +++ b/renderdoc/data/glsl/debuguniforms.h @@ -62,6 +62,16 @@ BINDING(0) uniform texdisplay float Slice; }; +BINDING(0) uniform FontUniforms +{ + vec2 TextPosition; + float txtpadding; + float TextSize; + + vec2 CharacterSize; + vec2 FontScreenAspect; +}; + // some constants available to both C++ and GLSL for configuring display #define CUBEMAP_FACE_POS_X 0 #define CUBEMAP_FACE_NEG_X 1 diff --git a/renderdoc/data/glsl/text.frag b/renderdoc/data/glsl/text.frag new file mode 100644 index 000000000..600365835 --- /dev/null +++ b/renderdoc/data/glsl/text.frag @@ -0,0 +1,50 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2014 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#version 420 core + +layout (binding = 0) uniform sampler2D tex0; +layout (location = 0) out vec4 color_out; + +in v2f +{ + vec4 tex; + vec2 glyphuv; +} IN; + +void main(void) +{ + float text = 0; + + if(IN.glyphuv.x >= 0.0f && IN.glyphuv.x <= 1.0f && + IN.glyphuv.y >= 0.0f && IN.glyphuv.y <= 1.0f) + { + vec2 uv; + uv.x = mix(IN.tex.x, IN.tex.z, IN.glyphuv.x); + uv.y = mix(IN.tex.y, IN.tex.w, IN.glyphuv.y); + text = texture2D(tex0, uv.xy).x; + } + + color_out = vec4(text.xxx, clamp(text + 0.5f, 0.0f, 1.0f)); +} diff --git a/renderdoc/data/glsl/text.vert b/renderdoc/data/glsl/text.vert new file mode 100644 index 000000000..073c16151 --- /dev/null +++ b/renderdoc/data/glsl/text.vert @@ -0,0 +1,64 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2014 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +struct glyph +{ + vec4 posdata; + vec4 uvdata; +}; + +layout (binding = 1, std140) uniform glyphdata +{ + glyph glyphs[127-32]; +}; + +layout (binding = 2, std140) uniform stringdata +{ + uvec4 str[256]; +}; + +out v2f +{ + vec4 tex; + vec2 glyphuv; +} OUT; + +void main(void) +{ + const vec3 verts[4] = vec3[4](vec3( 0.0, 0.0, 0.5), + vec3( 1.0, 0.0, 0.5), + vec3( 0.0, 1.0, 0.5), + vec3( 1.0, 1.0, 0.5)); + + vec3 pos = verts[gl_VertexID]; + uint strindex = gl_InstanceID; + + vec2 charPos = vec2(strindex + pos.x + TextPosition.x, -pos.y - TextPosition.y); + + glyph G = glyphs[str[strindex].x]; + + gl_Position = vec4(charPos.xy*2.0f*TextSize*FontScreenAspect.xy + vec2(-1, 1), 1, 1); + OUT.glyphuv.xy = (pos.xy - G.posdata.xy) * G.posdata.zw; + OUT.tex = G.uvdata * CharacterSize.xyxy; +} diff --git a/renderdoc/data/renderdoc.rc b/renderdoc/data/renderdoc.rc index c683aa9f3..fc74dea7f 100644 --- a/renderdoc/data/renderdoc.rc +++ b/renderdoc/data/renderdoc.rc @@ -117,6 +117,8 @@ RESOURCE_generic_vert TYPE_EMBED "glsl/generic.vert" RESOURCE_generic_frag TYPE_EMBED "glsl/generic.frag" RESOURCE_mesh_vert TYPE_EMBED "glsl/mesh.vert" RESOURCE_debuguniforms_h TYPE_EMBED "glsl/debuguniforms.h" +RESOURCE_text_vert TYPE_EMBED "glsl/text.vert" +RESOURCE_text_frag TYPE_EMBED "glsl/text.frag" RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf" diff --git a/renderdoc/data/resource.h b/renderdoc/data/resource.h index 0033b58d1..df9622ad2 100644 --- a/renderdoc/data/resource.h +++ b/renderdoc/data/resource.h @@ -19,6 +19,8 @@ #define RESOURCE_generic_frag 206 #define RESOURCE_mesh_vert 207 #define RESOURCE_debuguniforms_h 208 +#define RESOURCE_text_vert 209 +#define RESOURCE_text_frag 210 #define RESOURCE_sourcecodepro_ttf 301 diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index d1e034e32..70eca4994 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -37,7 +37,7 @@ #include "d3d11_renderstate.h" -#include "3rdparty/stb/stb_truetype.h" +#include "stb/stb_truetype.h" #include diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index b27fa3d68..d7e1ef5d6 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -33,6 +33,9 @@ #include "maths/vec.h" #include "jpeg-compressor/jpge.h" +#include "stb/stb_truetype.h" + +#include "data/glsl/debuguniforms.h" const char *GLChunkNames[] = { @@ -500,6 +503,23 @@ void *WrappedOpenGL::GetCtx() void WrappedOpenGL::DeleteContext(void *contextHandle) { + FontData &font = m_Fonts[contextHandle]; + + if(font.built && font.ready) + { + if(font.Program) + m_Real.glDeleteProgram(font.Program); + if(font.GeneralUBO) + m_Real.glDeleteBuffers(1, &font.GeneralUBO); + if(font.GlyphUBO) + m_Real.glDeleteBuffers(1, &font.GlyphUBO); + if(font.StringUBO) + m_Real.glDeleteBuffers(1, &font.StringUBO); + if(font.GlyphTexture) + m_Real.glDeleteTextures(1, &font.GlyphTexture); + } + + m_Fonts.erase(contextHandle); } void WrappedOpenGL::CreateContext(void *windowHandle, void *contextHandle, void *shareContext, GLInitParams initParams) @@ -513,6 +533,139 @@ void WrappedOpenGL::ActivateContext(void *windowHandle, void *contextHandle) m_ActiveContexts[Threading::GetCurrentID()] = contextHandle; // TODO: support multiple GL contexts more explicitly Keyboard::AddInputWindow(windowHandle); + + if(contextHandle) + { + FontData &font = m_Fonts[contextHandle]; + + if(!font.built) + { + font.built = true; + + const GLHookSet &gl = m_Real; + + if(gl.glGenTextures && gl.glTextureStorage2DEXT && gl.glTextureSubImage2DEXT && + gl.glGenVertexArrays && gl.glBindVertexArray && + gl.glGenBuffers && gl.glNamedBufferStorageEXT && + gl.glCreateShader && gl.glShaderSource && gl.glCompileShader && gl.glGetShaderiv && gl.glGetShaderInfoLog && gl.glDeleteShader && + gl.glCreateProgram && gl.glAttachShader && gl.glLinkProgram && gl.glGetProgramiv && gl.glGetProgramInfoLog) + { + gl.glGenTextures(1, &font.GlyphTexture); + gl.glTextureStorage2DEXT(font.GlyphTexture, eGL_TEXTURE_2D, 1, eGL_R8, FONT_TEX_WIDTH, FONT_TEX_HEIGHT); + + GLuint curvao = 0; + gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); + + gl.glGenVertexArrays(1, &font.DummyVAO); + gl.glBindVertexArray(font.DummyVAO); + + string ttfstring = GetEmbeddedResource(sourcecodepro_ttf); + byte *ttfdata = (byte *)ttfstring.c_str(); + + const int firstChar = int(' ') + 1; + const int lastChar = 127; + const int numChars = lastChar-firstChar; + + byte *buf = new byte[FONT_TEX_WIDTH * FONT_TEX_HEIGHT]; + + const float pixelHeight = 20.0f; + + stbtt_bakedchar chardata[numChars]; + int ret = stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, firstChar, numChars, chardata); + + font.CharSize = pixelHeight; + font.CharAspect = chardata->xadvance / pixelHeight; + + stbtt_fontinfo f = {0}; + stbtt_InitFont(&f, ttfdata, 0); + + int ascent = 0; + stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); + + float maxheight = float(ascent)*stbtt_ScaleForPixelHeight(&f, pixelHeight); + + gl.glTextureSubImage2DEXT(font.GlyphTexture, eGL_TEXTURE_2D, 0, 0, 0, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, + eGL_RED, eGL_UNSIGNED_BYTE, (void *)buf); + + delete[] buf; + + Vec4f glyphData[2*(numChars+1)]; + + for(int i=0; i < numChars; i++) + { + stbtt_bakedchar *b = chardata+i; + + float x = b->xoff; + float y = b->yoff + maxheight; + + glyphData[(i+1)*2 + 0] = Vec4f(x/b->xadvance, y/pixelHeight, b->xadvance/float(b->x1 - b->x0), pixelHeight/float(b->y1 - b->y0)); + glyphData[(i+1)*2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); + } + + gl.glGenBuffers(1, &font.GlyphUBO); + gl.glNamedBufferStorageEXT(font.GlyphUBO, sizeof(glyphData), glyphData, 0); + + gl.glGenBuffers(1, &font.GeneralUBO); + gl.glNamedBufferStorageEXT(font.GeneralUBO, sizeof(FontUniforms), NULL, GL_MAP_WRITE_BIT); + + gl.glGenBuffers(1, &font.StringUBO); + gl.glNamedBufferStorageEXT(font.StringUBO, sizeof(uint32_t)*4*FONT_MAX_CHARS, NULL, GL_MAP_WRITE_BIT); + + string textvs = GetEmbeddedResource(debuguniforms_h); + textvs += GetEmbeddedResource(text_vert); + string textfs = GetEmbeddedResource(text_frag); + + GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); + GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + + const char *src = textvs.c_str(); + gl.glShaderSource(vs, 1, &src, NULL); + src = textfs.c_str(); + gl.glShaderSource(fs, 1, &src, NULL); + + gl.glCompileShader(vs); + gl.glCompileShader(fs); + + char buffer[1024] = {0}; + GLint status = 0; + + gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); + RDCERR("Shader error: %hs", buffer); + } + + gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); + RDCERR("Shader error: %hs", buffer); + } + + font.Program = gl.glCreateProgram(); + + gl.glAttachShader(font.Program, vs); + gl.glAttachShader(font.Program, fs); + + gl.glLinkProgram(font.Program); + + gl.glGetProgramiv(font.Program, eGL_LINK_STATUS, &status); + if(status == 0) + { + gl.glGetProgramInfoLog(font.Program, 1024, NULL, buffer); + RDCERR("Link error: %hs", buffer); + } + + gl.glDeleteShader(vs); + gl.glDeleteShader(fs); + + font.ready = true; + + gl.glBindVertexArray(curvao); + } + } + } } void WrappedOpenGL::WindowSize(void *windowHandle, uint32_t w, uint32_t h) @@ -522,6 +675,108 @@ void WrappedOpenGL::WindowSize(void *windowHandle, uint32_t w, uint32_t h) m_InitParams.height = h; } +void WrappedOpenGL::RenderOverlayText(float x, float y, const char *fmt, ...) +{ + static char tmpBuf[4096]; + + va_list args; + va_start(args, fmt); + StringFormat::vsnprintf( tmpBuf, 4095, fmt, args ); + tmpBuf[4095] = '\0'; + va_end(args); + + RenderOverlayStr(x, y, tmpBuf); +} + +void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) +{ + if(char *t = strchr((char *)text, '\n')) + { + *t = 0; + RenderOverlayStr(x, y, text); + RenderOverlayStr(x, y+1.0f, t+1); + *t = '\n'; + return; + } + + if(strlen(text) == 0) + return; + + const GLHookSet &gl = m_Real; + + RDCASSERT(strlen(text) < FONT_MAX_CHARS); + + FontData &font = m_Fonts[GetCtx()]; + + if(!font.built || !font.ready) return; + + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.GeneralUBO); + + FontUniforms *ubo = (FontUniforms *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(FontUniforms), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + ubo->TextPosition.x = x; + ubo->TextPosition.y = y; + + ubo->FontScreenAspect.x = 1.0f/float(m_InitParams.width); + ubo->FontScreenAspect.y = 1.0f/float(m_InitParams.height); + + ubo->TextSize = font.CharSize; + ubo->FontScreenAspect.x *= font.CharAspect; + + ubo->CharacterSize.x = 1.0f/float(FONT_TEX_WIDTH); + ubo->CharacterSize.y = 1.0f/float(FONT_TEX_HEIGHT); + + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + + size_t len = strlen(text); + + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.StringUBO); + uint32_t *texs = (uint32_t *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, len*4*sizeof(uint32_t), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + + for(size_t i=0; i < len; i++) + { + texs[i*4+0] = text[i] - ' '; + texs[i*4+1] = text[i] - ' '; + texs[i*4+2] = text[i] - ' '; + texs[i*4+3] = text[i] - ' '; + } + + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + + // set blend state + gl.glEnable(eGL_BLEND); + gl.glBlendFuncSeparatei(0, eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA, eGL_SRC_ALPHA, eGL_SRC_ALPHA); + gl.glBlendEquationSeparatei(0, eGL_FUNC_ADD, eGL_FUNC_ADD); + + // set depth & stencil + gl.glDisable(eGL_DEPTH_TEST); + gl.glDisable(eGL_DEPTH_CLAMP); + gl.glDisable(eGL_STENCIL_TEST); + gl.glDisable(eGL_CULL_FACE); + + // set viewport & scissor + gl.glViewportIndexedf(0, 0.0f, 0.0f, (float)m_InitParams.width, (float)m_InitParams.height); + gl.glDisablei(eGL_SCISSOR_TEST, 0); + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + + // bind UBOs + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.GeneralUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, font.GlyphUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, font.StringUBO); + + // bind empty VAO just for valid rendering + gl.glBindVertexArray(font.DummyVAO); + + // bind textures + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D, font.GlyphTexture); + + // bind program + gl.glUseProgram(font.Program); + + // draw string + gl.glDrawArraysInstanced(eGL_TRIANGLE_STRIP, 0, 4, (GLsizei)len); +} + void WrappedOpenGL::Present(void *windowHandle) { RenderDoc::Inst().SetCurrentDriver(RDC_OpenGL); @@ -558,14 +813,78 @@ void WrappedOpenGL::Present(void *windowHandle) m_AvgFrametime /= double(m_FrameTimes.size()); m_FrameTimes.clear(); + } + + uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); + + if((overlay & eOverlay_Enabled) && m_Real.glGetIntegerv && m_Real.glReadBuffer && m_Real.glBindFramebuffer && m_Real.glBindBuffer && m_Real.glReadPixels) + { + RDCLOG("Doing GL overlay"); + + GLRenderState old(&m_Real, m_pSerialiser, m_State); + + old.FetchState(); + + // TODO: handle selecting active window amongst many + { + vector keys = RenderDoc::Inst().GetCaptureKeys(); + + string overlayText = ""; + + for(size_t i=0; i < keys.size(); i++) + { + if(i > 0) + overlayText += ", "; + + overlayText += ToStr::Get(keys[i]); + } + + if(!keys.empty()) + overlayText += " to capture."; + + if(overlay & eOverlay_FrameNumber) + { + if(!overlayText.empty()) overlayText += " "; + overlayText += StringFormat::Fmt("Frame: %d.", m_FrameCounter); + } + if(overlay & eOverlay_FrameRate) + { + if(!overlayText.empty()) overlayText += " "; + overlayText += StringFormat::Fmt("%.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", + m_AvgFrametime, m_MinFrametime, m_MaxFrametime, 1000.0f/m_AvgFrametime); + } + + float y=0.0f; + + if(!overlayText.empty()) + { + RenderOverlayText(0.0f, y, overlayText.c_str()); + y += 1.0f; + } + + if(overlay & eOverlay_CaptureList) + { + RenderOverlayText(0.0f, y, "%d Captures saved.\n", (uint32_t)m_FrameRecord.size()); + y += 1.0f; + + uint64_t now = Timing::GetUnixTimestamp(); + for(size_t i=0; i < m_FrameRecord.size(); i++) + { + if(now - m_FrameRecord[i].frameInfo.captureTime < 20) + { + RenderOverlayText(0.0f, y, "Captured frame %d.\n", m_FrameRecord[i].frameInfo.frameNumber); + y += 1.0f; + } + } + } - RDCLOG("Frame: %d. F12/PrtScr to capture. %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", - m_FrameCounter, m_AvgFrametime, m_MinFrametime, m_MaxFrametime, 1000.0f/m_AvgFrametime); - for(size_t i=0; i < m_FrameRecord.size(); i++) - RDCLOG("Captured Frame %d. Multiple frame capture not supported.\n", m_FrameRecord[i].frameInfo.frameNumber); #if !defined(RELEASE) - RDCLOG("%llu chunks - %.2f MB", Chunk::NumLiveChunks(), float(Chunk::TotalMem())/1024.0f/1024.0f); + RenderOverlayText(0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), float(Chunk::TotalMem())/1024.0f/1024.0f); + y += 1.0f; #endif + } + + old.ApplyState(); } } @@ -731,6 +1050,7 @@ void WrappedOpenGL::Present(void *windowHandle) FetchFrameRecord record; record.frameInfo.frameNumber = m_FrameCounter+1; + record.frameInfo.captureTime = Timing::GetUnixTimestamp(); m_FrameRecord.push_back(record); GetResourceManager()->ClearReferencedResources(); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 36ab2ec9a..b2441d293 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -253,6 +253,37 @@ class WrappedOpenGL void BeginCaptureFrame(); void FinishCapture(); void EndCaptureFrame(); + + struct FontData + { + FontData() + : built(false), ready(false), + Program(0), + GeneralUBO(0), StringUBO(0), GlyphUBO(0), + GlyphTexture(0), + DummyVAO(0) + {} + + bool built; + bool ready; + + GLuint Program; + GLuint GeneralUBO, StringUBO, GlyphUBO; + GLuint GlyphTexture; + GLuint DummyVAO; + + float CharSize; + float CharAspect; + }; + + map m_Fonts; + + static const int FONT_TEX_WIDTH = 256; + static const int FONT_TEX_HEIGHT = 128; + static const int FONT_MAX_CHARS = 256; + + void RenderOverlayText(float x, float y, const char *fmt, ...); + void RenderOverlayStr(float x, float y, const char *str); vector glExts; string glExtsString; diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 6f5eb9063..6ca150aca 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -303,13 +303,13 @@ - + - + @@ -378,6 +378,8 @@ + + diff --git a/renderdoc/renderdoc.vcxproj.filters b/renderdoc/renderdoc.vcxproj.filters index de2499724..e190f6878 100644 --- a/renderdoc/renderdoc.vcxproj.filters +++ b/renderdoc/renderdoc.vcxproj.filters @@ -559,6 +559,12 @@ Resources\glsl + + Resources\glsl + + + Resources\glsl +