Hi,

I have added support for 24bit displays to wmesa.c.
I have tested building it with VC9 and mingw compilers and running the built dlls
for some simple rendering and readbacks with a 24bit display.

Basically I have copied the 32bit support and just updated the pointer arithmetic, although because there isn't a basic 3 byte type, I write each byte separately as a BYTE.

I passed the cColorBits to the wmesa_set_renderbuffer_funcs as both 24bit and 32bit are using
the same pixelformat.

This is a patch against Mesa-7.1

Shane.

Only in Mesa-7.1-mingw-24bit: .cproject
--- Mesa-7.1/src/mesa/drivers/windows/gdi/wmesa.c       2008-08-26 
02:46:44.000000000 +1200
+++ Mesa-7.1-mingw-24bit/src/mesa/drivers/windows/gdi/wmesa.c   2008-09-11 
12:36:29.273735200 +1200
@@ -116,19 +116,21 @@
     pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
 
     /* Only 16 and 32 bit targets are supported now */
     assert(pwfb->cColorBits == 0 ||
           pwfb->cColorBits == 16 || 
+          pwfb->cColorBits == 24 || 
           pwfb->cColorBits == 32);
 
     switch(pwfb->cColorBits){
     case 8:
        pwfb->pixelformat = PF_INDEX8;
        break;
     case 16:
        pwfb->pixelformat = PF_5R6G5B;
        break;
+    case 24:
     case 32:
        pwfb->pixelformat = PF_8R8G8B;
        break;
     default:
        pwfb->pixelformat = PF_BADFORMAT;
@@ -854,10 +856,199 @@
 }
 
 
 /*********************************************************************/
 
+/* DOUBLE BUFFER 24-bit */
+
+#define WMSETPIXEL24(pwc, y, x, r, g, b) { \
+LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
+lpb[0] = (b); \
+lpb[1] = (g); \
+lpb[2] = (r); }
+
+/* Write a horizontal span of RGBA color pixels with a boolean mask. */
+static void write_rgba_span_24(const GLcontext *ctx, 
+                              struct gl_renderbuffer *rb, 
+                              GLuint n, GLint x, GLint y,
+                              const GLubyte rgba[][4], 
+                              const GLubyte mask[] )
+{
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    GLuint i;
+    LPBYTE lpb;
+
+    (void) ctx;
+    
+    y=FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+                lpb[3*i] = rgba[i][BCOMP];
+                lpb[3*i+1] = rgba[i][GCOMP];
+                lpb[3*i+2] = rgba[i][RCOMP];
+           }
+    }
+    else {
+           for (i=0; i<n; i++) {
+            *lpb++ = rgba[i][BCOMP];
+            *lpb++ = rgba[i][GCOMP];
+            *lpb++ = rgba[i][RCOMP];
+           }
+    }
+}
+
+
+/* Write a horizontal span of RGB color pixels with a boolean mask. */
+static void write_rgb_span_24(const GLcontext *ctx, 
+                             struct gl_renderbuffer *rb, 
+                             GLuint n, GLint x, GLint y,
+                             const GLubyte rgb[][3], 
+                             const GLubyte mask[] )
+{
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    GLuint i;
+    LPBYTE lpb;
+
+    (void) ctx;
+    
+    y=FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+            lpb[3*i] = rgb[i][BCOMP];
+            lpb[3*i+1] = rgb[i][GCOMP];
+            lpb[3*i+2] = rgb[i][RCOMP];
+           }
+    }
+    else {
+       for (i=0; i<n; i++) {
+               *lpb++ = rgb[i][BCOMP];
+               *lpb++ = rgb[i][GCOMP];
+               *lpb++ = rgb[i][RCOMP];
+       }
+    }
+}
+
+/*
+ * Write a horizontal span of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_span_24(const GLcontext *ctx, 
+                                   struct gl_renderbuffer *rb,
+                                   GLuint n, GLint x, GLint y,
+                                   const GLchan color[4], 
+                                   const GLubyte mask[])
+{
+    LPBYTE lpb;
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    y=FLIP(y);
+    if (mask) {
+       for (i=0; i<n; i++)
+           if (mask[i]) {
+               lpb[3*i] = color[BCOMP];
+               lpb[3*i+1] = color[GCOMP];
+               lpb[3*i+2] = color[RCOMP];
+           }
+    }
+    else
+       for (i=0; i<n; i++) {
+               *lpb++ = color[BCOMP];
+               *lpb++ = color[GCOMP];
+               *lpb++ = color[RCOMP];          
+       }
+}
+
+/* Write an array of RGBA pixels with a boolean mask. */
+static void write_rgba_pixels_24(const GLcontext *ctx, 
+                                struct gl_renderbuffer *rb,
+                                GLuint n, const GLint x[], const GLint y[],
+                                const GLubyte rgba[][4], 
+                                const GLubyte mask[])
+{
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    for (i=0; i<n; i++)
+       if (mask[i])
+           WMSETPIXEL24(pwfb, FLIP(y[i]), x[i],
+                        rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+}
+
+/*
+ * Write an array of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_pixels_24(const GLcontext *ctx, 
+                                     struct gl_renderbuffer *rb,
+                                     GLuint n,
+                                     const GLint x[], const GLint y[],
+                                     const GLchan color[4],
+                                     const GLubyte mask[])
+{
+    GLuint i;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    for (i=0; i<n; i++)
+       if (mask[i])
+           WMSETPIXEL24(pwfb, FLIP(y[i]),x[i],color[RCOMP],
+                        color[GCOMP], color[BCOMP]);
+}
+
+/* Read a horizontal span of color pixels. */
+static void read_rgba_span_24(const GLcontext *ctx, 
+                             struct gl_renderbuffer *rb,
+                             GLuint n, GLint x, GLint y,
+                             GLubyte rgba[][4] )
+{
+    GLuint i;
+    LPBYTE lpb;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+    
+    y = FLIP(y);
+    lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
+    for (i=0; i<n; i++) {
+       rgba[i][RCOMP] = lpb[3*i+2];
+       rgba[i][GCOMP] = lpb[3*i+1];
+       rgba[i][BCOMP] = lpb[3*i];
+       rgba[i][ACOMP] = 255;
+    }
+}
+
+
+/* Read an array of color pixels. */
+static void read_rgba_pixels_24(const GLcontext *ctx, 
+                               struct gl_renderbuffer *rb,
+                               GLuint n, const GLint x[], const GLint y[],
+                               GLubyte rgba[][4])
+{
+    GLuint i;
+    LPBYTE lpb;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
+
+    for (i=0; i<n; i++) {
+       GLint y2 = FLIP(y[i]);
+       lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + (3 * x[i]);
+       rgba[i][RCOMP] = lpb[3*i+2];
+       rgba[i][GCOMP] = lpb[3*i+1];
+       rgba[i][BCOMP] = lpb[3*i];
+       rgba[i][ACOMP] = 255;
+  }
+}
+
+
+/*********************************************************************/
+
 /* DOUBLE BUFFER 16-bit */
 
 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
 *lpw = BGR16((r),(g),(b)); }
