[gelöst] OpenGL Blending

Alles rund um die Programmierung mit Qt
Antworten
Gorn
Beiträge: 10
Registriert: 24. April 2010 17:29

[gelöst] OpenGL Blending

Beitrag von Gorn »

Versuche derzeit die Blending Option von OpenGL zu nutzen. Soweit scheint auch alles zu laufen, nur wirkt das Blenden über den Aplha Channel bei mir eher als dunkles Licht statt als Transparenz. Egal wie ich es einstelle, scheinbar will es die Transparenz nicht aktualisieren. Ich halte mich dabei hauptsächlich an die NeHe Lektion 8:
http://nehe.gamedev.net/data/lessons/le ... ?lesson=08

Ich poste mal hier teile des Codes, vielleicht weiß ja jemand ob ich bei Qt noch etwas aktivieren oder einen speziellen QGL Befehl verwenden muss, habe bisher allerdings keinen passenden in der Datenbank gefunden:

Code: Alles auswählen

void displayWidget::initializeGL(){
	// matrix init
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-.5, .5, .5, -.5, -1000, 1000);
	glMatrixMode(GL_MODELVIEW);

	// shading, depth and background init
	glShadeModel(GL_SMOOTH);	// Enable Smooth Shading
	qglClearColor(Qt::black);	// Black Background
	glClearDepth(1.0f);			// Depth Buffer Setup

	// GL options
	glEnable(GL_TEXTURE_2D);	// Enable Texture Mapping
	glEnable(GL_CULL_FACE);
	glEnable(GL_MULTISAMPLE);	// Enable Multisampling
	glEnable(GL_DEPTH_TEST);	// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);		// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations

	// Light Options
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);		// sets the ambient Light1
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);		// sets the diffuse Light1
	glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);	// sets the position of Light1
	glEnable(GL_LIGHT1);		// Enables Light1 (light won't work without overall light enable)

	// Blending Options
	glColor4f(1.0f,1.0f,1.0f,0.5f);			// Full Brightness, 50% Alpha - fourth value for alpha: 0.0 = full transparency, 1.0 = full opaque 
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA);		// Blending Function For Translucency Based On Source Alpha Value

	object = makeObject();		// Generate an OpenGL display list
}

/* -------------------------------------------------------------------------------- */

void displayWidget::switchBlending(){
	if(blending){
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		blending = false;
		emit statusMsg("Blending enabled");
	} else {
		glDisable(GL_BLEND);
		glEnable(GL_DEPTH_TEST);
		blending = true;
		emit statusMsg("Blending disabled");
	}
	updateGL();
}

/* -------------------------------------------------------------------------------- */

GLuint displayWidget::makeObject(){
	GLuint list;
	list = glGenLists(1);

	glNewList(list, GL_COMPILE);
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//		glColor3f(1.0f, 1.0f, 1.0f);
		glLoadIdentity();
		glTranslatef(0.0f,0.0f,z);

		glRotatef(xRot, 1.0, 0.0, 0.0);
		glRotatef(yRot, 0.0, 1.0, 0.0);
		glRotatef(zRot, 0.0, 0.0, 1.0);

		if(img = loadBMP("glass.jpg"))
			bindTexture(*img, GL_TEXTURE_2D, GL_RGBA);

		glBegin(GL_QUADS);
			// Front Face
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Left Of The Texture and Quad
			
                            [...] /* Würfel zeichnen */
Sind soweit die einzigen Funktionen, in denen ich Blending Optionen verwendet habe.
Zuletzt geändert von Gorn am 6. Mai 2010 14:34, insgesamt 2-mal geändert.
N¤X
Beiträge: 77
Registriert: 21. September 2009 12:24

Re: OpenGL Blending

Beitrag von N¤X »

Gorn hat geschrieben:

Code: Alles auswählen

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA);
Ich nehme mal an, dass du hier GL_ONE_MINUS_SRC_ALPHA meinst. Wenn die beiden Faktoren sich nicht zu Eins aufsummieren kann das durchaus eine Erklärung für Verfälschungen sein.
Poste mal Screenshots wies denn aussieht, oder sag wenn das bereits geholfen hat.

