Я следил за учебником Lazy Foo для создания текста с использованием шрифта ttf, и все было хорошо, но мне нужно было создать несколько текстовых строк в разных местах с разными размерами и цветом шрифта, поэтому Я решил использовать вектор. Вот мой код TextTexture (в основном копии Ленивого Foo учебника):Текстуры SDL_ttf в векторе влияют на прямоугольник назначения другого
#ifndef TEXT_TEXTURE_HPP
#define TEXT_TEXTURE_HPP
#include "graphics.hpp"
#include "vector2.hpp"
#include <SDL2/SDL_ttf.h>
#include <string>
class TextTexture {
public:
TextTexture(
Graphics& graphics,
TTF_Font* font,
std::string textureText,
SDL_Color textColor,
Vector2 coordinates
);
~TextTexture();
void draw(Graphics& graphics);
private:
SDL_Texture* mTexture;
int mWidth;
int mHeight;
int mX;
int mY;
};
#endif // TEXT_TEXTURE_HPP
И .cpp файл для этого:
#include "text_texture.hpp"
#include "vector2.hpp"
#include <iostream>
#include <unistd.h>
TextTexture::TextTexture (
Graphics& graphics,
TTF_Font* font,
std::string textureText,
SDL_Color textColor,
Vector2 coordinates
) :
mTexture(NULL),
mWidth(0),
mHeight(0),
mX(0),
mY(0)
{
//Render temp surface
SDL_Surface* tempSurface = TTF_RenderUTF8_Blended (font, textureText.c_str(), textColor);
if (tempSurface == NULL) {
std::cout << "Unable to render text surface! SDL_ttf Error: " << TTF_GetError() << std::endl;
} else {
this -> mTexture = SDL_CreateTextureFromSurface(graphics.getRenderer(), tempSurface);
if (this -> mTexture == NULL) {
std::cout << "Unable to create texture from rendered text! SDL Error: " << SDL_GetError() << std::endl;
} else {
//Get image dimensions
mWidth = tempSurface -> w;
mHeight = tempSurface -> h;
// Get coordinates
this -> mX = coordinates.getX();
this -> mY = coordinates.getY();
}
SDL_FreeSurface (tempSurface);
tempSurface = NULL;
}
}
TextTexture::~TextTexture() {
//Free texture if it exists
if (mTexture != NULL) {
SDL_DestroyTexture(mTexture);
}
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
// FIXME somewhy affects previous dest rects
void TextTexture::draw (Graphics& graphics) {
//Set rendering space and render to screen
SDL_Rect destinationRectangle = { mX, mY, this -> mWidth, this -> mHeight };
//Render to screen
graphics.blitSurface(mTexture, NULL, &destinationRectangle);
}
Я создал простой текстовый менеджер для обработки текстов вектора:
#ifndef TEXT_MANAGER_HPP
#define TEXT_MANAGER_HPP
#include "graphics.hpp"
#include "text_texture.hpp"
#include "vector2.hpp"
#include <string>
#include <vector>
enum fontSize {
SMALL = 16,
NORMAL = 32,
BIG = 48,
TITLE = 72
};
enum fontColor {
WHITE,
ORANGE,
BLACK
};
class TextManager {
public:
TextManager(Graphics& graphics);
~TextManager();
void addText(std::string, fontSize, fontColor, Vector2);
void draw();
void clearText();
private:
Graphics& graphics;
std::vector <TextTexture> gText;
};
#endif // TEXT_MANAGER_HPP
и .cpp файл:
#include "text_manager.hpp"
#include <iostream>
TextManager::TextManager(Graphics& graphics) :
graphics(graphics)
{}
TextManager::~TextManager() {}
void TextManager::addText(std::string text, fontSize size, fontColor color, Vector2 coordinates) {
TTF_Font* tempFont = TTF_OpenFont("resources/fonts/pixel.ttf", fontSize::TITLE);
SDL_Color tempColor = { 255, 255, 255 };
// Switch removed for shorter code
this -> gText.emplace_back(graphics, tempFont, text, tempColor, coordinates);
TTF_CloseFont(tempFont);
tempFont = NULL;
}
// FIXME
void TextManager::draw() {
std::vector<TextTexture>::iterator it;
for(it = gText.begin(); it != gText.end(); ++it) {
it -> draw(graphics);
}
}
void TextManager::clearText() {
gText.clear();
}
Но когда я запустить приложение, я вижу что-то вроде этого:
Second string is printed, but font and bonding rectangle of first line is saved, hovewer
Позже я добавил ввод обработчик, который добавил вторую строку текста после нажатия на кнопку, и, когда есть только одна строка текста, все отлично, но когда вы добавляете второй, начинается что-то странное - иногда первый текст исчезает, иногда «оба» из них запихиваются. Насколько я понимаю, вторая поверхность текста как-то влияет на первую, скопировав ее текстуру на место первого места назначения.
Вот мой graphics.blitSurface, если это поможет:
void Graphics::blitSurface(SDL_Texture* texture, SDL_Rect* sourceRectangle, SDL_Rect* destinationRectangle)
{
SDL_RenderCopy (this -> _renderer, texture, sourceRectangle, destinationRectangle);
}
Где моя ошибка? Извините за плохой английский, надеюсь, вы получите мою проблему.
Ваш последний цикл «отключает» рисунок, потому что он копирует 'TextTexture', но у вас нет надлежащего копирования-конструктор. – tkausl
Для вашего последнего редактирования: нет, версия без итератора использует временную переменную, и как только ее деструктор называется, вы уничтожаете свою текстуру. Что касается исходной проблемы, было бы проще, если бы вы описали ее лучше. Например. Я не вижу кода, который переключает шрифты в зависимости от переданного размера, но вы подразумеваете, что это должно произойти (также этот «ввод кода здесь» немного подозрительный, но я ожидаю, что это будет ошибка copypaste). – keltar
О, это на самом деле имеет смысл. Спасибо! – SuperPrower