@@ -1075,11 +1266,11 @@
 /**
  * Plug in the Get/PutRow/Values functions for a renderbuffer depending
  * on if we're drawing to the front or back color buffer.
  */
 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
-                                  int double_buffer)
+                                  BYTE cColorBits, int double_buffer)
 {
     if (double_buffer) {
         /* back buffer */
        /* Picking the correct span functions is important because
         * the DIB was allocated with the indicated depth. */
@@ -1095,20 +1286,36 @@
             rb->RedBits = 5;
             rb->GreenBits = 6;
             rb->BlueBits = 5;
            break;
        case PF_8R8G8B:
-           rb->PutRow = write_rgba_span_32;
-           rb->PutRowRGB = write_rgb_span_32;
-           rb->PutMonoRow = write_mono_rgba_span_32;
-           rb->PutValues = write_rgba_pixels_32;
-           rb->PutMonoValues = write_mono_rgba_pixels_32;
-           rb->GetRow = read_rgba_span_32;
-           rb->GetValues = read_rgba_pixels_32;
+               if (cColorBits == 24)
+               {
+                   rb->PutRow = write_rgba_span_24;
+                   rb->PutRowRGB = write_rgb_span_24;
+                   rb->PutMonoRow = write_mono_rgba_span_24;
+                   rb->PutValues = write_rgba_pixels_24;
+                   rb->PutMonoValues = write_mono_rgba_pixels_24;
+                   rb->GetRow = read_rgba_span_24;
+                   rb->GetValues = read_rgba_pixels_24;
+               rb->RedBits = 8;
+               rb->GreenBits = 8;
+               rb->BlueBits = 8;               
+               }
+               else
+               {
+               rb->PutRow = write_rgba_span_32;
+               rb->PutRowRGB = write_rgb_span_32;
+               rb->PutMonoRow = write_mono_rgba_span_32;
+               rb->PutValues = write_rgba_pixels_32;
+               rb->PutMonoValues = write_mono_rgba_pixels_32;
+               rb->GetRow = read_rgba_span_32;
+               rb->GetValues = read_rgba_pixels_32;
             rb->RedBits = 8;
             rb->GreenBits = 8;
             rb->BlueBits = 8;
+               }
            break;
        default:
            break;
        }
     }
@@ -1411,15 +1618,15 @@
        
         /* make render buffers */
         if (visual->doubleBufferMode == 1) {
             rb = wmesa_new_renderbuffer();
             _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
-            wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1);
+            wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 
pwfb->cColorBits, 1);
        }
         rb = wmesa_new_renderbuffer();
         _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
-        wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0);
+        wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 
0);
 
        /* Let Mesa own the Depth, Stencil, and Accum buffers */
         _mesa_add_soft_renderbuffers(&pwfb->Base,
                                      GL_FALSE, /* color */
                                      visual->depthBits > 0,

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to