Des Weiteren sei vllt noch erwähnt, dass das deaktivieren des Depth-Tests nur in deinem Beispiel so klappt, da alle Flächen den selben Alpha-Wert haben und nur maximal zwei Flächen übereinander liegen können. Transparenz ist keine so simple Sache die man einfach ein- und ausschalten kann, denn hier kommt es im generellen Fall immer auch auf die Reihenfolge an in der die Primitive gerendert werden (von Fern nach Nah).
mfg N¤X
Gorn
Beiträge: 10
Registriert: 24. April 2010 17:29

Beitrag von Gorn »

Das mit dem GL_ONE_MINUS_DST_ALPHA hatte ich nur mal kurz ausprobiert, hab es versehentlich nicht mehr herausgenommen. Hatte bereits vorher SRC statt DST drin, ändert leider nichts. Das mit dem Depth Test war leider auch nur ein Versuch, der nichts verändert, der Sonderfall bei dem es helfen könnte ist demnach bei mir nicht der Fall. Ich weiß auch, dass man die Objekte nach folgender Reihenfolge zeichnen sollte:
Erst alle nicht transparenten Objekte von nah nach fern, danach alle transparenten Objekte von fern nach nah.

Das ist bei mir allerdings völlig egal, da ich nur ein Objekt habe. Ich habe leider immernoch keinen Anhaltspunkt, woran es liegen könnte. Allerdings finde ich es seltsam, dass das Objekt dennoch transparent ist, auch wenn es nur so aussieht, als ob es dunkler werden würde. Konnte ich erkennen, als ich einfach eine Textur nach hinten (wie eine Wand) gelegt habe und ich die Textur durch meinen Würfel erkennen konnte. Trotzdem verstehe ich nicht warum ich die Rückwände meines eigenen Würfels nicht erkennen kann.

Hier mal ein Bild:

Bild

------------------------------------------------------

Edit:

Konnte das Problem lösen. Die Lösung war recht simpel, ich habe einfach den Würfel noch einmal gezeichnet, nur nach innen statt nach außen. Daraus erfolgte, das ich durch den Würfel die eigenen Innenwände sehen konnte.
N¤X
Beiträge: 77
Registriert: 21. September 2009 12:24

Beitrag von N¤X »

Gorn hat geschrieben:Erst alle nicht transparenten Objekte von nah nach fern, danach alle transparenten Objekte von fern nach nah.
Das wiederum ist ein bisschen zu viel des Guten, die opaken (nicht transparenten) Primitive kannst du in beliebiger Reihenfolge zeichnen. Außerdem musst du nicht die Objekte sondern die Primitive (deine Dreiecke) sortieren, denn die werden einzeln gezeichnet und geblendet.
Daher kannst du auch nicht unbedingt Displaylisten verwenden, denn die Z-Reihenfolge der Dreiecke ändert sich unter Rotation ständig, sprich eigentlich musst du die einzelnen Quads vor jedem Rendern frisch sortieren. Aber da ja eh alle gleich transparent sind sollte es in deinem Beispiel auch noch mit Displayliste (aber halt ohne Depth-Test) normal aussehen.
Gorn hat geschrieben:Trotzdem verstehe ich nicht warum ich die Rückwände meines eigenen Würfels nicht erkennen kann.
Du hast Backface-Culling aktiviert. Damit werden alle Dreiecke die du nur von Hinten sehen würdest gar nicht erst gezeichnet (in plastischen Figuren zeigen die Rückseiten eh nach Innen und werden daher normalerweise eh nicht gesehen, daher ist das bei opaken Objekten eine gute optimierung). Das erklärt auch, warum dein Würfel bei aktivierter Transparenz nur dunkler erscheint: Die Vorderseiten sind halb transparent vor dem schwarzen Hintergrund, die Rückseiten sind unsichtbar.
Lass einfach "glEnable(GL_CULL_FACE);" weg, dann sollte es auch ohne zweimaligem Zeichnen funktionieren ;)
mfg N¤X
Gorn
Beiträge: 10
Registriert: 24. April 2010 17:29

Beitrag von Gorn »

hey klasse, danke für die lösung, funktioniert jetzt auch ohne das doppelte zeichnen^^
Antworten