implemented alpha blending (hopefully correctly!)

master
Bartek Kostrzewa 2010-11-22 17:41:21 +01:00
parent ce8c4e74ae
commit f3fdb74d03
3 changed files with 39 additions and 22 deletions

View File

@ -24,7 +24,7 @@ UDPSock.bind((outgoing_if, local_port))
segments = open('segments','r') segments = open('segments','r')
alpha = chr(255) alpha = chr(125)
z_buffer = chr(1) + "\n" z_buffer = chr(1) + "\n"

View File

@ -164,6 +164,7 @@ void Server::mix()
while(1) while(1)
{ {
frame_t temp_frame; frame_t temp_frame;
float temp_alpha;
// we lock the buffers for a long time, but we need to make sure // we lock the buffers for a long time, but we need to make sure
// that none of the buffers is allowed to expire while we're working on it! // that none of the buffers is allowed to expire while we're working on it!
@ -179,9 +180,6 @@ void Server::mix()
{ {
for(int a = 0; a < CHANNELS; a++) for(int a = 0; a < CHANNELS; a++)
{ {
if( a == CHANNELS-1 )
frame.windows[i][j][a] = 255;
else
frame.windows[i][j][a] = 0; frame.windows[i][j][a] = 0;
} }
} }
@ -193,15 +191,13 @@ void Server::mix()
{ {
for(int a = 0; a < SEGCHANNELS; a++) for(int a = 0; a < SEGCHANNELS; a++)
{ {
if(a == SEGCHANNELS-1 )
frame.segments[w][n][a] = 255;
else
frame.segments[w][n][a] = 0; frame.segments[w][n][a] = 0;
} }
} }
} // zero out frame } // zero out frame
// implement alpha blending
for(int x = 0; x < size; x++) for(int x = 0; x < size; x++)
{ {
temp_frame = buffers[x]->get(); temp_frame = buffers[x]->get();
@ -209,12 +205,17 @@ void Server::mix()
{ {
for(int j = 0; j < WIDTH; j++) for(int j = 0; j < WIDTH; j++)
{ {
for(int a = 0; a < CHANNELS-1; a++) temp_alpha = (float)temp_frame.windows[i][j][CHANNELS-1]/255;
for(int a = 0; a < CHANNELS; a++)
{ {
// do something interesting here // this works for the colors and for the alpha channel
pixel = frame.windows[i][j][a] + (float)temp_frame.windows[i][j][CHANNELS-1]/255*temp_frame.windows[i][j][a]; pixel = (1-temp_alpha)*frame.windows[i][j][a] + temp_alpha*temp_frame.windows[i][j][a];
//make sure we don't do anything silly
if( pixel >= 255 ) if( pixel >= 255 )
frame.windows[i][j][a] = 255; frame.windows[i][j][a] = 255;
else if( pixel <= 0 )
frame.windows[i][j][a] = 0;
else else
frame.windows[i][j][a] = pixel; frame.windows[i][j][a] = pixel;
} }
@ -225,11 +226,17 @@ void Server::mix()
{ {
for(int n = 0;n < SEGNUM; n++) for(int n = 0;n < SEGNUM; n++)
{ {
for(int a = 0; a < SEGCHANNELS-1; a++) temp_alpha = (float)temp_frame.segments[w][n][SEGCHANNELS-1]/255;
for(int a = 0; a < SEGCHANNELS; a++)
{ {
pixel = frame.segments[w][n][a] + (float)temp_frame.segments[w][n][SEGCHANNELS-1]/255*temp_frame.segments[w][n][a]; // this works for the colors and for the alpha channel
pixel = (1-temp_alpha)*frame.segments[w][n][a] + temp_alpha*temp_frame.segments[w][n][a];
// make sure we don't make silly mistakes
if( pixel >= 255 ) if( pixel >= 255 )
frame.segments[w][n][a] = 255; frame.segments[w][n][a] = 255;
else if( pixel <= 0 )
frame.segments[w][n][a] = 0;
else else
frame.segments[w][n][a] = pixel; frame.segments[w][n][a] = pixel;
} }
@ -237,6 +244,8 @@ void Server::mix()
} }
} }
// temp frame has validity in the loop only so it can be safely used without locking the whole object // temp frame has validity in the loop only so it can be safely used without locking the whole object
// we do this in case output() takes a long time to return. If it read frame directly, we'd end up
// waiting for a long time
temp_frame = frame; temp_frame = frame;
} // release lock and send off to hardware } // release lock and send off to hardware
output(temp_frame); output(temp_frame);
@ -303,7 +312,7 @@ void Server::input()
// now we need to lock data structure because we're going to use shared objects // now we need to lock data structure because we're going to use shared objects
{ {
Glib::Mutex::Lock lock(mutex_);
switch(c) switch(c)
{ {
case KEY_F(2): case KEY_F(2):
@ -320,11 +329,14 @@ void Server::input()
break; break;
case '0': case '0':
default: default:
{
Glib::Mutex::Lock lock(mutex_);
console_input = c; console_input = c;
} }
} }
} }
} }
}
/* the console functions should only be used in the console thread, they don't /* the console functions should only be used in the console thread, they don't
* implement their own locking and they need ncurses to be initialised */ * implement their own locking and they need ncurses to be initialised */
@ -428,8 +440,15 @@ void Server::console_printframe_values(frame_t _frame)
void Server::console_printclients() void Server::console_printclients()
{ {
int rows, cols, offset=0;
getmaxyx(stdscr,rows,cols);
for(int i = 0; i < buffers.size(); i++) for(int i = 0; i < buffers.size(); i++)
mvprintw(i+2,0,"(%3d) %s\n", i,buffers[i]->get_id().c_str() ); {
if(i >= 1 && i%(rows-2)==0)
offset += 27;
if( offset + 27 < cols )
mvprintw(i%(rows-2)+2,offset,"(%3d) %s\n", i,buffers[i]->get_id().c_str() );
}
} }

View File

@ -56,8 +56,6 @@ private:
int get_size(); int get_size();
void expire(); void expire();
bool consoleinit; bool consoleinit;
int console_input; int console_input;
long displaycounter, packetcounter; long displaycounter, packetcounter;