Batch glyph for quicker text rendering
This commit is contained in:
parent
719af8c54b
commit
4d72b118e3
@ -1,11 +1,11 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 col;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture(tex, uv);
|
||||
FragColor = res * col;
|
||||
vec4 res = texture(tex, uv);
|
||||
FragColor = res * color;
|
||||
}
|
||||
|
@ -15,14 +15,14 @@ in vec4 Color;
|
||||
#endif
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 col;
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float s = sin(rotation);
|
||||
float c = cos(rotation);
|
||||
mat2 m = mat2(c, -s, s, c);
|
||||
col = Color.zyxw;
|
||||
color = Color.zyxw;
|
||||
uv = Texcoord * texsize + texcenter;
|
||||
gl_Position = vec4(m * Position * size + center, 0., 1.);
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ out vec4 color;
|
||||
void main(void)
|
||||
{
|
||||
color = Color.zyxw;
|
||||
vec3 P = Position / vec3(fullscreen, 1.);
|
||||
P = 2. * P - 1.;
|
||||
P.y *= -1.;
|
||||
gl_Position = vec4(P, 1.);
|
||||
vec2 point = Position.xy / fullscreen;
|
||||
point = 2.0 * point - 1.0;
|
||||
point.y *= -1.0;
|
||||
gl_Position = vec4(point, 0.0, 1.0);
|
||||
uv = Texcoord;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
254
src/font/font_drawer.cpp
Normal file
254
src/font/font_drawer.cpp
Normal file
@ -0,0 +1,254 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2020 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "font/font_drawer.hpp"
|
||||
#include "graphics/2dutils.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/texture_shader.hpp"
|
||||
|
||||
#include <S3DVertex.h>
|
||||
#include <irrArray.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
// ============================================================================
|
||||
class FontDrawerShader : public TextureShader<FontDrawerShader, 1, core::vector2df>
|
||||
{
|
||||
public:
|
||||
GLuint m_vao, m_vbo, m_ibo;
|
||||
FontDrawerShader()
|
||||
{
|
||||
loadProgram(OBJECT, GL_VERTEX_SHADER, "primitive2dlist.vert",
|
||||
GL_FRAGMENT_SHADER, "colortexturedquad.frag");
|
||||
assignUniforms("fullscreen");
|
||||
assignSamplerNames(0, "tex", ST_BILINEAR_FILTERED);
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glGenBuffers(1, &m_ibo);
|
||||
} // FontDrawerShader
|
||||
~FontDrawerShader()
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
glDeleteBuffers(1, &m_vbo);
|
||||
glDeleteBuffers(1, &m_ibo);
|
||||
}
|
||||
}; //FontDrawerShader
|
||||
|
||||
// ============================================================================
|
||||
std::unique_ptr<core::rect<s32> > g_clip;
|
||||
// ============================================================================
|
||||
std::map<video::ITexture*, std::vector<uint8_t> > g_glyphs;
|
||||
// ----------------------------------------------------------------------------
|
||||
void FontDrawer::addGlyph(video::ITexture* texture,
|
||||
const core::rect<float>& dest_rect,
|
||||
const core::rect<s32>& source_rect,
|
||||
const core::rect<s32>* clip_rect,
|
||||
const video::SColor* color)
|
||||
{
|
||||
if (clip_rect)
|
||||
g_clip.reset(new core::rect<s32>(*clip_rect));
|
||||
else
|
||||
g_clip.reset();
|
||||
const float tex_h = (float)texture->getSize().Height;
|
||||
const float tex_w = (float)texture->getSize().Width;
|
||||
|
||||
if (g_glyphs.find(texture) == g_glyphs.end())
|
||||
texture->grab();
|
||||
|
||||
auto& glyph_data = g_glyphs[texture];
|
||||
size_t stride = sizeof(video::S3DVertex);
|
||||
if (CVS->isGLSL())
|
||||
stride -= 16;
|
||||
size_t old_size = glyph_data.size();
|
||||
glyph_data.resize(old_size + stride * 4);
|
||||
uint8_t* glyph_ptr = &glyph_data[old_size];
|
||||
|
||||
auto copy_glyph = [stride](const video::S3DVertex& v, uint8_t* glyph_ptr)
|
||||
{
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
size_t pos_size = sizeof(float) * 2;
|
||||
memcpy(glyph_ptr, &v.Pos.X, pos_size);
|
||||
memcpy(glyph_ptr + pos_size, &v.Color, stride - pos_size);
|
||||
}
|
||||
else
|
||||
memcpy(glyph_ptr, &v.Pos.X, stride);
|
||||
};
|
||||
|
||||
video::S3DVertex glyph = video::S3DVertex(
|
||||
dest_rect.UpperLeftCorner.X, dest_rect.LowerRightCorner.Y, 0, 0, 0, 0,
|
||||
color[1], source_rect.UpperLeftCorner.X / tex_w,
|
||||
source_rect.LowerRightCorner.Y / tex_h);
|
||||
copy_glyph(glyph, glyph_ptr);
|
||||
glyph = video::S3DVertex(
|
||||
dest_rect.UpperLeftCorner.X, dest_rect.UpperLeftCorner.Y, 0, 0, 0, 0,
|
||||
color[0], source_rect.UpperLeftCorner.X / tex_w,
|
||||
source_rect.UpperLeftCorner.Y / tex_h);
|
||||
copy_glyph(glyph, glyph_ptr + stride);
|
||||
glyph = video::S3DVertex(
|
||||
dest_rect.LowerRightCorner.X, dest_rect.UpperLeftCorner.Y, 0, 0, 0, 0,
|
||||
color[2], source_rect.LowerRightCorner.X / tex_w,
|
||||
source_rect.UpperLeftCorner.Y / tex_h);
|
||||
copy_glyph(glyph, glyph_ptr + stride * 2);
|
||||
glyph = video::S3DVertex(
|
||||
dest_rect.LowerRightCorner.X, dest_rect.LowerRightCorner.Y, 0, 0, 0, 0,
|
||||
color[3], source_rect.LowerRightCorner.X / tex_w,
|
||||
source_rect.LowerRightCorner.Y / tex_h);
|
||||
copy_glyph(glyph, glyph_ptr + stride * 3);
|
||||
} // addGlyph
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void FontDrawer::draw()
|
||||
{
|
||||
if (g_clip && !g_clip->isValid())
|
||||
{
|
||||
for (auto it = g_glyphs.begin(); it != g_glyphs.end();)
|
||||
{
|
||||
it->first->drop();
|
||||
it = g_glyphs.erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
FontDrawerShader::getInstance()->use();
|
||||
FontDrawerShader::getInstance()->setUniforms(
|
||||
core::vector2df(float(irr_driver->getActualScreenSize().Width),
|
||||
float(irr_driver->getActualScreenSize().Height)));
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (g_clip)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& render_target_size =
|
||||
irr_driver->getActualScreenSize();
|
||||
glScissor(g_clip->UpperLeftCorner.X,
|
||||
(s32)render_target_size.Height - g_clip->LowerRightCorner.Y +
|
||||
irr_driver->getDevice()->getMovedHeight(),
|
||||
g_clip->getWidth(), g_clip->getHeight());
|
||||
}
|
||||
else
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
for (auto& glyph : g_glyphs)
|
||||
{
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<uint32_t> indices_32;
|
||||
u32 idx = 0;
|
||||
size_t stride = sizeof(video::S3DVertex);
|
||||
if (CVS->isGLSL())
|
||||
stride -= 16;
|
||||
for (unsigned i = 0; i < glyph.second.size() / stride; i += 4)
|
||||
{
|
||||
if (idx >= 65536)
|
||||
{
|
||||
if (indices_32.empty())
|
||||
{
|
||||
for (auto& index : indices)
|
||||
indices_32.push_back(index);
|
||||
}
|
||||
indices_32.push_back(idx++);
|
||||
indices_32.push_back(idx++);
|
||||
indices_32.push_back(idx++);
|
||||
indices_32.push_back(indices_32[indices_32.size() - 3]);
|
||||
indices_32.push_back(indices_32[indices_32.size() - 2]);
|
||||
indices_32.push_back(idx++);
|
||||
}
|
||||
else
|
||||
{
|
||||
indices.push_back(idx++);
|
||||
indices.push_back(idx++);
|
||||
indices.push_back(idx++);
|
||||
indices.push_back(indices[indices.size() - 3]);
|
||||
indices.push_back(indices[indices.size() - 2]);
|
||||
indices.push_back(idx++);
|
||||
}
|
||||
}
|
||||
void* idx_data = indices_32.empty() ?
|
||||
(void*)indices.data() : (void*)indices_32.data();
|
||||
size_t idx_count = indices_32.empty() ? indices.size() : indices_32.size();
|
||||
size_t idx_size = indices_32.empty() ?
|
||||
idx_count * sizeof(u16) : idx_count * sizeof(u32);
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
// Unfortunately we need to re-define the vao each time otherwise
|
||||
// if texture is changed no glyph is drawn
|
||||
glBindVertexArray(FontDrawerShader::getInstance()->m_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER,
|
||||
FontDrawerShader::getInstance()->m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
glyph.second.size(), glyph.second.data(), GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
||||
FontDrawerShader::getInstance()->m_ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_size, idx_data,
|
||||
GL_STREAM_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, 0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (GLvoid*)8);
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)12);
|
||||
FontDrawerShader::getInstance()->setTextureUnits(
|
||||
glyph.first->getOpenGLTextureName());
|
||||
glDrawElements(GL_TRIANGLES, idx_count,
|
||||
indices_32.empty() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
video::SMaterial m;
|
||||
m.setTexture(0, glyph.first);
|
||||
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
irr_driver->getVideoDriver()->setMaterial(m);
|
||||
irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(
|
||||
glyph.second.data(), glyph.second.size() / stride,
|
||||
idx_data, idx_count / 3, video::EVT_STANDARD,
|
||||
scene::EPT_TRIANGLES,
|
||||
indices_32.empty() ? video::EIT_16BIT : video::EIT_32BIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_clip)
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
g_clip.reset();
|
||||
}
|
||||
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
for (auto it = g_glyphs.begin(); it != g_glyphs.end();)
|
||||
{
|
||||
it->first->drop();
|
||||
it = g_glyphs.erase(it);
|
||||
}
|
||||
} // draw
|
||||
|
||||
#endif
|
56
src/font/font_drawer.hpp
Normal file
56
src/font/font_drawer.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2020 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_FONT_DRAWER_HPP
|
||||
#define HEADER_FONT_DRAWER_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <ITexture.h>
|
||||
#include <rect.h>
|
||||
#include <SColor.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
namespace FontDrawer
|
||||
{
|
||||
// ------------------------------------------------------------------------
|
||||
void addGlyph(video::ITexture* texture,
|
||||
const core::rect<float>& dest_rect,
|
||||
const core::rect<s32>& source_rect,
|
||||
const core::rect<s32>* clip_rect,
|
||||
const video::SColor* color);
|
||||
// ------------------------------------------------------------------------
|
||||
inline void addGlyph(video::ITexture* texture,
|
||||
const core::rect<float>& dest_rect,
|
||||
const core::rect<s32>& source_rect,
|
||||
const core::rect<s32>* clip_rect,
|
||||
const video::SColor& color)
|
||||
{
|
||||
std::array<video::SColor, 4> colors = {{ color, color, color, color }};
|
||||
addGlyph(texture, dest_rect, source_rect, clip_rect, colors.data());
|
||||
} // addGlyph
|
||||
// ------------------------------------------------------------------------
|
||||
void draw();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/face_ttf.hpp"
|
||||
#include "font/font_drawer.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "graphics/2dutils.hpp"
|
||||
@ -880,9 +881,9 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
||||
for (int y_delta = -thickness; y_delta <= thickness; y_delta++)
|
||||
{
|
||||
if (x_delta == 0 || y_delta == 0) continue;
|
||||
draw2DImage(texture, dest + core::position2d<float>
|
||||
FontDrawer::addGlyph(texture, dest + core::position2d<float>
|
||||
(float(x_delta), float(y_delta)), source, clip,
|
||||
border_color, true);
|
||||
border_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -898,11 +899,8 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
||||
top.setAlpha(color.getAlpha());
|
||||
bottom.setAlpha(color.getAlpha());
|
||||
|
||||
std::array<video::SColor, 4> title_colors;
|
||||
if (CVS->isGLSL())
|
||||
title_colors = { { top, bottom, top, bottom } };
|
||||
else
|
||||
title_colors = { { bottom, top, top, bottom } };
|
||||
std::array<video::SColor, 4> title_colors =
|
||||
{ { bottom, top , bottom, top } };
|
||||
|
||||
video::SColor text_marked = GUIEngine::getSkin()->getColor(
|
||||
"text_field::background_marked");
|
||||
@ -946,8 +944,8 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
||||
}
|
||||
else
|
||||
{
|
||||
draw2DImage(texture, dest, source, clip,
|
||||
is_colored ? white.data() : title_colors.data(), true);
|
||||
FontDrawer::addGlyph(texture, dest, source, clip,
|
||||
is_colored ? white.data() : title_colors.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -961,11 +959,13 @@ void FontWithFace::render(const std::vector<gui::GlyphLayout>& gl,
|
||||
}
|
||||
else
|
||||
{
|
||||
draw2DImage(texture, dest, source, clip,
|
||||
is_colored ? video::SColor(-1) : color, true);
|
||||
FontDrawer::addGlyph(texture, dest, source, clip,
|
||||
is_colored ? video::SColor(-1) : color);
|
||||
}
|
||||
}
|
||||
}
|
||||
FontDrawer::draw();
|
||||
|
||||
for (unsigned i = 0; i < gld_offsets.size(); i += 2)
|
||||
{
|
||||
if (df_used == gui::GLD_MARKED)
|
||||
|
@ -243,49 +243,6 @@ static void getSize(unsigned texture_width, unsigned texture_height,
|
||||
sourceRect.LowerRightCorner.Y * invH);
|
||||
} // getSize
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static void getSize(unsigned texture_width, unsigned texture_height,
|
||||
bool textureisRTT, const core::rect<float>& destRect,
|
||||
const core::rect<s32>& sourceRect,
|
||||
float &width, float &height,
|
||||
float ¢er_pos_x, float ¢er_pos_y,
|
||||
float &tex_width, float &tex_height,
|
||||
float &tex_center_pos_x, float &tex_center_pos_y )
|
||||
{
|
||||
core::dimension2d<u32> frame_size = irr_driver->getActualScreenSize();
|
||||
const int screen_w = frame_size.Width;
|
||||
const int screen_h = frame_size.Height;
|
||||
center_pos_x = destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X;
|
||||
center_pos_x /= screen_w;
|
||||
center_pos_x -= 1.;
|
||||
center_pos_y = destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y;
|
||||
center_pos_y /= screen_h;
|
||||
center_pos_y = float(1.f - center_pos_y);
|
||||
width = destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X;
|
||||
width /= screen_w;
|
||||
height = destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y;
|
||||
height /= screen_h;
|
||||
|
||||
tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X);
|
||||
tex_center_pos_x /= texture_width * 2.f;
|
||||
tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y);
|
||||
tex_center_pos_y /= texture_height * 2.f;
|
||||
tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X);
|
||||
tex_width /= texture_width * 2.f;
|
||||
tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y);
|
||||
tex_height /= texture_height * 2.f;
|
||||
|
||||
if (textureisRTT)
|
||||
tex_height = -tex_height;
|
||||
|
||||
const f32 invW = 1.f / static_cast<f32>(texture_width);
|
||||
const f32 invH = 1.f / static_cast<f32>(texture_height);
|
||||
const core::rect<f32> tcoords(sourceRect.UpperLeftCorner.X * invW,
|
||||
sourceRect.UpperLeftCorner.Y * invH,
|
||||
sourceRect.LowerRightCorner.X * invW,
|
||||
sourceRect.LowerRightCorner.Y * invH);
|
||||
} // getSize
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void draw2DImage(const video::ITexture* texture,
|
||||
const core::rect<s32>& destRect,
|
||||
@ -355,82 +312,6 @@ void draw2DImage(const video::ITexture* texture,
|
||||
glGetError();
|
||||
} // draw2DImage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void draw2DImage(const video::ITexture* texture,
|
||||
const core::rect<float>& destRect,
|
||||
const core::rect<s32>& sourceRect,
|
||||
const core::rect<s32>* clip_rect,
|
||||
const video::SColor &colors,
|
||||
bool use_alpha_channel_of_texture)
|
||||
{
|
||||
if (!CVS->isGLSL())
|
||||
{
|
||||
core::rect<irr::s32> dest_rect
|
||||
(irr::s32(destRect.UpperLeftCorner.X),
|
||||
irr::s32(destRect.UpperLeftCorner.Y),
|
||||
irr::s32(destRect.LowerRightCorner.X),
|
||||
irr::s32(destRect.LowerRightCorner.Y));
|
||||
|
||||
video::SColor duplicatedArray[4] = { colors, colors, colors, colors };
|
||||
draw2DImage(texture, dest_rect, sourceRect, clip_rect, duplicatedArray,
|
||||
use_alpha_channel_of_texture);
|
||||
return;
|
||||
}
|
||||
|
||||
float width, height, center_pos_x, center_pos_y;
|
||||
float tex_width, tex_height, tex_center_pos_x, tex_center_pos_y;
|
||||
|
||||
getSize(texture->getSize().Width, texture->getSize().Height,
|
||||
texture->isRenderTarget(), destRect, sourceRect, width, height,
|
||||
center_pos_x, center_pos_y, tex_width, tex_height,
|
||||
tex_center_pos_x, tex_center_pos_y);
|
||||
|
||||
if (use_alpha_channel_of_texture)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (clip_rect)
|
||||
{
|
||||
if (!clip_rect->isValid())
|
||||
return;
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& render_target_size =
|
||||
irr_driver->getActualScreenSize();
|
||||
glScissor(clip_rect->UpperLeftCorner.X,
|
||||
(s32)render_target_size.Height - clip_rect->LowerRightCorner.Y +
|
||||
irr_driver->getDevice()->getMovedHeight(),
|
||||
clip_rect->getWidth(), clip_rect->getHeight());
|
||||
}
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()->use();
|
||||
glBindVertexArray(SharedGPUObjects::getUI_VAO());
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setTextureUnits(texture->getOpenGLTextureName());
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setUniforms(core::vector2df(center_pos_x, center_pos_y),
|
||||
core::vector2df(width, height),
|
||||
core::vector2df(tex_center_pos_x, tex_center_pos_y),
|
||||
core::vector2df(tex_width, tex_height),
|
||||
colors);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
if (clip_rect)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glUseProgram(0);
|
||||
|
||||
glGetError();
|
||||
} // draw2DImage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h,
|
||||
const core::rect<s32>& destRect,
|
||||
@ -594,83 +475,6 @@ void draw2DImageCustomAlpha(const irr::video::ITexture* texture,
|
||||
glGetError();
|
||||
} // draw2DImage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void draw2DImage(const video::ITexture* texture,
|
||||
const core::rect<float>& destRect,
|
||||
const core::rect<s32>& sourceRect,
|
||||
const core::rect<s32>* clip_rect,
|
||||
const video::SColor* const colors,
|
||||
bool use_alpha_channel_of_texture,
|
||||
bool draw_translucently)
|
||||
{
|
||||
if (!CVS->isGLSL())
|
||||
{
|
||||
core::rect<irr::s32> dest_rect
|
||||
(irr::s32(destRect.UpperLeftCorner.X),
|
||||
irr::s32(destRect.UpperLeftCorner.Y),
|
||||
irr::s32(destRect.LowerRightCorner.X),
|
||||
irr::s32(destRect.LowerRightCorner.Y));
|
||||
|
||||
irr_driver->getVideoDriver()->draw2DImage(texture, dest_rect, sourceRect,
|
||||
clip_rect, colors,
|
||||
use_alpha_channel_of_texture);
|
||||
return;
|
||||
}
|
||||
|
||||
float width, height, center_pos_x, center_pos_y, tex_width, tex_height;
|
||||
float tex_center_pos_x, tex_center_pos_y;
|
||||
|
||||
getSize(texture->getSize().Width, texture->getSize().Height,
|
||||
texture->isRenderTarget(), destRect, sourceRect, width, height,
|
||||
center_pos_x, center_pos_y, tex_width, tex_height,
|
||||
tex_center_pos_x, tex_center_pos_y);
|
||||
|
||||
if (draw_translucently)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
else if (use_alpha_channel_of_texture)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
if (clip_rect)
|
||||
{
|
||||
if (!clip_rect->isValid())
|
||||
return;
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const core::dimension2d<u32>& render_target_size =
|
||||
irr_driver->getActualScreenSize();
|
||||
glScissor(clip_rect->UpperLeftCorner.X,
|
||||
(s32)render_target_size.Height - clip_rect->LowerRightCorner.Y +
|
||||
irr_driver->getDevice()->getMovedHeight(),
|
||||
clip_rect->getWidth(), clip_rect->getHeight());
|
||||
}
|
||||
if (colors)
|
||||
{
|
||||
drawTexColoredQuad(texture, colors, width, height, center_pos_x,
|
||||
center_pos_y, tex_center_pos_x, tex_center_pos_y,
|
||||
tex_width, tex_height, 0.0f/*rotation*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTexQuad(texture->getOpenGLTextureName(), width, height,
|
||||
center_pos_x, center_pos_y, tex_center_pos_x,
|
||||
tex_center_pos_y, tex_width, tex_height, 0.0f/*rotation*/);
|
||||
}
|
||||
if (clip_rect)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glUseProgram(0);
|
||||
|
||||
glGetError();
|
||||
} // draw2DImage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices,
|
||||
u32 vertexCount, const void* indexList,
|
||||
|
@ -44,13 +44,6 @@ void draw2DImage(const irr::video::ITexture* texture,
|
||||
const irr::video::SColor &color,
|
||||
bool useAlphaChannelOfTexture);
|
||||
|
||||
void draw2DImage(const irr::video::ITexture* texture,
|
||||
const irr::core::rect<float>& destRect,
|
||||
const irr::core::rect<irr::s32>& sourceRect,
|
||||
const irr::core::rect<irr::s32>* clipRect,
|
||||
const irr::video::SColor &color,
|
||||
bool useAlphaChannelOfTexture);
|
||||
|
||||
void draw2DImage(const irr::video::ITexture* texture,
|
||||
const irr::core::rect<irr::s32>& destRect,
|
||||
const irr::core::rect<irr::s32>& sourceRect,
|
||||
@ -65,13 +58,6 @@ void draw2DImageCustomAlpha(const irr::video::ITexture* texture,
|
||||
const irr::core::rect<irr::s32>* clipRect,
|
||||
float rotation, float custom_alpha);
|
||||
|
||||
void draw2DImage(const irr::video::ITexture* texture,
|
||||
const irr::core::rect<float>& destRect,
|
||||
const irr::core::rect<irr::s32>& sourceRect,
|
||||
const irr::core::rect<irr::s32>* clipRect,
|
||||
const irr::video::SColor* const colors,
|
||||
bool useAlphaChannelOfTexture, bool draw_translucently = false);
|
||||
|
||||
void draw2DVertexPrimitiveList(irr::video::ITexture *t, const void* vertices,
|
||||
irr::u32 vertexCount, const void* indexList,
|
||||
irr::u32 primitiveCount,
|
||||
|
Loading…
x
Reference in New Issue
Block a user