Blending

In deze tutorial zal ik je laten zien hoe je blending toe kunt passen in je scenes waardoor transparante voorwerpen mogelijk worden. Hieronder vind je een deel van de sourcecode met de nodige uitleg.


///////////////////////////////////////////////////////////////////////////////
//box1
///////////////////////////////////////////////////////////////////////////////
void box1(float xpos,float ypos,float zpos)
{
	glPushMatrix();
		glColor4f(1.0f,1.0f,1.0f, 0.3f);
		glTranslatef(xpos,ypos,zpos);
		glScalef(1.0f,1.0f,1.0f);
		glRotatef(hoek, 1.0f,1.0f,1.0f);
		box(0.0f,0.0f,0.0f);
	glPopMatrix();
}

///////////////////////////////////////////////////////////////////////////////
//box2
///////////////////////////////////////////////////////////////////////////////
void box2(float xpos,float ypos,float zpos)
{
	glPushMatrix();
		glColor4f(1.0f,1.0f,1.0f, 0.8f);
		glTranslatef(xpos,ypos,zpos);
		glScalef(1.0f,1.0f,1.0f);
		glRotatef(hoek, 1.0f,1.0f,1.0f);
		box(0.0f,0.0f,0.0f);
	glPopMatrix();
}
De eerste veranderingen komen we tegen bij de 2 voorwerpen waar we nu in plaats van glColor3f glColor4f tegenkomen. De nieuwe parameter die er bij is gekomen is voor de transparantie van het voorwerp, hoe kleiner het getal hoe meer doorzichtig het voorwerp is. Voordat we deze functie echter kunnen gebruiken moeten we nog een paar instellingen doen in de initgl() functie.

///////////////////////////////////////////////////////////////////////////////
//initialisatie van opengl
///////////////////////////////////////////////////////////////////////////////
void initgl()
{
	glClearColor(0.0f,0.0f,0.0f,0.0f);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	float ambientlight[]={0.5f,1.0f,0.5f,1.0f};

	float position[]={2.0f,3.0f,3.0f,1.0f};
	float direction[]={0.0f,0.0f,-1.0f};

	float matspecular[]={1.0f,1.0f,1.0f,1.0f};

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientlight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, ambientlight);

	glLightfv(GL_LIGHT0, GL_POSITION, position);

	glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 40.0f);
	glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 30.0f);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction);

	glEnable(GL_LIGHT0);

	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	glMaterialfv(GL_FRONT, GL_SPECULAR, matspecular);
	glMaterialf(GL_FRONT, GL_SHININESS, 10.0f);
	
}
Om blending mogelijk te maken moeten we dit eerst inschakelen met glEnable(GL_BLEND); en kunnen we hierna met de glBlendFunc() functie de blending opties instellen. Voor een complete lijst van de opties kun je zoals altijd terecht bij de referenties van OpenGL. Als je dit (allemaal) hebt ingesteld ben je klaar om blending te gebruiken in je scenes. Er is echter nog een klein ding waar je aan moet denken wat grote gevolgen kan hebben.

Je weet dat door de diepte buffer voorwerpen die achter andere voorwerpen zitten niet gerendert worden. Je begrijpt nu natuurlijk wel dat als een voorwerp doorzichtig is en voorwerpen daarachter niet gerendert worden je scene er niet uitziet. Wat we hieraan kunnen doen is de diepte buffer op read only te zetten wanneer de transparante voorwerpen worden gerendert. Als we het op deze manier doen worden de gegevens in de diepte buffer niet verandert en zal de scene er goed uit blijven zijn. Dit hebben we dus ook gedaan in de code hieronder.


/////////////////////////////////////////////////////////////////////
//Rendering
/////////////////////////////////////////////////////////////////////
void render()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glPushMatrix();
		glLoadIdentity();
		glTranslatef(0.0f,0.0f,-10.0f);

		glDepthMask(GL_FALSE);
		glBindTexture(GL_TEXTURE_2D, water);
		box2(-0.5f,-0.5f,0.0f);
		glDepthMask(GL_TRUE);

		glBindTexture(GL_TEXTURE_2D, land);
		box1(-3.0f,-3.0f,-10.0f);		
	glPopMatrix();
	
	hoek += 0.1f;
	if (hoek == 360.0f)
	{hoek = 0.0;}

	glFlush();
	SwapBuffers(g_HDC);	
}



Door glDepthMask() false te maken wordt de diepte buffer uitgeschakeld en kunnen we de doorzichte voorwerpen renderen.

Succes

Vampire,