Sur mon 2ème projet, je travaille avec opengl et SDL2. Je veux rendre le texte à une surface avec SDL2, puis le convertir.Pourquoi la conversion d'une surface SDL fonctionne-t-elle lorsque la surface a été chargée à partir d'un fichier mais pas quand elle a été générée à partir d'un fichier de police?
Je charge déjà des textures à partir de fichiers avec SDL donc j'ai une fonction qui peut convertir des surfaces. Encore quand je fournis une surface générée par la fonction TTF_Render le résultat est le suivant:
Maintenant je ne sais pas pourquoi cela se produit donc un soutien serait apprécié. J'utilise la librairie SDL_ttf pour charger le fichier. J'utilise visual studio 2015 comme ide.
Voici ma fonction de conversion:
GLuint JUMA_Texture::loadFromSurface(SDL_Surface *img, GLenum target, GLenum filtering) {
GLuint TextureID = 0;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
std::cout << " got " << img;
if (target == GL_TEXTURE_2D)
{
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
int Mode = GL_RGB;
if (img->format->BytesPerPixel == 4) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
transparent = true;
Mode = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, Mode, img->w, img->h, 0, Mode, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(target);
return TextureID;
}
J'imprime l'adresse des pointeurs de surface avant et après qu'il ait été envoyé à la fonction et ils semblent identiques.
Aussi j'écris la surface dans un fichier en utilisant SDL_SaveBmp et il semble bien aussi.
Edit:
En raison de la demande Je vais maintenant poster le code pour les fonctions d'utilisation, ainsi que les constructeurs de mes classes de shaders et de texture.
constructeur shader/chargeur
printf("Loading shader");
// 1. Retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
strcpy_s(Fragpath, fragmentPath);
strcpy_s(Vertexpath, vertexPath);
printf(".");
// ensures ifstream objects can throw exceptions:
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try
{
// Open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// Read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// Convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
printf(".");
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar * fShaderCode = fragmentCode.c_str();
// 2. Compile shaders
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
// Vertex Shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
// Print compile errors if any
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
printf(".");
if (!success)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
// Print compile errors if any
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
printf(".");
// Shader Program
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
// Print linking errors if any
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
printf(".");
// Delete the shaders as they're linked into our program now and no longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
printf("done\n");
fonction shader utilisation
void JUMA_Shader::Use()
{
glUseProgram(this->Program);
}
constructeur de texture
printf("loading Texture");
int pos;
pos = filePath.find(".");
if (filePath.substr(pos) == ".png") {
IMG_Init(IMG_INIT_PNG);
}
else if (filePath.substr(pos) == ".jpg")
IMG_Init(IMG_INIT_JPG);
SDL_Surface *img = IMG_Load(filePath.c_str());
id = loadFromSurface(img,target,filtering);
Texture :: loadFromSurface (NOTE:. J'AI PAS ENCORE DISPONIBLE POUR VÉRIFIER GL_BGR ET GL_BGRA Toutefois, j'ai MANUELLEMENT TENTATIVE DE CES DEUX MODES SANS EFFET DIFFERENT ACTUELLEMENT)
GLuint JUMA_Texture::loadFromSurface(SDL_Surface *img, GLenum target, GLenum filtering) {
GLuint TextureID = 0;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
std::cout << " got " << img;
if (target == GL_TEXTURE_2D)
{
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
int Mode = GL_RGB;
if (img->format->BytesPerPixel == 4) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
transparent = true;
Mode = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, Mode, img->w, img->h, 0, Mode, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(target);
return TextureID;
}
Texture :: UTILISATION
int JUMA_Texture::use(GLenum Channel) {
glActiveTexture(Channel); // Activate the texture unit first before binding texture
glBindTexture(GL_TEXTURE_2D, id);
if (transparent)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
return 1;
}
aussi voici ce que je vois en ce moment (Notez que j'ai vérifié à nouveau et ce n'est pas la couleur que je mets ma police comme je l'ai déjà dit. Je ne sais pas d'où vient cette couleur bleue.Je suis actuellement en train de comprendre cela)
Enfin voici mon vertex shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 texcoords;
out vec2 texCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec4 pos;
void main()
{
pos=gl_Position = projection*view*model*vec4(position,1.0f);
texCoords=vec2(texcoords.xy);
};
Et mon fragment shader:
#version 330 core
out vec4 color;
in vec2 texCoords;
in vec4 pos;
uniform sampler2D ourTexture;
uniform vec4 mixCol;
void main()
{
vec4 texColor = texture(ourTexture, texCoords);
if(texColor.a < 0.1f)
discard;
color = texColor;
};
Mon constructeur de police
JUMA_Font::JUMA_Font(char *path, int size, SDL_Color color, char* text, char *uniform) {
TTF_Init();
font = TTF_OpenFont(path, 40);
sourceSurface = TTF_RenderText_Blended(font, text, color);
printf("%d %d %d %d", color.r, color.g, color.b, color.a);
};
police convertir texturer
JUMA_Texture convertToTexture() {
JUMA_Texture _this;
SDL_SaveBMP(sourceSurface, "out.bmp"); //outputs font correctly
std::cout << "Expected " << sourceSurface;
_this.id = _this.loadFromSurface(sourceSurface,GL_TEXTURE_2D,GL_NEAREST);
return _this;
}
Je suis un peu confus. Le code que vous avez ajouté charge la texture à partir d'un fichier (constructeur de texture), ce que vous avez indiqué fonctionne correctement. Est-ce toujours le cas? C'est à dire. Lorsque vous chargez une image à partir d'un fichier et envoyez la surface à 'loadFromSurface()', tout fonctionne-t-il correctement? Dans ce cas, la partie intéressante du code est la création de la surface à partir d'une police ('TTF_Render *'), qui est toujours manquante. – Meyer
Très bien, j'ajoute la classe complète de polices ... S'il vous plaît maintenez – MoustacheSpy
@Meyer J'ai ajouté tout ce que vous vouliez. Aussi les images sont encore chargées correctement – MoustacheSpy