diff --git a/r_context.c b/r_context.c index 55e8ff12..f7072be2 100644 --- a/r_context.c +++ b/r_context.c @@ -623,6 +623,13 @@ qboolean R_Init() { gl_emboss_scale = gEngfuncs.Cvar_Get( "gl_emboss_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "fake bumpmapping scale" ); // create the window and set up the context + r_temppool = Mem_AllocPool( "ref_sw zone" ); + + vid.width = 1920; + vid.height = 1080; + vid.rowbytes = 1920; // rowpixels + + vid.buffer = Mem_Malloc( r_temppool, 1920*1080*sizeof( pixel_t ) ); if( !gEngfuncs.R_Init_Video( REF_GL )) // request GL context { gEngfuncs.R_Free_Video(); @@ -630,12 +637,7 @@ qboolean R_Init() gEngfuncs.Host_Error( "Can't initialize video subsystem\nProbably driver was not installed" ); return false; } - r_temppool = Mem_AllocPool( "ref_sw zone" ); - vid.width = 1920; - vid.height = 1080; - vid.rowbytes = 1920; // rowpixels - vid.buffer = Mem_Malloc( r_temppool, 1920*1080*sizeof( pixel_t ) ); R_InitImages(); return true; diff --git a/r_glblit.c b/r_glblit.c index 9e8214d1..776feb02 100644 --- a/r_glblit.c +++ b/r_glblit.c @@ -35,10 +35,12 @@ static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLui } } int tex; +unsigned short *buffer; #define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x) void R_InitBlit() { + int i; LOAD(glBegin); LOAD(glEnd); LOAD(glTexCoord2f); @@ -69,12 +71,39 @@ void R_InitBlit() // enable all the low priority messages pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); 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; + } +} void R_BlitScreen() { //memset( vid.buffer, 10, vid.width * vid.height ); + int i; + byte *buf = vid.buffer; + + for( i = 0; i < vid.width * vid.height;i++) + { + byte major = buf[(i<<1)+1]; + byte minor = buf[(i<<1)]; + + buffer[i] = vid.screen_major[major]|vid.screen_minor[minor]; + } pglBindTexture(GL_TEXTURE_2D, tex); pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); pglMatrixMode( GL_PROJECTION ); @@ -90,7 +119,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, vid.buffer ); + 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 ); pglTexCoord2f( 0, 0 ); diff --git a/r_image.c b/r_image.c index 166060bc..778ce912 100644 --- a/r_image.c +++ b/r_image.c @@ -503,24 +503,34 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic ) gEngfuncs.Con_Printf("%s %d %d\n", tex->name, tex->width, tex->height ); + Assert( pic != NULL ); + Assert( tex != NULL ); + if( !pic->buffer ) return 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; + unsigned int r, g, b, major, minor; + 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; - /// TODO: use internal rgb565-based palette for textures and screen - tex->pixels[0][i] = r << (6 + 5) | (g << 5) | b; + // 565 to 332 + major = (((r >> 2) & MASK(3)) << 5) |( (( (g >> 3) & MASK(3)) << 2 ) )| (((b >> 3) & MASK(2))); + + // save minor GBRGBRGB + 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); } + /// TODO: generate mipmaps #if 0 - Assert( pic != NULL ); - Assert( tex != NULL ); + GL_SetTextureTarget( tex, pic ); // must be first diff --git a/r_local.h b/r_local.h index 62b7a668..7058201f 100644 --- a/r_local.h +++ b/r_local.h @@ -88,6 +88,11 @@ extern byte *r_temppool; #define CULL_VISFRAME 3 // culled by PVS #define CULL_OTHER 4 // culled by other reason +// bit operation helpers +#define MASK(x) (BIT(x+1)-1) +#define GET_BIT(s,b) ((s & (1 << b)) >> b) +#define MOVE_BIT(s, f, t) (GET_BIT(s,f) << t ) + /* skins will be outline flood filled and mip mapped @@ -124,6 +129,8 @@ typedef struct pixel_t *buffer; // invisible buffer pixel_t *colormap; // 256 * VID_GRADES size pixel_t *alphamap; // 256 * 256 translucency map + pixel_t screen_minor[256]; + pixel_t screen_major[256]; int rowbytes; // may be > width if displayed in a window // can be negative for stupid dibs int width;