[OpenGL] Designproblem beim Picking mitttels gluPickMatrix



  • Hallo!

    Ich arbeite an einer Art LevelEditor
    -> Objekte sind Klassen, deren Vertecies als QUADS dargestellt werden und verschiebbar und natürlich selektierbar sind

    Folgende Funktionen (paintGL() und paintStatic()) muss ich beim Picking leider fast "abschreiben"! paintStatic() Soll die vertecies so darstellen, dass sie nicht zoomen:

    glOrtho((-width/(2*zoom),width/(2*zoom),height/(2*zoom),-height/(2*zoom),-1000.0f,1000.0f);
    

    Jetzt folgt recht viel Code, ich hoffe ihr seht es euch trotzdem an, da ich so nciht weiterkomme 😞

    void glWidget::paintGL()
    {
            glMatrixMode(GL_MODELVIEW);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity();
    
    	//Move "camera":
    	glTranslatef(transX,transY, 0);
    	glRotatef(rotX, 1, 0, 0); 
    	glRotatef(rotY, 0, 1, 0);
    	glRotatef(rotZ, 0, 0, 1);
    
    	drawCoordinateSystem(); //Draw zero axes and grid (if enabled)
    
    	for (int i=0; i<scene->objects.size(); i++)
    	{
    		//Draw objects:
    		glPushMatrix();
    		scene->objects[i]->glTranslate();
    		scene->objects[i]->glDraw();
    		glPopMatrix();
    
    		for(int n=0; n<scene->objects[i]->vertecies->size(); n++)
    		{
    			//Draw vertecies:
    			glColor3f(1,0,0);
    			if(scene->objects[i]->vertecies->at(n)->isVisible())
    			{
    				glPushMatrix();
    				scene->objects[i]->glTranslate();
    				glTranslatef(scene->objects[i]->vertecies->at(n)->x,
    					scene->objects[i]->vertecies->at(n)->y, 
    					scene->objects[i]->vertecies->at(n)->z);
    
    				if(scene->isSelected(i, n))
    					glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    
    				paintStatic(vertexObj);
    
    				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    				glPopMatrix();
    			}
    		}
    	}
    
    	paintStatic(scene->anchor);
    
    	//Print to screen:
    	swapBuffers();
    }
    
    void glWidget::paintStatic(glObject *obj)
    {
    	QPointF screenPos = mapFromScene(obj->trans);
    
    	glMatrixMode(GL_PROJECTION);
    	glPushMatrix();
    	glLoadIdentity();
    	glOrtho(0,width(),height(),0,-1000.0f,1000.0f);
    	glMatrixMode(GL_MODELVIEW);
    
    	glInitNames();
    	glPushName(0);
    
    	glPushMatrix();
    	glLoadIdentity();
    
    	glTranslatef(screenPos.x(), screenPos.y(),  0);
    	glLoadName(6);
    	obj->glDraw();
    
    	glPopMatrix();
    
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
    	glMatrixMode(GL_MODELVIEW);
    }
    

    Meine Funktion die das Picking durchführt soll (vorerst) nur erkennen ob auf Vertecies geklickt wurde (soll später aber noch erweiterbar sein). Und so sieht das aus:

    GLuint buffer[256];  //diff
    	GLint viewport[4]; //diff
    	int hits = 0; //diff
    
    	glGetIntegerv(GL_VIEWPORT, viewport); //diff
    	glSelectBuffer(256, buffer); //diff
    
    	glMatrixMode(GL_PROJECTION); //RENDER-mode möglich (anderer user-modus?)
    	glPushMatrix();
    	glLoadIdentity();
    	glOrtho(-width()/(2*zoom),width()/(2*zoom),height()/(2*zoom),-height()/(2*zoom),-1000.0f,1000.0f);
    	glMatrixMode(GL_MODELVIEW);
    
    //##############paintGL() ANFANG####################################
    	glMatrixMode(GL_MODELVIEW);
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity();
    
    	//Move "camera":
    	glTranslatef(transX,transY, 0);
    	glRotatef(rotX, 1, 0, 0); 
    	glRotatef(rotY, 0, 1, 0);
    	glRotatef(rotZ, 0, 0, 1);
    
    	drawCoordinateSystem(); //Draw zero axes and grid (if enabled)
    
    	for (int i=0; i<scene->objects.size(); i++)
    	{
    		//Draw objects:
    		glPushMatrix();
    		scene->objects[i]->glTranslate();
    		scene->objects[i]->glDraw();
    		glPopMatrix();
    
    		for(int n=0; n<scene->objects[i]->vertecies->size(); n++)
    		{
    			//Draw vertecies:
    			glColor3f(1,0,0);
    			if(scene->objects[i]->vertecies->at(n)->isVisible())
    			{
    				glPushMatrix();
    				scene->objects[i]->glTranslate();
    				glTranslatef(scene->objects[i]->vertecies->at(n)->x,
    					scene->objects[i]->vertecies->at(n)->y, 
    					scene->objects[i]->vertecies->at(n)->z);					
    //##########paintStatic() ANFANG####################	
    				QPointF screenPos = mapFromScene(vertexObj->trans);
    
    				glMatrixMode(GL_PROJECTION);
    				glRenderMode(GL_SELECT);
    				glPushMatrix();
    				glLoadIdentity();
    				gluPickMatrix(mx, viewport[3] - my, w, h, viewport);
    				glOrtho(0,width(),height(),0,-1000.0f,1000.0f);
    				glMatrixMode(GL_MODELVIEW);
    
    //HIER einzige Unterschiede (namen und Rendermodus)
    				glInitNames();
    				glPushName(0);
    
    				glPushMatrix();
    				glLoadIdentity();
    
    				glTranslatef(screenPos.x(), screenPos.y(),  0);
    				glLoadName(i*10+n);
    //FIXME: 10 mit der größten Anzahl von Vertecies ersetzten, die ein Objekt bis jetzt hat (10er Schritte)
    				vertexObj->glDraw();
    
    				glPopMatrix();
    
    				glMatrixMode(GL_PROJECTION);
    				glPopMatrix();
    				hits += glRenderMode(GL_RENDER);
    				glMatrixMode(GL_MODELVIEW);
    //#######paintStatic() ENDE#############
    				glPopMatrix();
    			}
    		}
    	}
    
    	paintStatic(scene->anchor);
    
    	swapBuffers();	
    
    //########glPaint() ENDE#################
    
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
    	glMatrixMode(GL_MODELVIEW);
    
    //Treffer verarbeiten ...
    

    Wenn ihr nun fertig seit mim Hände über den Kopf zusmmenschlagen, dann habt ihr vielleicht einen Tipp, wie man sowas richtig macht? Ich habe in Qt (die bibliothek, die ich für die GUI nutze) was von overlays und zusätzlichen Renderkontexten gelesen, was aber nicht wirklich verständlich ist. Evtl ist das ein neuer Ansatz?



  • ich hab mir ne einfachere Möglichkeit gesucht, bei der ich allerdings momentan nicht genau weiß, wie ich einen Vertex dann verschiebe.

    OpenGl kennt verschiedene Rendermodi. Wenn du GL_SELECT einstellst, wird nur in den Speicher, aber nicht auf den Screen gerendert.
    jetzt musst du eigentlich beim Darstellen nur noch jedem Vertex eine Farbe zuordnen, anschließend den die Farbe an den Mouse-Koordinaten auslesen und das entsprechende Element auswählen.

    Mit dem Verschieben bin ich, wie gesagt, bisher nicht weiter gekommen.

    Edit: Vergiss es- machst ja schon so ^^ - hab wirklich zuviel stress heut 😞


Anmelden zum Antworten