Archived

This topic is now archived and is closed to further replies.

Lightning in a 2d world?

This topic is 5405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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();
}

Share this post


Link to post
Share on other sites