[SDL,OpenGL] Texturen werden in manchen Builds nicht gerendert
-
Guten Morgen,
ich habe das Problem, dass Texturen in manchen Builds meines Programmes nicht angezeigt werden. Es scheint, als wäre es ein Fall von undefiniertem Verhalten, doch ich finde leider den Fehler nicht.
Hier die vollständige Klasse
Textur
mit Ausgabe zu Debug-Zwecken:#include "textur.h" using namespace fabula; Textur::Textur(const std::string &filename) : filename_(filename) { if (filename_ != "") { textur_ = init(filename_); empty = false; std::cout << filename_ << " : " << filename << " Nor w/ file"<< std::endl; } else { empty = true; std::cout << filename_ << " Nor w/o file"<< std::endl; } } // Copy Textur::Textur(const Textur &textur) : filename_(textur.filename_) { if (filename_ != "") { textur_ = init(filename_); empty = false; std::cout << filename_ << " : " << textur.filename_ << " Copy w/ file"<< std::endl; } else { empty = true; std::cout << filename_ << " : " << textur.filename_ << " Copy w/o file"<< std::endl; } } Textur::~Textur() { glDeleteTextures(1, &textur_); } Textur& Textur::operator=(const std::string &filename) { glDeleteTextures(1, &textur_); filename_ = filename; if (filename_ != "") { textur_ = init(filename_); empty = false; std::cout << filename_ << " : " << filename << " Nor= w/ file"<< std::endl; } else { textur_ = 0; empty = true; std::cout << filename_ << " : " << filename << " Nor= w/o file"<< std::endl; } return *this; } // Copy Textur& Textur::operator=(const Textur &textur) { glDeleteTextures(1, &textur_); filename_ = textur.filename_; if (filename_ != "") { textur_ = init(filename_); empty = false; std::cout << filename_ << " : " << textur.filename_ << " Copy= w/ file" << empty<< std::endl; } else { textur_ = 0; empty = true; std::cout << filename_ << " : " << textur.filename_ << " Copy= w/ file"<< std::endl; } return *this; } std::string& Textur::getFilename() { return this->filename_; } GLuint& Textur::init(const std::string &filename) { SDL_Surface *image = IMG_Load( filename.c_str() ); SDL_Surface *imageFormated = SDL_DisplayFormatAlpha(image); textur_ = 0; glGenTextures(1, &textur_); glBindTexture(GL_TEXTURE_2D, textur_); //Texture behaving glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); //Free Surface SDL_FreeSurface(imageFormated); SDL_FreeSurface(image); return textur_; } int Textur::bind() { glBindTexture(GL_TEXTURE_2D, textur_); return 0; } GLuint& Textur::toGL() { return textur_; }
Textur
nutze ich als Attribut der KlassePanel
, von der nur die Konstruktoren wichtig sein sollten:Panel::Panel() : xPos_(0), yPos_(0), width_(0), height_(0), alpha_(255) , texture_(FABULA_NULLTEX),draw_(false) {} Panel::Panel(float x,float y,float w, float h, const std::string &fileName, bool draw) : xPos_(x), yPos_(y), width_(w), height_(h), alpha_(255) , texture_(fileName),draw_(draw) {} // Copy Panel::Panel( const Panel& panel ) : xPos_(panel.xPos_), yPos_(panel.yPos_), width_(panel.width_), height_(panel.height_), alpha_(panel.alpha_) , texture_(panel.texture_),draw_(panel.draw_) {} Panel& Panel::operator=( const Panel& panel ) { xPos_ = panel.xPos_; yPos_ = panel.yPos_; width_ = panel.width_; height_ = panel.height_; alpha_ = panel.alpha_; texture_= panel.texture_; draw_ = panel.draw_; return *this; }
Definiert wird ein Objekt der Klasse
Panel
folgendermaßen:#define IMG_MENU_BG ".graphic/background/menu.png" std::cout << "bg_ erstellen" << std::endl; bg_ = { 0,0,WINDOW_WIDTH,WINDOW_HEIGHT,IMG_MENU_BG,true };
Die Ausgabe an dieser Stelle sieht also in jedem Fall, egal ob das Bild angezeigt wird, oder nicht, so aus:
bg_ erstellen
.graphic/background/menu.png : .graphic/background/menu.png Nor w/ file
.graphic/background/menu.png : .graphic/background/menu.png Copy= w/ file0Das Rendern wird durch diese Funktion eingeleitet:
bool Panel::draw() { if ( !draw_ ) { return 0; } if ( texture_.empty == true ) { panelStd( xPos_ , yPos_ , width_ , height_ ); } else { panelAlpha( xPos_ , yPos_ , width_ , height_ , texture_.toGL(), alpha_ ); } return 1; }
Aus irgendeinem Grund ist also das Attribut
Textur::empty
, das laut Ausgabefalse
sein sollte, plötzlichtrue
.Wie gesagt: Ob die Textur angezeigt wird, oder nicht, ändert sich von Build zu Build. Ich habe dieses mal extra mehr Code in den Post gepackt und hoffe, dass der Fehler irgendwo dort liegt. Ich finde ihn leider nicht und bitte daher um Hilfe.
Mit freundlichen Grüßen,
Ki
-
Ersetz mal
if (filename_ != "")
durch
if (filename_.length() != 0)
-
MisterX schrieb:
Ersetz mal
if (filename_ != "")
durch
if (filename_.length() != 0)
Das ist eleganter, hilft bei dem Problem aber leider nicht.
EDIT:
Ungewöhnlicher Weise tritt das Problem übrigens nie bei Objekten der KlassePanel_Button
auf.Panel_Button::Panel_Button(int index, float x,float y,float w, float h, const std::string &fileName, bool draw) : Panel(x, y, w, h, fileName, draw), bIndex_(index) {}
-
Da hilft wohl nix...
Du must den Ablauf mit dem Debugger verfolgen und die Stelle finden wo es zum ersten mal falsch ist.Es gibt ja nur einige Möglichkeiten wie es passieren kann:
1. Die Ausführung erreicht ein
empty = true;
womit du nicht gerechnet hast.
2. Die Variablen sind irgendwie in einem lokalen Gültigkeitswbereich und die erwarteten Änderungen werden nicht global, wie du es erwartest.
3. Ein Seiteneffekt den Du nicht bedacht hast wirkt auf die Variable
4. Du überschreibst irgendwo fremden Speicher und triffst genau diese Variable
(ist eher unwahrscheinlich)Mehr möglichkeiten fallen mir nicht ein, wie so eine "geisterhafte" Änderung eintreten kann.
-
Ich bin jetzt von Ubuntu nach Fedora migriert und der Fehler tritt seltsamerweise nicht mehr auf.
Vorsichtshalber lasse ich den Thread aber besser offen, da ich diesen seltsamen Bug und sein Verschwinden absolut nicht nachvollziehen kann.