Advertisement

Lightning in a 2d world?

Started by March 02, 2003 08:58 AM
5 comments, last by ProfEich 22 years ago
Hi! First I need to know how I can set an ambient light. If its dark the complete 2d world should be nearly black. If its full the complete 2d world should be full of light ^^ Then I like to set specially light. Direction light, and so on. The easyiest way is, if I''m able to create a alpha image and use it as light. Is there a way?
it depends on which API u are using for ur 2d scene since some APIs has their own support for 2d lighting.

However, the easiest way to do 2d lighting is by using a light-map which is basically nothing more than just a buffer of the same size as the screen where each value ( typically 0-255 ) will represent the light intensity of the pixel at that same location on the screen. Suppose u have a screen of size 640*480 then your light-map will be something like "byte lightmap[480][640]"

Now everytime u render the scene u blend your color buffer [ back-buffer ] with the light-map... something like this....


      for(int y=0;y<480;y++){    for(int x=0;x<640;x++){         back_buffer[y][x] = (back_buffer[y][x] * light_map[y][x])/ 255;    }}    


To add light , now, all u have to do is arrange the values of the light-map accordingly and u r done. For example, to create a spot-light effect somewhere are the center of the screen, u might draw a circle in the light-map filled with values 255 at the centre and gradually fading away at the periphery.

One major pit-fall of this technique is it's very SLOW, sometimes notoriously slow if ur screen size is big because we aren't using any hardware acceleration for the blending. However, the same technique could be taken a little further and implemented in APIs like DirectDraw and make the full use of hardware blending.

Dont forget, this is probably the easiest way of doin a cheap global lighting for 2d scenes.

[edited by - browny on March 2, 2003 10:23:12 AM]

[edited by - browny on March 2, 2003 10:26:33 AM]
Z
Advertisement
Well, I'm using OpenGL - I didn't tried it, but I'll do it later ^^

Hope OpelGL has a background_buffer which is changeable so easyly.

[Edit] Well. I don't know how to change the background buffer in OpenGL - sorry <,<

Thx

[edited by - ProfEich on March 2, 2003 10:39:20 AM]
Sorry - That became too slow <.<

Even if I just do:
[script]
GLbyte bytes[640*480*3];

glReadPixels(0,0,640,480, GL_RGB, GL_BYTE, &bytes);
glDrawPixels(640, 480, GL_RGB, GL_BYTE, &bytes);
[/script]
glReadPixels is redicously slow...
Hi.

The way I do it (in d3d) is to render all the lights as texturemapped quads to a texture, then render this texture over the level with the blendmode BLEND_ZERO-BLEND_SRCCOLOR. This looks good for white/grey lights, but it doesn''t quite do it with colored lights (the colored lights only lights pixels of it''s own color.)
/ Martin
Advertisement
It''s even to slow =( =( =(
Someone another idea:

InitDrawGame is the first thing which runs.
Then DrawGameField runs.

Part 1:

  typedef struct{	GLubyte	*imageData;	GLuint	bpp;	GLuint	width;	GLuint	height;	GLuint	texID;} TextureImage;struct Vector2I {  int X, Y;};  


Part 2:

  GLuint light;TextureImage Alpha;extern Vector2I Cursor;void DrawLight() {  int cx = Cursor.X;  int cy = Cursor.Y;  if (cx > 640) cx = 640;  if (cy > 480) cy = 480;  for (int x=0; x<640; x++)    for (int y=0; y<480; y++) {      Alpha.imageData[x + (y * 1024)] = light;      Alpha.imageData[x + ((480 - Cursor.Y) * 1024)] = 0;      Alpha.imageData[Cursor.X + (y * 1024)] = 0;    }  glBindTexture(GL_TEXTURE_2D, Alpha.texID);  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1024, 512, 0, GL_ALPHA, GL_BYTE, Alpha.imageData);  glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  glBegin(GL_QUADS);  glTexCoord2f(0,0); glVertex3f(0,0,-19);  glTexCoord2f(0,1); glVertex3f(0,512,-19);  glTexCoord2f(1,1); glVertex3f(1024,512,-19);  glTexCoord2f(1,0); glVertex3f(1024,0,-19);  glEnd();}void DrawMap() {  glBindTexture(GL_TEXTURE_2D, NULL);  glBlendFunc(GL_SRC_ALPHA,GL_ONE);  glColor4f(1,0,0,1);  glBegin(GL_QUADS);  glVertex3f(0,0,-19);  glVertex3f(0,480,-19);  glVertex3f(213,480,-19);  glVertex3f(213,0,-19);  glEnd();  glColor4f(0,1,0,1);  glBegin(GL_QUADS);  glVertex3f(213,0,-19);  glVertex3f(213,480,-19);  glVertex3f(427,480,-19);  glVertex3f(427,0,-19);  glEnd();  glColor4f(0,0,1,1);  glBegin(GL_QUADS);  glVertex3f(427,0,-19);  glVertex3f(427,480,-19);  glVertex3f(640,480,-19);  glVertex3f(640,0,-19);  glEnd();}void DrawGameField() {  DrawMap();  DrawLight();}void InitAlphaTexture() {  Alpha.width = 1024;  Alpha.height = 512;  int imageSize = 1024*512;  Alpha.imageData=(GLubyte *)malloc(imageSize);  for (int x=0; x<640; x++) {    for (int y=0; y<480; y++) {      Alpha.imageData[x + (y * 1024)] = ((float(y) / 480.0) * 128.0);    }  }  glGenTextures(1, &Alpha.texID);  glBindTexture(GL_TEXTURE_2D, Alpha.texID);  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1024, 512, 0, GL_ALPHA, GL_BYTE, Alpha.imageData);}void InitDrawGame() {  bool Error = false;  InitAlphaTexture();  light = 64;  if (Error) End();}  

This topic is closed to new replies.

Advertisement