gpt4 book ai didi

c++ - 在 OpenGL 中自由类型文本后面的渲染正方形被裁剪

转载 作者:行者123 更新时间:2023-11-30 04:58:31 25 4
gpt4 key购买 nike

我正在尝试放置一个正方形作为我的文本的背景,它由 OpenGL 中的 FreeType 呈现。但是文字不知何故像这样穿过我的方 block :enter image description here

看,我方 block 后面的弧线没问题。圆弧在 0.0 上,正方形在 1.0 上,文字在 Z 轴上在 2.0 上。

这就是我创建它们的方式:

auto arc2x = new OpenGL::Rendering::Models::Arc(
Container::Position(pos_x, pos_y, 0), Container::Color::GREEN, 50,
radius, 90, arc_degree);
arc2x->create();
arc2x->set_rotation(76, 0, 0, 1);

auto text1_back = new OpenGL::Rendering::Models::Quad(
Container::Position(pos_x, pos_y - radius, -0.1),
Container::Color::CYAN, 25, 25);
text1_back->create();

auto text1 = new OpenGL::Rendering::Models::Text(
"8", Container::Position(pos_x - 5, pos_y - radius / 1.5, 2), 22,
Container::Color::PINK);
text1->create();

我的文本类:

// Text.cpp
#include "Text.h"

using namespace OpenGL::Rendering::Models;

Text::Text(const std::string& text, OpenGL::Container::Position position,
int font_size, OpenGL::Container::Color color) {
m_font_size = font_size;
m_scale = 1.0;
m_text = text;
float angle = 0;
this->color.r = color.r;
this->color.g = color.g;
this->color.b = color.b;
this->color.a = color.a;

matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);

this->position.x = position.x;
this->position.y = position.y;
this->position.z = position.z;

if (FT_Init_FreeType(&font)) {
Log()->critical("Could not initalize Freetype library for fonts.");
}

if (FT_New_Face(font, "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", 0,
&face)) {
Log()->critical("Could not load font. File is missing maybe?");
}

FT_Set_Char_Size(face, 0, m_font_size * 64, 300, 300);
FT_Set_Pixel_Sizes(face, 0, m_font_size);
if (FT_Load_Char(face, 'X', FT_LOAD_RENDER)) {
Log()->critical(
"Could not load a test glyph. The font is corrupted maybe?");
}

for (GLubyte c = 0; c < 128; ++c) {
FT_Set_Transform(face, &matrix, 0);
if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
Log()->critical("Could not load glyph \"{}\"", c);
continue;
}

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width,
face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
face->glyph->advance.x};

characters.insert(std::pair<GLchar, Character>(c, character));
}

FT_Done_Face(face);
FT_Done_FreeType(font);
}

void Text::create() {
GLuint vao;
GLuint vbo;

glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);

glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL,
GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat),
(void*)0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

this->vao = vao;
this->vbos.push_back(vbo);
this->set_program(OpenGL::Managers::ShaderManager::get_program("text"));
this->set_position(position.x, position.y, position.z);
}

void Text::draw() {

glUseProgram(this->program);
glUniformMatrix4fv(glGetUniformLocation(this->program, "model_matrix"), 1,
false, &model_matrix[0][0]);
glUniform4f(glGetUniformLocation(this->program, "text_color"), color.r,
color.g, color.b, color.a);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(this->vao);

GLfloat temp_x = 0;
GLfloat temp_y = 0;

std::string::const_iterator c;
for (c = m_text.begin(); c != m_text.end(); c++) {
Character ch = characters[*c];

GLfloat xpos = temp_x + ch.bearing.x * m_scale;
GLfloat ypos = temp_y - (ch.size.y - ch.bearing.y) * m_scale;

GLfloat w = ch.size.x * m_scale;
GLfloat h = ch.size.y * m_scale;

GLfloat vertices[6][4] = {
{xpos, ypos + h, 0.0, 0.0}, /**/
{xpos, ypos, 0.0, 1.0}, /**/
{xpos + w, ypos, 1.0, 1.0}, /**/

{xpos, ypos + h, 0.0, 0.0}, /**/
{xpos + w, ypos, 1.0, 1.0}, /**/
{xpos + w, ypos + h, 1.0, 0.0} /**/
};

glBindTexture(GL_TEXTURE_2D, ch.texture_id);
glBindBuffer(GL_ARRAY_BUFFER, this->vbos[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
temp_x += (ch.advance >> 6) * m_scale;
}

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}

void Text::set_text(const std::string& a_text) {
if (!a_text.empty()) {
m_text = a_text;
} else {
Log()->info("Cannot set the text. Input seems to be empty.");
}
}

std::string Text::get_text() { return m_text; }

void Text::set_color(const Container::Color a_color) {
color.r = a_color.r;
color.g = a_color.g;
color.b = a_color.b;
color.a = a_color.a;
}

还有我的 Quad 类:

// Quad.cpp
#include "Quad.h"

using namespace OpenGL;
using namespace Rendering::Models;

Quad::Quad(Container::Position pos, Container::Color color, float width,
float height) {
position.x = pos.x;
position.y = pos.y;
position.z = pos.z;

this->color.x = color.r;
this->color.y = color.g;
this->color.z = color.b;
this->color.w = color.a;

this->width = width;
this->height = height;
}

Quad::~Quad() {}

void Quad::create() {
GLuint vao;
GLuint vbo;

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

std::vector<Container::Vertex> vertices;
vertices.push_back(
Container::Vertex(glm::vec3(-1, -1, 0.0), color));
vertices.push_back(
Container::Vertex(glm::vec3(-1, 1, 0.0), color));
vertices.push_back(
Container::Vertex(glm::vec3(1, -1, 0.0), color));
vertices.push_back(
Container::Vertex(glm::vec3(1, 1, 0.0), color));

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Container::Vertex) * 4, &vertices[0],
GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Container::Vertex),
(void*)0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(
1, 4, GL_FLOAT, GL_FALSE, sizeof(Container::Vertex),
(void*)(offsetof(Container::Vertex, Container::Vertex::m_color)));

glBindVertexArray(0);
this->vao = vao;
this->vbos.push_back(vbo);
this->set_program(OpenGL::Managers::ShaderManager::get_program("shape"));
this->set_scale(width / 2, height / 2, 1.0);
this->set_position(position.x, position.y, position.z);
}

void Quad::draw() {
glUseProgram(this->program);
glUniformMatrix4fv(glGetUniformLocation(this->program, "model_matrix"), 1,
false, &model_matrix[0][0]);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
}

知道为什么会这样吗?如果您需要更多代码进行诊断,我会立即添加。非常感谢。

最佳答案

您正在使用 alpha 混合绘制四边形。 alpha 混合允许 8 周围的区域透明。然而,就 OpenGL 而言,这只是片段颜色的修改。透明片段仍会写入深度缓冲区。

您的抽奖顺序似乎未指定。从下面的评论来看,您正在使用 std::map 来保存您的模型。迭代该容器时获得的顺序不一定与插入顺序相同。这意味着您可能首先绘制一个“更近”的元素,导致其深度值写入深度缓冲区,从而防止任何后续“更远”的元素影响片段颜色。

在绝大多数情况下,无序绘图是好的(并且出于性能原因实际上是鼓励的)。但是,一旦您开始使用 alpha 混合透明度,顺序就变得很重要。

对于 alpha 混合 2D 元素,绘制的一般方法是:

  • 关闭深度测试。
  • 根据深度对 CPU 代码中的元素进行排序。
  • 将它们从后往前画(从最远到最近)。

关于c++ - 在 OpenGL 中自由类型文本后面的渲染正方形被裁剪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51656993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com