diff --git a/r_context.c b/r_context.c index f7072be2..7c22764e 100644 --- a/r_context.c +++ b/r_context.c @@ -376,6 +376,7 @@ void R_AllowFog(qboolean allowed) void GL_SetRenderMode(int mode) { + vid.rendermode = mode; /// TODO: table shading/blending??? /// maybe, setup block drawing function pointers here } diff --git a/r_draw.c b/r_draw.c index aa9c8ba7..9aeb1933 100644 --- a/r_draw.c +++ b/r_draw.c @@ -108,12 +108,12 @@ void R_DrawStretchPicImplementation (int x, int y, int w, int h, int s1, int t1, { sv = (skip + v)*(t2-t1)/h + t1; source = pic->pixels[0] + sv*pic->width + s1; - if (w == s2 - s1) - memcpy (dest, source, w * 2); - else { f = 0; fstep = s2*0x10000/w; + if( w == s2 - s1 ) + fstep = 0x10000; +#if 0 for (u=0 ; u>16]; @@ -125,6 +125,37 @@ void R_DrawStretchPicImplementation (int x, int y, int w, int h, int s1, int t1, dest[u+3] = source[f>>16]; f += fstep; } +#else + for (u=0 ; u>16]; + int alpha = vid.alpha; + + if( pic->transparent ) + { + alpha &= src >> 16 - 3; + src = src << 3; + } + + if( vid.color != COLOR_WHITE ) + src = vid.modmap[src & 0xff00|(vid.color>>8)] << 8 | (src & vid.color & 0xff) | ((src & 0xff) >> 1); + + if( vid.rendermode == kRenderTransAdd) + { + pixel_t screen = dest[u]; + dest[u] = vid.addmap[src & 0xff00|(screen>>8)] << 8 | (screen & 0xff) | ((src & 0xff) >> 0); + } + else if( alpha < 7) // && (vid.rendermode == kRenderTransAlpha || vid.rendermode == kRenderTransTexture ) ) + { + pixel_t screen = dest[u]; + dest[u] = vid.alphamap[(vid.alpha << 16)|(src & 0xff00)|(screen>>8)] << 8 | (screen & 0xff) | ((src & 0xff) >> 1); + + } + else + dest[u] = src; + f += fstep; + } +#endif } } } @@ -160,7 +191,7 @@ void R_DrawTileClear( int texnum, int x, int y, int w, int h ) image_t *pic; pixel_t *psrc, *pdest; - //GL_SetRenderMode( kRenderNormal ); + GL_SetRenderMode( kRenderNormal ); _TriColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); GL_Bind( XASH_TEXTURE0, texnum ); @@ -239,6 +270,7 @@ R_Set2DMode */ void R_Set2DMode( qboolean enable ) { + vid.color = COLOR_WHITE; if( enable ) { // if( glState.in2DMode ) diff --git a/r_glblit.c b/r_glblit.c index 776feb02..f92cd824 100644 --- a/r_glblit.c +++ b/r_glblit.c @@ -38,9 +38,103 @@ int tex; unsigned short *buffer; #define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x) -void R_InitBlit() + +void R_BuildScreenMap() { int i; +#ifdef SEPARATE_BLIT + for( i = 0; i < 256; i++ ) + { + unsigned int r,g,b; + + // 332 to 565 + r = ((i >> (8 - 3) )<< 2 ) & MASK(5); + g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); + b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); + vid.screen_major[i] = r << (6 + 5) | (g << 5) | b; + + + // restore minor GBRGBRGB + r = MOVE_BIT(i, 5, 1) | MOVE_BIT(i, 2, 0); + g = MOVE_BIT(i, 7, 2) | MOVE_BIT(i, 4, 1) | MOVE_BIT(i, 1, 0); + b = MOVE_BIT(i, 6, 2) | MOVE_BIT(i, 3, 1) | MOVE_BIT(i, 0, 0); + vid.screen_minor[i] = r << (6 + 5) | (g << 5) | b; + + } +#else + for( i = 0; i < 256; i++ ) + { + unsigned int r,g,b , major, j; + + // 332 to 565 + r = ((i >> (8 - 3) )<< 2 ) & MASK(5); + g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); + b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); + major = r << (6 + 5) | (g << 5) | b; + + + for( j = 0; j < 256; j++ ) + { + // restore minor GBRGBRGB + r = MOVE_BIT(i, 5, 1) | MOVE_BIT(i, 2, 0); + g = MOVE_BIT(i, 7, 2) | MOVE_BIT(i, 4, 1) | MOVE_BIT(i, 1, 0); + b = MOVE_BIT(i, 6, 2) | MOVE_BIT(i, 3, 1) | MOVE_BIT(i, 0, 0); + vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major; + + } + + } +#endif +} + +void R_BuildBlendMaps() +{ + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + + for( r1 = 0; r1 < BIT(3); r1++ ) + for( g1 = 0; g1 < BIT(3); g1++ ) + for( b1 = 0; b1 < BIT(2); b1++ ) + for( r2 = 0; r2 < BIT(3); r2++ ) + for( g2 = 0; g2 < BIT(3); g2++ ) + for( b2 = 0; b2 < BIT(2); b2++ ) + { + unsigned int r, g, b; + unsigned short index1 = r1 << (2 + 3) | g1 << 2 | b1; + unsigned short index2 = (r2 << (2 + 3) | g2 << 2 | b2) << 8; + unsigned int a; + + r = r1 + r2; + g = g1 + g2; + b = b1 + b2; + if( r > MASK(2) ) + r = MASK(2); + if( g > MASK(2) ) + g = MASK(2); + if( b > MASK(1) ) + b = MASK(1); + ASSERT(!vid.addmap[index2|index1]); + + vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b; + r = r1 * r2 / MASK(2); + g = g1 * g2 / MASK(2); + b = b1 * b2 / MASK(1); + vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b; + + for( a = 0; a < 8; a++ ) + { + r = r1 * a / 7 + r2 * (7 - a) / 7; + g = g1 * a / 7 + g2 * (7 - a) / 7; + b = b1 * a / 7 + b2 * (7 - a) / 7; + vid.alphamap[a << 16|index2|index1] = r << (2 + 3) | g << 2 | b; + } + + } +} + +void R_InitBlit() +{ + LOAD(glBegin); LOAD(glEnd); LOAD(glTexCoord2f); @@ -58,7 +152,7 @@ void R_InitBlit() LOAD(glGetError); LOAD(glGenTextures); LOAD(glTexParameteri); - +#ifdef GLDEBUG if( gpGlobals->developer ) { gEngfuncs.Con_Reportf( "Installing GL_DebugOutput...\n"); @@ -70,25 +164,14 @@ void R_InitBlit() // enable all the low priority messages pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); +#endif pglGenTextures( 1, &tex ); + + buffer = Mem_Malloc( r_temppool, 1920*1080*2 ); - for( i = 0; i < 256; i++ ) - { - unsigned int r,g,b; - - // 332 to 565 - r = ((i >> (8 - 3) )<< 2 ) & MASK(5); - g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); - b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); - vid.screen_major[i] = r << (6 + 5) | (g << 5) | b; - - // restore minor GBRGBRGB - r = MOVE_BIT(i, 5, 1) | MOVE_BIT(i, 2, 0); - g = MOVE_BIT(i, 7, 2) | MOVE_BIT(i, 4, 1) | MOVE_BIT(i, 1, 0); - b = MOVE_BIT(i, 6, 2) | MOVE_BIT(i, 3, 1) | MOVE_BIT(i, 0, 0); - vid.screen_minor[i] = r << (6 + 5) | (g << 5) | b; - } + R_BuildScreenMap(); + R_BuildBlendMaps(); } void R_BlitScreen() @@ -99,11 +182,18 @@ void R_BlitScreen() for( i = 0; i < vid.width * vid.height;i++) { +#ifdef SEPARATE_BLIT + // need only 1024 bytes table, but slower + // wtf?? maybe some prefetch??? byte major = buf[(i<<1)+1]; byte minor = buf[(i<<1)]; - buffer[i] = vid.screen_major[major]|vid.screen_minor[minor]; + buffer[i] = vid.screen_major[major] |vid.screen_minor[minor]; +#else + buffer[i] = vid.screen[vid.buffer[i]]; +#endif } + pglBindTexture(GL_TEXTURE_2D, tex); pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); pglMatrixMode( GL_PROJECTION ); @@ -119,6 +209,7 @@ void R_BlitScreen() pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //gEngfuncs.Con_Printf("%d\n",pglGetError()); + pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vid.width, vid.height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer ); //gEngfuncs.Con_Printf("%d\n",pglGetError()); pglBegin( GL_QUADS ); @@ -136,4 +227,5 @@ void R_BlitScreen() pglEnd(); pglDisable( GL_TEXTURE_2D ); gEngfuncs.GL_SwapBuffers(); + memset( vid.buffer, 0, vid.width * vid.height * 2 ); } diff --git a/r_image.c b/r_image.c index 778ce912..07900cbf 100644 --- a/r_image.c +++ b/r_image.c @@ -220,7 +220,7 @@ static void GL_SetTextureFormat( image_t *tex, pixformat_t format, int channelMa qboolean haveAlpha = ( channelMask & IMAGE_HAS_ALPHA ); Assert( tex != NULL ); - tex->transparent = !!( channelMask & IMAGE_HAS_ALPHA ); + //tex->transparent = !!( channelMask & IMAGE_HAS_ALPHA ); } /* @@ -509,16 +509,26 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic ) if( !pic->buffer ) return true; + /// TODO: generate mipmaps + + if( tex->flags & TF_HAS_ALPHA ) + tex->transparent = true; + tex->pixels[0] = Mem_Calloc( r_temppool, tex->width * tex->height * sizeof(pixel_t) + 64 ); for( i = 0; i < tex->width * tex->height; i++ ) { unsigned int r, g, b, major, minor; - +#if 0 + r = pic->buffer[i * 4 + 0] * MASK(5-1) / 255; + g = pic->buffer[i * 4 + 1] * MASK(6-1) / 255; + b = pic->buffer[i * 4 + 2] * MASK(5-1) / 255; +#else + // seems to look better r = pic->buffer[i * 4 + 0] * BIT(5) / 256; g = pic->buffer[i * 4 + 1] * BIT(6) / 256; b = pic->buffer[i * 4 + 2] * BIT(5) / 256; - +#endif // 565 to 332 major = (((r >> 2) & MASK(3)) << 5) |( (( (g >> 3) & MASK(3)) << 2 ) )| (((b >> 3) & MASK(2))); @@ -526,9 +536,14 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic ) minor = MOVE_BIT(r,1,5) | MOVE_BIT(r,0,2) | MOVE_BIT(g,2,7) | MOVE_BIT(g,1,4) | MOVE_BIT(g,0,1) | MOVE_BIT(b,2,6)| MOVE_BIT(b,1,3)|MOVE_BIT(b,0,0); tex->pixels[0][i] = major << 8 | (minor & 0xFF); + if( tex->transparent ) + { + unsigned int alpha = (pic->buffer[i * 4 + 3] * 8 / 256) << (16 - 3); + tex->pixels[0][i] = (tex->pixels[0][i] >> 3) | alpha; + } } - /// TODO: generate mipmaps + #if 0 diff --git a/r_local.h b/r_local.h index 7058201f..1548f63e 100644 --- a/r_local.h +++ b/r_local.h @@ -124,13 +124,27 @@ typedef struct vrect_s struct vrect_s *pnext; } vrect_t; +#define COLOR_WHITE 0xFFFF +#define SEPARATE_BLIT typedef struct { pixel_t *buffer; // invisible buffer pixel_t *colormap; // 256 * VID_GRADES size - pixel_t *alphamap; // 256 * 256 translucency map + //pixel_t *alphamap; // 256 * 256 translucency map +#ifdef SEPARATE_BLIT pixel_t screen_minor[256]; pixel_t screen_major[256]; +#else + pixel_t screen[256*256]; +#endif + byte addmap[256*256]; + byte modmap[256*256]; + pixel_t alphamap[8*256*256]; + pixel_t color; + byte alpha; + + // maybe compute colormask for minor byte? + int rendermode; int rowbytes; // may be > width if displayed in a window // can be negative for stupid dibs int width; diff --git a/r_triapi.c b/r_triapi.c index 1ff6f817..1ee810b4 100644 --- a/r_triapi.c +++ b/r_triapi.c @@ -39,7 +39,7 @@ set rendermode */ void TriRenderMode( int mode ) { - ds.renderMode = mode; + ds.renderMode = vid.rendermode = mode; #if 0 switch( mode ) { @@ -130,9 +130,29 @@ _TriColor4f ============= */ -void _TriColor4f( float r, float g, float b, float a ) +void _TriColor4f( float rr, float gg, float bb, float aa ) { //pglColor4f( r, g, b, a ); + unsigned short r,g,b; + + if( rr == 1 && gg == 1 && bb == 1 ) + { + vid.color = COLOR_WHITE; + return; + } + + r = rr * 31, g = gg * 63, b = bb * 31; + + vid.alpha = aa * 7; + if( vid.alpha > 7 ) + vid.alpha = 7; + + unsigned int major = (((r >> 2) & MASK(3)) << 5) |( (( (g >> 3) & MASK(3)) << 2 ) )| (((b >> 3) & MASK(2))); + + // save minor GBRGBRGB + unsigned int minor = MOVE_BIT(r,1,5) | MOVE_BIT(r,0,2) | MOVE_BIT(g,2,7) | MOVE_BIT(g,1,4) | MOVE_BIT(g,0,1) | MOVE_BIT(b,2,6)| MOVE_BIT(b,1,3)|MOVE_BIT(b,0,0); + + vid.color = major << 8 | (minor & 0xFF); } /* @@ -148,7 +168,7 @@ void TriColor4ub( byte r, byte g, byte b, byte a ) ds.triRGBA[2] = b * (1.0f / 255.0f); ds.triRGBA[3] = a * (1.0f / 255.0f); - _TriColor4f( ds.triRGBA[0], ds.triRGBA[1], ds.triRGBA[2], 1.0f ); + _TriColor4f( ds.triRGBA[0], ds.triRGBA[1], ds.triRGBA[2], ds.triRGBA[3] ); //1.0f ); } /*