OpenGL: Eine Textur in glusphere einfügen
-
Kann mir jemand an Hand eines Codebeispiels zeigen, wie man eine Textur an die Oberfläche einer Kugel anpasst? Ich möchte nämlich ein geographisches Mini-Programm schreiben, dass Ähnlichkeiten mit Marble (KDE) oder Google Earth haben soll. Maus-Ereignisse zum drehen der Kugel habe ich schon geschrieben. Mir fehlt nur die Textatur auf der Kugel (glusphere). Vielleicht kann mir auch jemand verraten, wie ich eine blaue halbdurchsichtige Atmosphäre hinzufügen kann. Wäre sehr nett. Danke jetzt schon für eure Hilfe!
Gruß,
littletux
-
Hallo littletux,
bei einer gluSphere kannst du verschiedene Einstellungen vornehmen, darunter fällt auch:
gluQuadricTexture(m_quadricObj, true); //default: false
Damit wählst du, ob deine Kugel texturiert sein soll, oder nicht. Da der default-Wert false ist, solltest du obige Zeile verwenden. Ansonsten ist das Vorgehen wie gewohnt.
Für die Atmosphäre fallen mir spontan zwei Lösungen ein:
(1)
Du renderst eine zweite Kugel, mit leicht größerem Radius (und gleichem Mittelpunkt). Dabei muss Blending aktiviert seinglEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
(2)
Alternativ kannst du um deinen Planet einen 2D-Ring bzw. eine Disk zeichnen, der sich nicht mit der Kugel dreht und dessen Normale senkrecht zur Bildebene steht. Dann fängst du innen mit vollem Alpha-Wert an (Farbe deiner Textur) und lässt den Alpha-Wert nach außen kleiner werden.Viele Grüße,
MaBa
-
Hi littletux,
Hast Du Dir schon überlegt, ob Du an der Marble-Entwicklung teilnehmen möchtest?
http://edu.kde.org/marble/getinvolved.php
Wir sind eine große offene Community von Entwicklern und Anwendern und suchen dauernd Leute, die mithelfen wollen unsere große blaue Murmel zum Rollen zu bringen
Auch ein OpenGL backend ist bei uns in der Planungsphase.
Viele Grüße,
Torsten
-
@MaBa: Danke für Deine Hilfe! Es hat geklappt
@tackat: Danke für Dein Angebot! Ich würde gerne bei Projekten mitwirken, vor allem wenn es um Linux und Open Source geht. Aber ich glaube ich bin noch nicht soweit, da mir noch einige Grundkenntnisse von OpenGL fehlen. Ich habe ja erst angefangen mir OpenGL anzufangen. Vielleicht melde mich irgendwann bei Dir, wenn ich so weit bin.Ich habe ein Problem beim Zoomen: Wenn ich versuchen will mit der Mausrad die Erde zu vergrößern verschwindet bei einer gewissen Größe ein Teil der Erde, beim verkleinern wird die Erde wieder sichtbar. Ich glaube es liegt irgendwie an OpenGL. Weiß einer, wie man es vermeiden kann, dass die Kugel beim vergrößern zerlegt wird? Wie wurde das Problem bei Marble gelöst? Danke!
Gruß,
littletux
-
Hallo littletux,
ich vermute, dass deine Erde weggeclippt wird (s. z.B. Kapitel 3 aus dem Redbook). D.h. es wird der Teil deiner Szene, der sich außerhalb des Sichtvolumens befindet abgeschnitten. Damit wird eine Effizienzsteigerung erreicht, da nicht die komplette Szene durch die Graphikpipeline durchgeschleust werden muss. Der "Nachteil" ist, dass eben nicht die ganze Szene sichtbar ist. Du musst eben nur schauen, dass das Sichtvolumen für deine Anwendung sinnvoll definiert wird.
Vermeiden lässt sich der Effekt des Abschneidens bei dir, indem du die near-plane weiter nach vorne setzt.
Je nachdem welche Projektion du verwendest, kannst du eine der folgenden Befehle verwenden:
// (1) perspektivische Projektion glFrustum(left, right, bottom, top, zNear, zFar); // (2) perspektivische Projektion mit Hilfe der GLU-Bibliothek gluPerspective(fovy, aspect, zNear, zFar); // (3) orthographische Projektion glOrtho(left, right, bottom, top, znear, zfar);
Ich vermute du willst eine perspektivische Projektion. In dem Fall würde ich zu gluPerspective raten, da die Parameter m.E. intuitiver sind.
Viele Grüße,
MaBa
-
> Grundkenntnisse von OpenGL fehlen. Ich habe ja erst angefangen
> mir OpenGL anzufangen.
> Vielleicht melde mich irgendwann bei Dir, wenn ich so weit bin.> Wie wurde das Problem bei Marble gelöst? Danke!
In Marble verwenden wir aktuell ja noch kein OpenGL, sondern machen alles via QPainter & Co (in Software). OpenGL werden wir in künftigen Versionen als zusätzliche Option anbieten. Zum (im Experimentierstadium befindlichen) Marble-OpenGL mode weiß ich persönlich leider keine Details.
Grüße,
Torsten
-
Kann es sein, dass ich mich mit gluPerspektive im Planet befinde? Mit glOrtho sehe ich die Erde von außen (mit Clippingplane) und kann sie zoomen. Mit gluPerspective habe ich kein Clippingplane. Dafür sehe ich die Erde von innen und kann sie nicht zoomen. Das einzige was beim zoomen passiert ist, dass das Licht gedimmt wird (von hell auf dunkel verändert wird oder umgekehrt). Wie bekomme ich es hin, dass ich die Erde mit gluPerspektive von außen sehen kann und die Erde richtig gezoomt wird? Hier ist mein Code:
//////////////////////////////////////////////////////////////////////////////// /// Die srOpenGL-Implementierung //////////////////////////////////////////////////////////////////////////////// #include "opengl.h" srOpenGL::srOpenGL(wxWindow *parent, int *args, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) : wxGLCanvas(parent, id, pos, size, style, name, args), init(FALSE), fit(1.0f), scaleX(1.0f), scaleY(1.0f), scaleZ(1.0f), rotateX(0.0f), rotateY(0.0f), rotateZ(0.0f), translateX(0.0f), translateY(0.0f), translateZ(0.0f) { //////////////////////////////////////////////////////////////////////////////// /// Die Konfiguration //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->fit = (static_cast<float>(this->GetWidth()) /static_cast<float>(this->GetHeight())); this->image = new srImage(1); //////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Die Connect-Ereignisse //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->Connect(wxEVT_MOTION, wxMouseEventHandler(srOpenGL::OnMouseMove)); this->Connect(wxEVT_PAINT, wxPaintEventHandler(srOpenGL::OnPaint)); this->Connect(wxEVT_SIZE, wxSizeEventHandler(srOpenGL::OnSize)); this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(srOpenGL::OnZoom)); //////////////////////////////////////// } srOpenGL::~srOpenGL() { //////////////////////////////////////////////////////////////////////////////// /// Die Disconnect-Ereignisse //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(srOpenGL::OnZoom)); this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(srOpenGL::OnSize)); this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(srOpenGL::OnPaint)); this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(srOpenGL::OnMouseMove)); //////////////////////////////////////// } int srOpenGL::GetHeight() { //////////////////////////////////////////////////////////////////////////////// /// Der Höhen-Akzessor //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// return this->GetSize().y; //////////////////////////////////////// } int srOpenGL::GetWidth() { //////////////////////////////////////////////////////////////////////////////// /// Der Breiten-Akzessor //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// return this->GetSize().x; //////////////////////////////////////// } void srOpenGL::BindID(unsigned int index) { //////////////////////////////////////////////////////////////////////////////// /// Eine Textur-ID einbinden //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// if(index<this->image->SizeOfArray()) { glBindTexture(GL_TEXTURE_2D, this->image->GetID()[index]); } //////////////////////////////////////// } void srOpenGL::DrawPlanet(unsigned int id, float radius) { //////////////////////////////////////////////////////////////////////////////// /// Ein Planet zeichnen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// GLUquadricObj *sphere; sphere = gluNewQuadric(); gluQuadricTexture(sphere, TRUE); this->BindID(id); glPushMatrix(); glRotatef(90, 1.0f, 0.0f, 0.0f); gluSphere(sphere, radius, 25, 25); glPopMatrix(); gluDeleteQuadric(sphere); //////////////////////////////////////// } void srOpenGL::InitOpenGL() { //////////////////////////////////////////////////////////////////////////////// /// OpenGL vorbereiten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// static const GLfloat light0_color[4] = {0.6f, 0.6f, 0.6f, 1.0f}; static const GLfloat light0_pos[4] = {-5.0f, 5.0f, 5.0f, 0.0f}; static const GLfloat light1_color[4] = {0.4f, 0.4f, 1.0f, 1.0f}; static const GLfloat light1_pos[4] = {5.0f, -5.0f, -5.0f, 0.0f}; glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color); glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); glLightfv(GL_LIGHT1, GL_POSITION, light1_pos); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glClearColor(0.92f, 0.92f, 0.92f, 0.0f); glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_COLOR_MATERIAL); glViewport(0.0f, 0.0f, this->GetWidth(), this->GetHeight()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, this->fit, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //////////////////////////////////////// } void srOpenGL::InitTextures() { //////////////////////////////////////////////////////////////////////////////// /// Die Texturen einrichten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->image->LoadFile(wxT("earth.png"), 0); for(unsigned int c = 0; c<this->image->SizeOfArray(); c++) { this->image->IsTexture(c); } //////////////////////////////////////// } void srOpenGL::OnMouseMove(wxMouseEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt mit der Maus drehen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int baseX, baseY, difX, difY, posX, posY; baseX = (this->GetWidth()/2); baseY = (this->GetHeight()/2); posX = event.GetX(); posY = event.GetY(); difX = (baseX-posX); difY = (baseY-posY); if(event.LeftIsDown()) { this->Rotate(difY, difX, 0); } event.Skip(); //////////////////////////////////////// } void srOpenGL::OnPaint(wxPaintEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// OpenGL einrichten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// wxPaintDC *paint = new wxPaintDC(this); wxGLCanvas::SetCurrent(); if(!this->init) { this->InitOpenGL(); this->InitTextures(); this->init = TRUE; } this->Render(); glFlush(); wxGLCanvas::SwapBuffers(); delete paint; //////////////////////////////////////// } void srOpenGL::OnSize(wxSizeEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// OpenGL im Panel anpassen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int height, width; wxGLCanvas::GetClientSize(&width, &height); if(wxGLCanvas::GetContext()) { wxGLCanvas::SetCurrent(); glViewport(0, 0, width, height); } wxGLCanvas::OnSize(event); //////////////////////////////////////// } void srOpenGL::OnZoom(wxMouseEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt mit der Maus zoomen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int scroll; float scale = this->scaleX; scroll = event.GetWheelRotation(); if((scroll>0)&&(scale<5.1f)) { scale = scale+0.1f; this->Scale(scale, scale, scale); } else { if(scale>0.4f) { scale = scale-0.1f; this->Scale(scale, scale, scale); } } event.Skip(); //////////////////////////////////////// } void srOpenGL::Render() { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt rendern //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glRotatef(this->rotateX, 1.0f, 0.0f, 0.0f); glRotatef(this->rotateY, 0.0f, 1.0f, 0.0f); glRotatef(this->rotateZ, 0.0f, 0.0f, 1.0f); glScalef(this->scaleX, this->scaleY, this->scaleZ); glTranslatef(this->translateX, this->translateY, this->translateZ); this->DrawPlanet(0, 0.8f); //////////////////////////////////////// } void srOpenGL::Rotate(float x, float y, float z) { //////////////////////////////////////////////////////////////////////////////// /// Das 3D-Objekt drehen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->rotateX = x; this->rotateY = y; this->rotateZ = z; this->Refresh(); //////////////////////////////////////// } void srOpenGL::Scale(float x, float y, float z) { //////////////////////////////////////////////////////////////////////////////// /// Das 3D-Objekt skalieren //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->scaleX = x; this->scaleY = y; this->scaleZ = z; this->Refresh(); //////////////////////////////////////// } void srOpenGL::Translate(float x, float y, float z) { //////////////////////////////////////////////////////////////////////////////// /// Das 3D-Objekt verschieben //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->translateX = x; this->translateY = y; this->translateZ = z; this->Refresh(); //////////////////////////////////////// }
Würde mich freuen, wenn Ihr mir weiterhelfen könnt!
Viele Grüße,
littletux
-
Hallo littletux,
Kann es sein, dass ich mich mit gluPerspektive im Planet befinde?
gluPerspective ändert nichts an der Position der virtuellen Kamera, insofern sollte sich vom Betrachterstandpunkt nichts ändern. gluPerspective (wie auch glFrustum und glOrtho) legen lediglich fest, wie die Projektion auf die Bildeben stattfinden soll.
Wenn du vorher außerhalb warst, musst du bei Veränderung der Projektion immernoch außerhalb sein. Die Viewing-Transformation findet bereits vorher (in der Graphikpipeline) statt und das erreichst du mitgluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
Das einzige was beim zoomen passiert ist, dass das Licht gedimmt wird (von hell auf dunkel verändert wird oder umgekehrt).
Auch an der Beleuchtung wird bei der Projektion nichts geändert.
Zu deinem Code:
Hat zwar nichts mit deinem Fehler zu tun, aber vielleicht dennoch interessant für dich: swapBuffers() führt implizit auch glFLush() aus, d.h. glFlush kannst du weglassen.Ansonsten sehe ich auf Anhieb keinen Fehler.
Hier ein kleines Minimalbeispiel (der Übersichtlichkeit halber ein Teapot ohne Textur, ohne Beleuchtung, "zoom" per Tastatur [w, s]):
#include <windows.h> #include <GL/gl.h> #include <GL/glut.h> float translateX = 0.0f, translateY = 0.0f, translateZ = -1.0f; void display () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(translateX, translateY, translateZ); glColor3f(1.0, 0.0, 0.0); glutSolidTeapot(0.2); glFlush(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'w': translateZ += 0.1f; glutPostRedisplay(); break; case 's': translateZ -= 0.1f; glutPostRedisplay(); break; } } int main ( int argc, char * argv[] ) { glutInit(&argc,argv); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutInitDisplayMode(GLUT_RGB); glutCreateWindow("hello, teapot!"); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 1.0f, 0.0f, 1.0f); glutMainLoop(); }
Wenn ich später noch ein wenig Zeit hab, schau ich mir deinen Code nochmal an.
Viele Grüße,
MaBa
-
Ich habe jetzt herraus gefunden warum glPerspective bei mir nicht richtig funktioniert hat. Ich muss das Objekt erst verschieben und dann drehen und nicht umgekehrt. Jetzt habe ich ein anderes Problem: Die Textur ist Spiegelverkehrt! Woran liegt es? Hier mein neuer Code:
//////////////////////////////////////////////////////////////////////////////// /// Die srOpenGL-Implementierung //////////////////////////////////////////////////////////////////////////////// #include "opengl.h" srOpenGL::srOpenGL(wxWindow *parent, int *args, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) : wxGLCanvas(parent, id, pos, size, style, name, args), init(FALSE), rotateX(0.0f), rotateY(0.0f), rotateZ(0.0f), translateX(0.0f), translateY(0.0f), translateZ(0.0f) { //////////////////////////////////////////////////////////////////////////////// /// Die Konfiguration //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->image = new srImage(1); //////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// Die Connect-Ereignisse //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->Connect(wxEVT_MOTION, wxMouseEventHandler(srOpenGL::OnMouseMove)); this->Connect(wxEVT_PAINT, wxPaintEventHandler(srOpenGL::OnPaint)); this->Connect(wxEVT_SIZE, wxSizeEventHandler(srOpenGL::OnSize)); this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(srOpenGL::OnZoom)); //////////////////////////////////////// } srOpenGL::~srOpenGL() { //////////////////////////////////////////////////////////////////////////////// /// Die Disconnect-Ereignisse //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(srOpenGL::OnZoom)); this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(srOpenGL::OnSize)); this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(srOpenGL::OnPaint)); this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(srOpenGL::OnMouseMove)); //////////////////////////////////////// } int srOpenGL::GetHeight() { //////////////////////////////////////////////////////////////////////////////// /// Der Höhen-Akzessor //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// return this->GetSize().y; //////////////////////////////////////// } int srOpenGL::GetWidth() { //////////////////////////////////////////////////////////////////////////////// /// Der Breiten-Akzessor //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// return this->GetSize().x; //////////////////////////////////////// } void srOpenGL::BindID(unsigned int index) { //////////////////////////////////////////////////////////////////////////////// /// Eine Textur-ID einbinden //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// if(index<this->image->SizeOfArray()) { glBindTexture(GL_TEXTURE_2D, this->image->GetID()[index]); } //////////////////////////////////////// } void srOpenGL::DrawPlanet(unsigned int id, float radius) { //////////////////////////////////////////////////////////////////////////////// /// Ein Planet zeichnen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// GLUquadricObj *sphere; sphere = gluNewQuadric(); gluQuadricTexture(sphere, TRUE); this->BindID(id); glPushMatrix(); glRotatef(90, 1.0f, 0.0f, 0.0f); gluSphere(sphere, radius, 25, 25); glPopMatrix(); gluDeleteQuadric(sphere); //////////////////////////////////////// } void srOpenGL::InitOpenGL() { //////////////////////////////////////////////////////////////////////////////// /// OpenGL vorbereiten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// float ratioWidthHeight = static_cast<float>(this->GetWidth())/static_cast<float>(GetHeight()); static const GLfloat light0_color[4] = {0.6f, 0.6f, 0.6f, 1.0f}; static const GLfloat light0_pos[4] = {-5.0f, 5.0f, 5.0f, 0.0f}; glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color); glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glClearColor(0.92f, 0.92f, 0.92f, 0.0f); glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_COLOR_MATERIAL); glViewport(0, 0, this->GetWidth(), this->GetHeight()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, ratioWidthHeight, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //////////////////////////////////////// } void srOpenGL::InitTextures() { //////////////////////////////////////////////////////////////////////////////// /// Die Texturen einrichten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// this->image->LoadFile(wxT("earth.png"), 0); for(unsigned int c = 0; c<this->image->SizeOfArray(); c++) { this->image->IsTexture(c); } //////////////////////////////////////// } void srOpenGL::OnMouseMove(wxMouseEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt mit der Maus drehen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int baseX, baseY, difX, difY, posX, posY; baseX = (this->GetWidth()/2); baseY = (this->GetHeight()/2); posX = event.GetX(); posY = event.GetY(); difX = (baseX-posX); difY = (baseY-posY); if(event.LeftIsDown()) { this->rotateX = -difY; this->rotateY = -difX; this->Refresh(); } event.Skip(); //////////////////////////////////////// } void srOpenGL::OnPaint(wxPaintEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// OpenGL einrichten //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// wxPaintDC *paint = new wxPaintDC(this); wxGLCanvas::SetCurrent(); if(!this->init) { this->InitOpenGL(); this->InitTextures(); this->init = TRUE; } this->Render(); wxGLCanvas::SwapBuffers(); delete paint; //////////////////////////////////////// } void srOpenGL::OnSize(wxSizeEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// OpenGL im Panel anpassen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int height, width; wxGLCanvas::GetClientSize(&width, &height); if(wxGLCanvas::GetContext()) { wxGLCanvas::SetCurrent(); glViewport(0, 0, width, height); } wxGLCanvas::OnSize(event); //////////////////////////////////////// } void srOpenGL::OnZoom(wxMouseEvent &event) { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt mit der Maus zoomen //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// int scroll; scroll = event.GetWheelRotation(); if((scroll>0)) { this->translateZ += 0.1f; this->Refresh(); } else { this->translateZ -= 0.1f; this->Refresh(); } event.Skip(); //////////////////////////////////////// } void srOpenGL::Render() { //////////////////////////////////////////////////////////////////////////////// /// Das Objekt rendern //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glTranslatef(this->translateX, this->translateY, this->translateZ); glRotatef(this->rotateX, 1.0f, 0.0f, 0.0f); glRotatef(this->rotateY, 0.0f, 1.0f, 0.0f); glRotatef(this->rotateZ, 0.0f, 0.0f, 1.0f); this->DrawPlanet(0, 0.5f); //////////////////////////////////////// }
-
Ich glaube es liegt irgendwie an translateZ. Wenn ich translateZ mit 0 setzte, so wird bei gluOrtho2D(0.0f, 0.0f, this->GetWidth(), this->GetHeight()) und gluPerspective(45.0f, ratioWidthHeight, 0.1f, 100.0f) die Textur richtig angezeigt. Verändere ich translateZ aber auf -1 so wird zwar die Kugel nach hinten verschoben wie ich es möchte, aber die Textur ist dann Spiegelverkehrt (In der X-Achse von Rechts nach Links). Auch die Maus dreht die Kugel in der Entgegengesetzte Richtung. Warum ist es so? Ich schau ja nicht nach "hinten", sondern verschiebe nur das Objekt. Vorher ist mir das Problem nicht aufgefallen, da ich mit glScalef() und nicht mit glTranslate() gearbeitet habe.
-
Ich habe eine Lösung gefunden: Ich muss ratioWidthHeight als negative Zahl setzten, dann klappt es mit der Textur und Maus.
float ratioWidthHeight = -static_cast<float>(this>GetWidth())/static_cast<float>(this>GetHeight()); ... gluPerspective(45.0f, ratioWidthHeight, 0.1f, 200.0f);