[Solved] Struggling with blending

Hi Guys,

I am making a 2D minecraft sort of game and all has gone well so far, but I’m stumped on something and am unable to find an answer online.

I first draw night sky image and then a day sky image on top of the night image. I then have a Sun class that returns a light level as a float which I then use to control the opacity of the night image so that it fades to night time which works fine.

The problem is that the rest of my world, ie the trees, grass, player etc still looks the same even at night. Blending is enabled in my Game class and below is what I tried but I just get a black screen. I have tried multiple blending modes to try to achieve a sort of multiply effect but nothing is working.


// Draw the overlay after everything else is drawn
		
		glBlendFunc(GL_DST_COLOR, GL_ZERO);
		glBegin(GL_QUADS);
		glColor3f(1.0f * light, 1.0f * light, 1.0f * light);
		glVertex2f(0,0);
		glVertex2f(Game.getWidth(),0);
		glVertex2f(Game.getWidth(),Game.getHeight());
		glVertex2f(0,Game.getHeight());
		glEnd();
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

I should mention that my default blend function is glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) and I would be grateful for some direction. I have tried reading about blend modes and I understand the concept but I can’t seem to get what I am looking for. I simply want to slowly darken what is already on the screen.

This nice tool helps a lot with understanding/experimenting the different blend modes:
http://www.andersriggelsen.dk/glblendfunc.php

Danny it’s an interesting tool but I cannot duplicate what I need with it either. Any other suggestions?

Have you tried using the alpha channel of the glColor function instead of modulate the rgb channels ?
With something like this :


	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0.0f, 0.0f, 0.0f, 1.0f-light);
	...

Which should draw the black rectangle with alpha of (1.0f-light), so day gives alpha of 0.0 and night 1.0.

Gef it works sort of. For some reason I can only see the effect when I hover the mouse over a block. In my player code I draw a selector which is just a sprite with a transparent center and black frame to show the selected block.

This one has no effect:

This one works as expected as my mouse is over a selectable block:

I’m so close if I could just figure this part out! If you look closely at the second image, you will notice I have a leaf block selected. When I select any block which triggers the drawing of the selector box, the darkening effect becomes visible.

EDIT: When I draw the player after drawing the overlay, the problem disappears but the player does not darken with the rest of the scene. Weird… I welcome any thoughts.

My updated drawing code:


	//float light = sun.getLightLevel();
		
		float light = 0.3f;  // Just to make it night for debugging
		
		nightSky.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);
		daySky.setTransparency(light);
		daySky.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);
		tileMap.draw();
		player.draw();
		
		// Draw the overlay
		
		quad.setColor(0, 0, 0, 1.0f-light);
		quad.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);
		/*glBegin(GL_QUADS);
		glColor4f(0.0f, 0.0f, 0.0f, 1.0f-light);
		glVertex2f(0,0);
		glVertex2f(Game.getWidth(),0);
		glVertex2f(Game.getWidth(),Game.getHeight());
		glVertex2f(0,Game.getHeight());
		glEnd();*/

Ok this one was a noobish mistake. I forgot to disable texturing when drawing the overlay.

Relevent code that now works as expected:

The Quad class draw method:


	public void draw(float x, float y)
	{
		glDisable(GL_TEXTURE_2D);
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_COLOR_ARRAY);
		
		glVertexPointer(2, 0, vertexData);
		glColorPointer(4, 0, colorData);
		
		glPushMatrix();
		glTranslatef(x,y,0);
		glDrawArrays(GL_QUADS, 0, 4);
		glPopMatrix();
		
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_COLOR_ARRAY);
		glEnable(GL_TEXTURE_2D);
	}

Gefs code from my World class:


	@Override
	public void draw()
	{
		float light = sun.getLightLevel();
		
		//float light = 0.3f;  // Just to make it night for debugging
		
		nightSky.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);
		daySky.setTransparency(light);
		daySky.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);
		tileMap.draw();
		player.draw();
		
		// Draw the overlay
		
		quad.setColor(0, 0, 0, 0.8f-light);
		quad.draw(camera.getX() + Game.getWidth() / 2, camera.getY() + Game.getHeight() / 2);

	}