bullet3/examples/OpenGLWindow/GwenOpenGL3CoreRenderer.h
erwincoumans ab8f16961e Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
2018-09-23 14:17:31 -07:00

373 lines
9.1 KiB
C++

#ifndef __GWEN_OPENGL3_CORE_RENDERER_H
#define __GWEN_OPENGL3_CORE_RENDERER_H
#include "Gwen/Gwen.h"
#include "Gwen/BaseRender.h"
#include "GLPrimitiveRenderer.h"
#include "../OpenGLWindow/OpenGLInclude.h"
struct sth_stash;
#include "fontstash.h"
#include "Gwen/Texture.h"
#include "TwFonts.h"
static float extraSpacing = 0.; //6f;
#include <assert.h>
#include <math.h>
template <class T>
inline void MyClamp(T& a, const T& lb, const T& ub)
{
if (a < lb)
{
a = lb;
}
else if (ub < a)
{
a = ub;
}
}
static GLuint BindFont(const CTexFont* _Font)
{
GLuint TexID = 0;
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_2D, TexID);
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, _Font->m_TexBytes);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
return TexID;
}
struct MyTextureLoader
{
virtual ~MyTextureLoader()
{
}
virtual void LoadTexture(Gwen::Texture* pTexture) = 0;
virtual void FreeTexture(Gwen::Texture* pTexture) = 0;
};
class GwenOpenGL3CoreRenderer : public Gwen::Renderer::Base
{
GLPrimitiveRenderer* m_primitiveRenderer;
float m_currentColor[4];
float m_yOffset;
sth_stash* m_font;
float m_screenWidth;
float m_screenHeight;
float m_fontScaling;
float m_retinaScale;
bool m_useTrueTypeFont;
const CTexFont* m_currentFont;
GLuint m_fontTextureId;
MyTextureLoader* m_textureLoader;
public:
GwenOpenGL3CoreRenderer(GLPrimitiveRenderer* primRender, sth_stash* font, float screenWidth, float screenHeight, float retinaScale, MyTextureLoader* loader = 0)
: m_primitiveRenderer(primRender),
m_font(font),
m_screenWidth(screenWidth),
m_screenHeight(screenHeight),
m_retinaScale(retinaScale),
m_useTrueTypeFont(false),
m_textureLoader(loader)
{
///only enable true type fonts on Macbook Retina, it looks gorgeous
if (retinaScale == 2.0f)
{
m_useTrueTypeFont = true;
}
m_currentColor[0] = 1;
m_currentColor[1] = 1;
m_currentColor[2] = 1;
m_currentColor[3] = 1;
m_fontScaling = 16.f * m_retinaScale;
TwGenerateDefaultFonts();
m_currentFont = g_DefaultNormalFont;
//m_currentFont = g_DefaultNormalFontAA;
//m_currentFont = g_DefaultLargeFont;
m_fontTextureId = BindFont(m_currentFont);
}
virtual ~GwenOpenGL3CoreRenderer()
{
TwDeleteDefaultFonts();
}
virtual void Resize(int width, int height)
{
m_screenWidth = width;
m_screenHeight = height;
}
virtual void Begin()
{
m_yOffset = 0;
glEnable(GL_BLEND);
assert(glGetError() == GL_NO_ERROR);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
assert(glGetError() == GL_NO_ERROR);
assert(glGetError() == GL_NO_ERROR);
glDisable(GL_DEPTH_TEST);
assert(glGetError() == GL_NO_ERROR);
//glColor4ub(255,0,0,255);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// saveOpenGLState(width,height);//m_glutScreenWidth,m_glutScreenHeight);
assert(glGetError() == GL_NO_ERROR);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
assert(glGetError() == GL_NO_ERROR);
glEnable(GL_BLEND);
assert(glGetError() == GL_NO_ERROR);
}
virtual void End()
{
glDisable(GL_BLEND);
}
virtual void StartClip()
{
if (m_useTrueTypeFont)
sth_flush_draw(m_font);
Gwen::Rect rect = ClipRegion();
// OpenGL's coords are from the bottom left
// so we need to translate them here.
{
GLint view[4];
glGetIntegerv(GL_VIEWPORT, &view[0]);
rect.y = view[3] / m_retinaScale - (rect.y + rect.h);
}
glScissor(m_retinaScale * rect.x * Scale(), m_retinaScale * rect.y * Scale(), m_retinaScale * rect.w * Scale(), m_retinaScale * rect.h * Scale());
glEnable(GL_SCISSOR_TEST);
//glDisable( GL_SCISSOR_TEST );
};
virtual void EndClip()
{
if (m_useTrueTypeFont)
sth_flush_draw(m_font);
glDisable(GL_SCISSOR_TEST);
};
virtual void SetDrawColor(Gwen::Color color)
{
m_currentColor[0] = color.r / 256.f;
m_currentColor[1] = color.g / 256.f;
m_currentColor[2] = color.b / 256.f;
m_currentColor[3] = color.a / 256.f;
}
virtual void DrawFilledRect(Gwen::Rect rect)
{
// BT_PROFILE("GWEN_DrawFilledRect");
Translate(rect);
m_primitiveRenderer->drawRect(rect.x, rect.y + m_yOffset,
rect.x + rect.w, rect.y + rect.h + m_yOffset, m_currentColor);
// m_primitiveRenderer->drawTexturedRect2a(rect.x, rect.y+m_yOffset,
// rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor,0,0,1,1);
// m_yOffset+=rect.h+10;
}
void RenderText(Gwen::Font* pFont, Gwen::Point rasterPos, const Gwen::UnicodeString& text)
{
// BT_PROFILE("GWEN_RenderText");
Gwen::String str = Gwen::Utility::UnicodeToString(text);
const char* unicodeText = (const char*)str.c_str();
Gwen::Rect r;
r.x = rasterPos.x;
r.y = rasterPos.y;
r.w = 0;
r.h = 0;
//
//printf("str = %s\n",unicodeText);
//int xpos=0;
//int ypos=0;
float dx;
int measureOnly = 0;
if (m_useTrueTypeFont)
{
float yoffset = 0.f;
if (m_retinaScale == 2.0f)
{
yoffset = -12;
}
Translate(r);
sth_draw_text(m_font,
1, m_fontScaling,
r.x, r.y + yoffset,
unicodeText, &dx, m_screenWidth, m_screenHeight, measureOnly, m_retinaScale);
}
else
{
//float width = 0.f;
int pos = 0;
//float color[]={0.2f,0.2,0.2f,1.f};
glBindTexture(GL_TEXTURE_2D, m_fontTextureId);
float width = r.x;
while (unicodeText[pos])
{
int c = unicodeText[pos];
r.h = m_currentFont->m_CharHeight;
r.w = m_currentFont->m_CharWidth[c] + extraSpacing;
Gwen::Rect rect = r;
Translate(rect);
m_primitiveRenderer->drawTexturedRect2(rect.x, rect.y + m_yOffset, rect.x + rect.w, rect.y + rect.h + m_yOffset, m_currentColor, m_currentFont->m_CharU0[c], m_currentFont->m_CharV0[c], m_currentFont->m_CharU1[c], m_currentFont->m_CharV1[c]);
width += r.w;
r.x = width;
pos++;
}
{
m_primitiveRenderer->drawTexturedRect3D2Text(false);
}
glBindTexture(GL_TEXTURE_2D, 0);
}
}
Gwen::Point MeasureText(Gwen::Font* pFont, const Gwen::UnicodeString& text)
{
// BT_PROFILE("GWEN_MeasureText");
Gwen::String str = Gwen::Utility::UnicodeToString(text);
const char* unicodeText = (const char*)str.c_str();
// printf("str = %s\n",unicodeText);
int xpos = 0;
int ypos = 0;
int measureOnly = 1;
float dx = 0;
if (m_useTrueTypeFont)
{
sth_draw_text(m_font,
1, m_fontScaling,
xpos, ypos,
unicodeText, &dx, m_screenWidth, m_screenHeight, measureOnly);
Gwen::Point pt;
if (m_retinaScale == 2.0f)
{
pt.x = dx * Scale() / 2.f;
pt.y = m_fontScaling / 2 * Scale() + 1;
}
else
{
pt.x = dx * Scale();
pt.y = m_fontScaling * Scale() + 1;
}
return pt;
}
else
{
float width = 0.f;
int pos = 0;
while (unicodeText[pos])
{
width += m_currentFont->m_CharWidth[(int)unicodeText[pos]] + extraSpacing;
pos++;
}
Gwen::Point pt;
int fontHeight = m_currentFont->m_CharHeight;
pt.x = width * Scale();
pt.y = (fontHeight + 2) * Scale();
return pt;
}
return Gwen::Renderer::Base::MeasureText(pFont, text);
}
virtual void LoadTexture(Gwen::Texture* pTexture)
{
if (m_textureLoader)
m_textureLoader->LoadTexture(pTexture);
}
virtual void FreeTexture(Gwen::Texture* pTexture)
{
if (m_textureLoader)
m_textureLoader->FreeTexture(pTexture);
}
virtual void DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect rect, float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f)
{
// BT_PROFILE("DrawTexturedRect");
Translate(rect);
//float eraseColor[4] = {0,0,0,0};
//m_primitiveRenderer->drawRect(rect.x, rect.y+m_yOffset, rect.x+rect.w, rect.y+rect.h+m_yOffset, eraseColor);
GLint texHandle = (GLint)pTexture->m_intData;
//if (!texHandle)
// return;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texHandle);
// glDisable(GL_DEPTH_TEST);
assert(glGetError() == GL_NO_ERROR);
/* bool useFiltering = true;
if (useFiltering)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
*/
//glEnable(GL_TEXTURE_2D);
// glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
static float add = 0.0;
//add+=1./512.;//0.01;
float color[4] = {1, 1, 1, 1};
m_primitiveRenderer->drawTexturedRect(rect.x, rect.y + m_yOffset, rect.x + rect.w, rect.y + rect.h + m_yOffset, color, 0 + add, 0, 1 + add, 1, true);
assert(glGetError() == GL_NO_ERROR);
}
};
#endif //__GWEN_OPENGL3_CORE_RENDERER_H