Cocoa Port: Improve the handling of HUD font rendering for OpenGL display views running on old drivers.
This commit is contained in:
parent
6e26980d87
commit
180df28ce7
|
@ -90,6 +90,7 @@ void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperti
|
|||
_scaleFactor = 1.0;
|
||||
|
||||
_hudObjectScale = 1.0;
|
||||
_isHUDRenderMipmapped = false;
|
||||
_isHUDVisible = false;
|
||||
_showExecutionSpeed = false;
|
||||
_showVideoFPS = true;
|
||||
|
@ -566,6 +567,17 @@ void ClientDisplayPresenter::SetHUDObjectScale(float objectScale)
|
|||
this->_hudObjectScale = objectScale;
|
||||
}
|
||||
|
||||
|
||||
bool ClientDisplayPresenter::WillHUDRenderMipmapped() const
|
||||
{
|
||||
return this->_isHUDRenderMipmapped;
|
||||
}
|
||||
|
||||
void ClientDisplayPresenter::SetHUDRenderMipmapped(const bool mipmapState)
|
||||
{
|
||||
this->_isHUDRenderMipmapped = mipmapState;
|
||||
}
|
||||
|
||||
bool ClientDisplayPresenter::GetHUDVisibility() const
|
||||
{
|
||||
return this->_isHUDVisible;
|
||||
|
|
|
@ -154,6 +154,7 @@ protected:
|
|||
double _scaleFactor;
|
||||
|
||||
double _hudObjectScale;
|
||||
bool _isHUDRenderMipmapped;
|
||||
bool _isHUDVisible;
|
||||
bool _showExecutionSpeed;
|
||||
bool _showVideoFPS;
|
||||
|
@ -260,6 +261,8 @@ public:
|
|||
float GetHUDObjectScale() const;
|
||||
virtual void SetHUDObjectScale(float objectScale);
|
||||
|
||||
bool WillHUDRenderMipmapped() const;
|
||||
void SetHUDRenderMipmapped(const bool mipmapState);
|
||||
bool GetHUDVisibility() const;
|
||||
virtual void SetHUDVisibility(const bool visibleState);
|
||||
bool GetHUDShowExecutionSpeed() const;
|
||||
|
|
|
@ -37,7 +37,7 @@ static const char *HUDOutputVertShader_100 = {"\
|
|||
uniform bool renderFlipped; \n\
|
||||
\n\
|
||||
VARYING vec4 vtxColor; \n\
|
||||
VARYING vec2 texCoord[1]; \n\
|
||||
VARYING vec2 texCoord; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
|
@ -53,7 +53,7 @@ static const char *HUDOutputVertShader_100 = {"\
|
|||
vec2( 0.0, scalar)); \n\
|
||||
\n\
|
||||
vtxColor = inColor; \n\
|
||||
texCoord[0] = inTexCoord0; \n\
|
||||
texCoord = inTexCoord0; \n\
|
||||
gl_Position = vec4(projection * rotation * scale * inPosition, 0.0, 1.0);\n\
|
||||
\n\
|
||||
if (renderFlipped)\n\
|
||||
|
@ -66,12 +66,12 @@ static const char *HUDOutputVertShader_100 = {"\
|
|||
// FRAGMENT SHADER FOR HUD OUTPUT
|
||||
static const char *HUDOutputFragShader_110 = {"\
|
||||
VARYING vec4 vtxColor;\n\
|
||||
VARYING vec2 texCoord[1];\n\
|
||||
VARYING vec2 texCoord;\n\
|
||||
uniform sampler2D tex;\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
OUT_FRAG_COLOR = SAMPLE4_TEX_2D(tex, texCoord[0]) * vtxColor;\n\
|
||||
OUT_FRAG_COLOR = SAMPLE4_TEX_2D(tex, texCoord) * vtxColor;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
||||
|
@ -5076,25 +5076,7 @@ void OGLVideoOutput::Init()
|
|||
(*this->_layerList)[i]->SetVisibility(wasPreviouslyVisibleList[i]);
|
||||
}
|
||||
|
||||
// Render State Setup (common to both shaders and fixed-function pipeline)
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_DITHER);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||
|
||||
// Set up fixed-function pipeline render states.
|
||||
if (!this->_contextInfo->IsShaderSupported())
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_FOG);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
}
|
||||
|
||||
// Set up clear attributes
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
this->PrerenderStateSetupOGL();
|
||||
|
||||
// Set up textures
|
||||
glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, this->_vfMasterDstBufferSize, this->_vfMasterDstBuffer);
|
||||
|
@ -5218,6 +5200,36 @@ void OGLVideoOutput::CopyFrameToBuffer(uint32_t *dstBuffer)
|
|||
this->_needUpdateViewport = true;
|
||||
}
|
||||
|
||||
void OGLVideoOutput::PrerenderStateSetupOGL()
|
||||
{
|
||||
// If the context is managed by us, then setting all of OpenGL's states
|
||||
// once at initialization time should be enough.
|
||||
//
|
||||
// But if the context is managed by a third party, then this method can
|
||||
// be manually called before rendering the video output if necessary.
|
||||
//
|
||||
// The most notable state here is enabling blending, which HUD rendering
|
||||
// requires.
|
||||
|
||||
// Render State Setup (common to both shaders and fixed-function pipeline)
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_DITHER);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
// Set up fixed-function pipeline render states.
|
||||
if (!this->_contextInfo->IsShaderSupported())
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_FOG);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
}
|
||||
}
|
||||
|
||||
void OGLVideoOutput::RenderFrameOGL(bool isRenderingFlipped)
|
||||
{
|
||||
if (this->_needUpdateViewport)
|
||||
|
@ -6274,6 +6286,9 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
|
|||
_uniformScalar = glGetUniformLocation(_program->GetProgramID(), "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(_program->GetProgramID(), "viewSize");
|
||||
_uniformRenderFlipped = glGetUniformLocation(_program->GetProgramID(), "renderFlipped");
|
||||
|
||||
GLint uniformTexSampler = glGetUniformLocation(_program->GetProgramID(), "tex");
|
||||
glUniform1i(uniformTexSampler, 0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
@ -6370,26 +6385,35 @@ OGLHUDLayer::~OGLHUDLayer()
|
|||
void OGLHUDLayer::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo)
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
std::vector<uint32_t *> workingBufferList;
|
||||
workingBufferList.reserve(16);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_texCharMap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
GLint texLevel = 0;
|
||||
for (size_t tileSize = glyphTileSize, gSize = glyphSize; tileSize >= 4; texLevel++, tileSize >>= 1, gSize = (GLfloat)tileSize * 0.75f)
|
||||
for (size_t tileSize = glyphTileSize, texSize = glyphTileSize * 16, gSize = glyphSize; texSize >= 1; texLevel++, tileSize >>= 1, texSize >>= 1, gSize = (GLfloat)tileSize * 0.75f)
|
||||
{
|
||||
const size_t charMapBufferPixCount = (16 * tileSize) * (16 * tileSize);
|
||||
|
||||
const size_t charMapBufferPixCount = texSize * texSize;
|
||||
const uint32_t fontColor = 0x00FFFFFF;
|
||||
|
||||
// Allocate a working buffer for FreeType to draw in. We then need to add
|
||||
// it to a list so that we can deallocate the working buffer after OpenGL
|
||||
// has copied the buffer to its associated texture.
|
||||
uint32_t *charMapBuffer = (uint32_t *)malloc(charMapBufferPixCount * 2 * sizeof(uint32_t));
|
||||
workingBufferList.push_back(charMapBuffer);
|
||||
for (size_t i = 0; i < charMapBufferPixCount; i++)
|
||||
{
|
||||
charMapBuffer[i] = fontColor;
|
||||
}
|
||||
|
||||
if (tileSize == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
error = FT_Set_Char_Size(fontFace, gSize << 6, gSize << 6, 72, 72);
|
||||
if (error)
|
||||
{
|
||||
|
@ -6404,7 +6428,7 @@ void OGLHUDLayer::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, c
|
|||
for (size_t pixIndex = 0; pixIndex < tileSize; pixIndex++)
|
||||
{
|
||||
const uint32_t colorRGBA8888 = 0xFFFFFFFF;
|
||||
charMapBuffer[(tileSize + pixIndex) + (rowIndex * (16 * tileSize))] = colorRGBA8888;
|
||||
charMapBuffer[(tileSize + pixIndex) + (rowIndex * texSize)] = colorRGBA8888;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6420,7 +6444,6 @@ void OGLHUDLayer::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, c
|
|||
const uint16_t tileOffsetX = (c & 0x0F) * tileSize;
|
||||
const uint16_t tileOffsetY = (c >> 4) * tileSize;
|
||||
const uint16_t tileOffsetY_texture = tileOffsetY - (tileSize - gSize + (gSize / 16));
|
||||
const uint16_t texSize = tileSize * 16;
|
||||
const GLuint glyphWidth = glyphSlot->bitmap.width;
|
||||
|
||||
if (tileSize == glyphTileSize)
|
||||
|
@ -6444,12 +6467,19 @@ void OGLHUDLayer::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, c
|
|||
}
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, texLevel, GL_RGBA, 16 * tileSize, 16 * tileSize, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, charMapBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, texLevel, GL_RGBA, texSize, texSize, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, charMapBuffer);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, texLevel - 1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Synchronize here, then free all previously allocated working buffers.
|
||||
glFinish();
|
||||
for (size_t i = 0; i < workingBufferList.size(); i++)
|
||||
{
|
||||
free(workingBufferList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void OGLHUDLayer::_UpdateVerticesOGL()
|
||||
|
@ -6551,19 +6581,19 @@ void OGLHUDLayer::RenderOGL(bool isRenderingFlipped)
|
|||
// First, draw the inputs.
|
||||
if (this->_output->GetHUDShowInput())
|
||||
{
|
||||
const ClientDisplayPresenterProperties &cdv = this->_output->GetPresenterProperties();
|
||||
const ClientDisplayPresenterProperties &cdp = this->_output->GetPresenterProperties();
|
||||
|
||||
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||
{
|
||||
glUniform1f(this->_uniformAngleDegrees, cdv.rotation);
|
||||
glUniform1f(this->_uniformScalar, cdv.viewScale);
|
||||
glUniform1f(this->_uniformAngleDegrees, cdp.rotation);
|
||||
glUniform1f(this->_uniformScalar, cdp.viewScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glRotatef(cdv.rotation, 0.0f, 0.0f, 1.0f);
|
||||
glScalef(cdv.viewScale, cdv.viewScale, 1.0f);
|
||||
glRotatef(cdp.rotation, 0.0f, 0.0f, 1.0f);
|
||||
glScalef(cdp.viewScale, cdp.viewScale, 1.0f);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
@ -6616,7 +6646,15 @@ void OGLHUDLayer::RenderOGL(bool isRenderingFlipped)
|
|||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
if (this->_output->WillHUDRenderMipmapped())
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.50f);
|
||||
}
|
||||
|
@ -6696,6 +6734,9 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
|
|||
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
_uniformRenderFlipped = glGetUniformLocation(finalOutputProgramID, "renderFlipped");
|
||||
_uniformBacklightIntensity = glGetUniformLocation(finalOutputProgramID, "backlightIntensity");
|
||||
|
||||
GLint uniformTexSampler = glGetUniformLocation(finalOutputProgramID, "tex");
|
||||
glUniform1i(uniformTexSampler, 0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -455,6 +455,7 @@ public:
|
|||
// Client view interface
|
||||
virtual void ProcessDisplays();
|
||||
virtual void CopyFrameToBuffer(uint32_t *dstBuffer);
|
||||
virtual void PrerenderStateSetupOGL();
|
||||
virtual void RenderFrameOGL(bool isRenderingFlipped);
|
||||
|
||||
virtual const OGLProcessedFrameInfo& GetProcessedFrameInfo();
|
||||
|
|
|
@ -1296,6 +1296,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
|
||||
NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"SourceSansPro-Bold" ofType:@"otf"];
|
||||
cdv->Get3DPresenter()->SetHUDFontPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
cdv->Get3DPresenter()->SetHUDRenderMipmapped(true);
|
||||
|
||||
if (scaleFactor != 1.0f)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue