|
|
@ -1,6 +1,13 @@ |
|
|
|
#include "r_local.h" |
|
|
|
#include "r_local.h" |
|
|
|
#include "../ref_gl/gl_export.h" |
|
|
|
#include "../ref_gl/gl_export.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct swblit_s |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint stride; |
|
|
|
|
|
|
|
uint bpp; |
|
|
|
|
|
|
|
uint rmask, gmask, bmask; |
|
|
|
|
|
|
|
} swblit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
======================== |
|
|
|
======================== |
|
|
@ -38,9 +45,35 @@ unsigned short *buffer; |
|
|
|
|
|
|
|
|
|
|
|
#define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x) |
|
|
|
#define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x) |
|
|
|
|
|
|
|
|
|
|
|
void R_BuildScreenMap() |
|
|
|
static int FIRST_BIT( uint mask ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; !(BIT(i) & mask); i++ ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return i; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int COUNT_BITS( uint mask ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; mask; mask = mask >> 1 ) |
|
|
|
|
|
|
|
i += mask & 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return i; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void R_BuildScreenMap( void ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
uint rshift = FIRST_BIT(swblit.rmask), gshift = FIRST_BIT(swblit.gmask), bshift = FIRST_BIT(swblit.bmask); |
|
|
|
|
|
|
|
uint rbits = COUNT_BITS(swblit.rmask), gbits = COUNT_BITS(swblit.gmask), bbits = COUNT_BITS(swblit.bmask); |
|
|
|
|
|
|
|
uint rmult = BIT(rbits), gmult = BIT(gbits), bmult = BIT(bbits); |
|
|
|
|
|
|
|
uint rdiv = MASK(5), gdiv = MASK(6), bdiv = MASK(5); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gEngfuncs.Con_Printf("Blit table: %d %d %d %d %d %d\n", rmult, gmult, bmult, rdiv, gdiv, bdiv ); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef SEPARATE_BLIT |
|
|
|
#ifdef SEPARATE_BLIT |
|
|
|
for( i = 0; i < 256; i++ ) |
|
|
|
for( i = 0; i < 256; i++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -69,16 +102,24 @@ void R_BuildScreenMap() |
|
|
|
r = ((i >> (8 - 3) )<< 2 ) & MASK(5); |
|
|
|
r = ((i >> (8 - 3) )<< 2 ) & MASK(5); |
|
|
|
g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); |
|
|
|
g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); |
|
|
|
b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); |
|
|
|
b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); |
|
|
|
major = r << (6 + 5) | (g << 5) | b; |
|
|
|
//major = r << (6 + 5) | (g << 5) | b;
|
|
|
|
|
|
|
|
major = (r * rmult / rdiv) << rshift | (g * gmult / gdiv) << gshift | (b * bmult / bdiv) << bshift; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( j = 0; j < 256; j++ ) |
|
|
|
for( j = 0; j < 256; j++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
uint minor; |
|
|
|
// restore minor GBRGBRGB
|
|
|
|
// restore minor GBRGBRGB
|
|
|
|
r = MOVE_BIT(j, 5, 1) | MOVE_BIT(j, 2, 0); |
|
|
|
r = MOVE_BIT(j, 5, 1) | MOVE_BIT(j, 2, 0); |
|
|
|
g = MOVE_BIT(j, 7, 2) | MOVE_BIT(j, 4, 1) | MOVE_BIT(j, 1, 0); |
|
|
|
g = MOVE_BIT(j, 7, 2) | MOVE_BIT(j, 4, 1) | MOVE_BIT(j, 1, 0); |
|
|
|
b = MOVE_BIT(j, 6, 2) | MOVE_BIT(j, 3, 1) | MOVE_BIT(j, 0, 0); |
|
|
|
b = MOVE_BIT(j, 6, 2) | MOVE_BIT(j, 3, 1) | MOVE_BIT(j, 0, 0); |
|
|
|
vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major; |
|
|
|
//vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major;
|
|
|
|
|
|
|
|
minor = (r * rmult / rdiv) << rshift | (g * gmult / gdiv) << gshift | (b * bmult / bdiv) << bshift; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( swblit.bpp == 2 ) |
|
|
|
|
|
|
|
vid.screen[(i<<8)|j] = major | minor; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
vid.screen32[(i<<8)|j] = major | minor; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -103,18 +144,18 @@ void R_BuildBlendMaps() |
|
|
|
r = r1 + r2; |
|
|
|
r = r1 + r2; |
|
|
|
g = g1 + g2; |
|
|
|
g = g1 + g2; |
|
|
|
b = b1 + b2; |
|
|
|
b = b1 + b2; |
|
|
|
if( r > MASK(2) ) |
|
|
|
if( r > MASK(3) ) |
|
|
|
r = MASK(2); |
|
|
|
r = MASK(3); |
|
|
|
if( g > MASK(2) ) |
|
|
|
if( g > MASK(3) ) |
|
|
|
g = MASK(2); |
|
|
|
g = MASK(3); |
|
|
|
if( b > MASK(1) ) |
|
|
|
if( b > MASK(2) ) |
|
|
|
b = MASK(1); |
|
|
|
b = MASK(2); |
|
|
|
ASSERT(!vid.addmap[index2|index1]); |
|
|
|
ASSERT(!vid.addmap[index2|index1]); |
|
|
|
|
|
|
|
|
|
|
|
vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b; |
|
|
|
vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b; |
|
|
|
r = r1 * r2 / MASK(2); |
|
|
|
r = r1 * r2 / MASK(3); |
|
|
|
g = g1 * g2 / MASK(2); |
|
|
|
g = g1 * g2 / MASK(3); |
|
|
|
b = b1 * b2 / MASK(1); |
|
|
|
b = b1 * b2 / MASK(2); |
|
|
|
|
|
|
|
|
|
|
|
vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b; |
|
|
|
vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b; |
|
|
|
|
|
|
|
|
|
|
@ -130,10 +171,12 @@ void R_BuildBlendMaps() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void R_AllocScreen(); |
|
|
|
|
|
|
|
|
|
|
|
void R_InitBlit() |
|
|
|
void R_InitBlit() |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
LOAD(glBegin); |
|
|
|
/*LOAD(glBegin);
|
|
|
|
LOAD(glEnd); |
|
|
|
LOAD(glEnd); |
|
|
|
LOAD(glTexCoord2f); |
|
|
|
LOAD(glTexCoord2f); |
|
|
|
LOAD(glVertex2f); |
|
|
|
LOAD(glVertex2f); |
|
|
@ -149,7 +192,7 @@ void R_InitBlit() |
|
|
|
LOAD(glDebugMessageControlARB); |
|
|
|
LOAD(glDebugMessageControlARB); |
|
|
|
LOAD(glGetError); |
|
|
|
LOAD(glGetError); |
|
|
|
LOAD(glGenTextures); |
|
|
|
LOAD(glGenTextures); |
|
|
|
LOAD(glTexParameteri); |
|
|
|
LOAD(glTexParameteri);*/ |
|
|
|
#ifdef GLDEBUG |
|
|
|
#ifdef GLDEBUG |
|
|
|
if( gpGlobals->developer ) |
|
|
|
if( gpGlobals->developer ) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -164,36 +207,100 @@ void R_InitBlit() |
|
|
|
pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); |
|
|
|
pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
buffer = Mem_Malloc( r_temppool, 1920*1080*2 ); |
|
|
|
//buffer = Mem_Malloc( r_temppool, 1920*1080*2 );
|
|
|
|
|
|
|
|
|
|
|
|
R_BuildScreenMap(); |
|
|
|
|
|
|
|
R_BuildBlendMaps(); |
|
|
|
R_BuildBlendMaps(); |
|
|
|
d_pzbuffer = malloc(vid.width*vid.height*2); |
|
|
|
R_AllocScreen(); |
|
|
|
R_InitCaches(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void R_AllocScreen() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( gpGlobals->width < 320 ) |
|
|
|
|
|
|
|
gpGlobals->width = 320; |
|
|
|
|
|
|
|
if( gpGlobals->height < 200 ) |
|
|
|
|
|
|
|
gpGlobals->height = 200; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
R_InitCaches(); |
|
|
|
|
|
|
|
gEngfuncs.SW_CreateBuffer( gpGlobals->width, gpGlobals->height, &swblit.stride, &swblit.bpp, |
|
|
|
|
|
|
|
&swblit.rmask, &swblit.gmask, &swblit.bmask); |
|
|
|
|
|
|
|
R_BuildScreenMap(); |
|
|
|
|
|
|
|
vid.width = gpGlobals->width; |
|
|
|
|
|
|
|
vid.height = gpGlobals->height; |
|
|
|
|
|
|
|
vid.rowbytes = gpGlobals->width; // rowpixels
|
|
|
|
|
|
|
|
if( d_pzbuffer ) |
|
|
|
|
|
|
|
Mem_Free( d_pzbuffer ); |
|
|
|
|
|
|
|
d_pzbuffer = Mem_Calloc( r_temppool, vid.width*vid.height*2 + 64 ); |
|
|
|
|
|
|
|
if( vid.buffer ) |
|
|
|
|
|
|
|
Mem_Free( vid.buffer ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vid.buffer = Mem_Malloc( r_temppool, vid.width * vid.height*sizeof( pixel_t ) ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void R_BlitScreen() |
|
|
|
void R_BlitScreen() |
|
|
|
{ |
|
|
|
{ |
|
|
|
//memset( vid.buffer, 10, vid.width * vid.height );
|
|
|
|
//memset( vid.buffer, 10, vid.width * vid.height );
|
|
|
|
int i; |
|
|
|
int u, v; |
|
|
|
byte *buf = vid.buffer; |
|
|
|
void *buffer = gEngfuncs.SW_LockBuffer(); |
|
|
|
|
|
|
|
if( !buffer || gpGlobals->width != vid.width || gpGlobals->height != vid.height ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
R_AllocScreen(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//byte *buf = vid.buffer;
|
|
|
|
|
|
|
|
|
|
|
|
#pragma omp parallel for schedule(static) |
|
|
|
//#pragma omp parallel for schedule(static)
|
|
|
|
for( i = 0; i < vid.width * vid.height;i++) |
|
|
|
if( swblit.bpp == 2 ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
#ifdef SEPARATE_BLIT |
|
|
|
unsigned short *pbuf = buffer; |
|
|
|
// need only 1024 bytes table, but slower
|
|
|
|
for( v = 0; v < vid.height;v++) |
|
|
|
// wtf?? maybe some prefetch???
|
|
|
|
{ |
|
|
|
byte major = buf[(i<<1)+1]; |
|
|
|
uint start = vid.rowbytes * v; |
|
|
|
byte minor = buf[(i<<1)]; |
|
|
|
uint dstart = swblit.stride * v; |
|
|
|
|
|
|
|
|
|
|
|
buffer[i] = vid.screen_major[major] |vid.screen_minor[minor]; |
|
|
|
for( u = 0; u < vid.width; u++ ) |
|
|
|
#else |
|
|
|
{ |
|
|
|
buffer[i] = vid.screen[vid.buffer[i]]; |
|
|
|
unsigned int s = vid.screen[vid.buffer[start + u]]; |
|
|
|
#endif |
|
|
|
pbuf[dstart + u] = s; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if( swblit.bpp == 4 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
unsigned int *pbuf = buffer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( v = 0; v < vid.height;v++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint start = vid.rowbytes * v; |
|
|
|
|
|
|
|
uint dstart = swblit.stride * v; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( u = 0; u < vid.width; u++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
unsigned int s = vid.screen32[vid.buffer[start + u]]; |
|
|
|
|
|
|
|
pbuf[dstart + u] = s; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if( swblit.bpp == 3 ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
byte *pbuf = buffer; |
|
|
|
|
|
|
|
for( v = 0; v < vid.height;v++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint start = vid.rowbytes * v; |
|
|
|
|
|
|
|
uint dstart = swblit.stride * v; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( u = 0; u < vid.width; u++ ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
unsigned int s = vid.screen32[vid.buffer[start + u]]; |
|
|
|
|
|
|
|
pbuf[(dstart+u)*3] = s; |
|
|
|
|
|
|
|
s = s >> 8; |
|
|
|
|
|
|
|
pbuf[(dstart+u)*3+1] = s; |
|
|
|
|
|
|
|
s = s >> 8; |
|
|
|
|
|
|
|
pbuf[(dstart+u)*3+2] = s; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); |
|
|
|
pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); |
|
|
|
pglMatrixMode( GL_PROJECTION ); |
|
|
|
pglMatrixMode( GL_PROJECTION ); |
|
|
|
pglLoadIdentity(); |
|
|
|
pglLoadIdentity(); |
|
|
@ -223,4 +330,7 @@ void R_BlitScreen() |
|
|
|
pglDisable( GL_TEXTURE_2D ); |
|
|
|
pglDisable( GL_TEXTURE_2D ); |
|
|
|
gEngfuncs.GL_SwapBuffers(); |
|
|
|
gEngfuncs.GL_SwapBuffers(); |
|
|
|
// memset( vid.buffer, 0, vid.width * vid.height * 2 );
|
|
|
|
// memset( vid.buffer, 0, vid.width * vid.height * 2 );
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
gEngfuncs.SW_UnlockBuffer(); |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|