This is mglmesa.c in view mode; [Download] [Up]
/**************************************************************************** * * Mesa bindings for SciTech MGL * * Copyright (C) 1996 SciTech Software. * All rights reserved. * * Filename: $Workfile: mglmesa.c $ * Version: $Revision: 1.5 $ * * Language: ANSI C * Environment: Any * * Description: Main Mesa 3D library interface between the MGL and * Mesa. For maximum peformance we call the MGL's internal * rendering functions directly so we can bypass all the * clipping and regular MGL API stuff as all that is already * handled by Mesa before the calls get here. * * Note also that all rendering is inherently single threaded * so we optimize for this case by using a global current * context structure. * * This module contains generic interface routines. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Date: 23 Jun 1997 18:10:16 $ $Author: KevinO $ * ****************************************************************************/ #include "mmesap.h" #pragma hdrstop #include "gl\mglmesa.h" /*--------------------------- Global Variables ----------------------------*/ #ifdef __WINDOWS__ MGLCallbacks _MGL_callbacks; /* MGL callback functions */ #endif gmode_t _MGL_mi; /* MGL mode information */ pixel_format_t _MGL_pf; /* MGL mode pixel format */ vecs _MGL_vecs; /* MGL Rendering vectors */ MGLRC _MM_rc; /* Current rendering context */ MGLRC *_MM_rcPtr = NULL; /* Pointer to current context */ /*------------------------- Implementation --------------------------------*/ #pragma warn -par /**********************************************************************/ /***** Miscellaneous device driver funcs *****/ /**********************************************************************/ PRIVATE void begin(GLcontext *ctx,GLenum mode) /**************************************************************************** * * Function: begin * * Description: Called when glBegin is called. We use this oportunity to * enable direct framebuffer access for our rendering functions. * ****************************************************************************/ { // TODO: Call begin directAccess depending on the currently selected mode // and also the current rendering attributes (to determine if we need // to directly access the buffer. We need this to support VBE/AF. // // We should optimize this to have this code in here run fast, and // put the complicated code into the setup_DD_funcs to avoid the // overheads of checking in here. _MGL_vecs.beginDirectAccess(); } PRIVATE void end(GLcontext *ctx) /**************************************************************************** * * Function: end * * Description: Called when glEnd is called. We use this oportunity to * disable direct framebuffer access for our rendering * functions. * ****************************************************************************/ { _MGL_vecs.endDirectAccess(); } PRIVATE void finish(GLcontext *ctx) /**************************************************************************** * * Function: finish * * Description: Called when glFinish is called. We simply do nothing here. * ****************************************************************************/ { } PRIVATE void flush(GLcontext *ctx) /**************************************************************************** * * Function: flush * * Description: Called when glFlush is called. We simply do nothing here * ****************************************************************************/ { } PRIVATE void clear_index(GLcontext *ctx, GLuint index) /**************************************************************************** * * Function: clear_index * Parameters: index - New color index for buffer clears * * Description: Sets the current buffer clear color for color index buffers. * ****************************************************************************/ { RC.clearColor = index; } PRIVATE void clear_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a) /**************************************************************************** * * Function: clear_color * Parameters: r,g,b,a - New RGBA color values for buffer clears * * Description: Set the current buffer clear color for TrueColor buffers. * Note that Mesa passes us color values pre-scaled to the * proper number of color bits: * * [0,ctx->Visual->RedScale] * [0,ctx->Visual->GreenScale] * [0,ctx->Visual->BlueScale] * [0,ctx->Visual->AlphaScale] * ****************************************************************************/ { RC.clearColor = PACK_COLOR(r,g,b); } PRIVATE void clear(GLcontext *ctx,GLboolean all, GLint x, GLint y, GLint width, GLint height) /**************************************************************************** * * Function: clear * Parameters: all - True to clear entire buffer * x,y,width,height - Rectangle to clear * * Description: Clears the buffer in the current clear color * ****************************************************************************/ { VECS.setColor(RC.clearColor); if (all) VECS.solid.fillRect(0,0,MI.xRes+1,MI.yRes+1); else VECS.solid.fillRect(x,y,x+width,y+height); } PRIVATE void set_index(GLcontext *ctx, GLuint index) /**************************************************************************** * * Function: clear_index * Parameters: index - New color index * * Description: Sets the current solid color for color index buffers. * ****************************************************************************/ { RC.color = index; } PRIVATE void set_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a) /**************************************************************************** * * Function: set_color * Parameters: r,g,b,a - New RGBA color value * * Description: Set the current solid color for TrueColor buffers. * Note that Mesa passes us color values pre-scaled to the * proper number of color bits: * * [0,ctx->Visual->RedScale] * [0,ctx->Visual->GreenScale] * [0,ctx->Visual->BlueScale] * [0,ctx->Visual->AlphaScale] * ****************************************************************************/ { RC.color = PACK_COLOR(r,g,b); RC.red = r; RC.green = g; RC.blue = b; } PRIVATE GLboolean index_mask(GLcontext *ctx, GLuint mask) /**************************************************************************** * * Function: index_mask * Parameters: mask - Color index mask * Returns: True if we implement masking, false if not * * Description: Implements color index masking ala glIndexMask if possible. * We currently return false for this function. * ****************************************************************************/ { return GL_FALSE; } PRIVATE GLboolean color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,GLboolean bmask, GLboolean amask) /**************************************************************************** * * Function: color_mask * Parameters: rmask - Red mask * gmask - Green mask * bmask - Blue mask * amask - Alpha mask * Returns: True if we implement masking, false if not * * Description: Implements RGB color masking ala glColorMask if possible. * We currently return false for this function. * ****************************************************************************/ { return GL_FALSE; } PRIVATE GLboolean logicop(GLcontext *ctx, GLenum op) /**************************************************************************** * * Function: logicop * Parameters: op - New logic op to enable * Returns: True if we implement masking, false if not * * Description: Implements logic operations ala glLogicOp if possible. For * op's that we dont support we simply return GL_FALSE and it * is implemented in software by Mesa. * ****************************************************************************/ { #if 0 int mode; switch (op) { case GL_COPY: mode = MGL_REPLACE_MODE; break; case GL_AND: mode = MGL_AND_MODE; break; case GL_OR: mode = MGL_OR_MODE; break; case GL_XOR: mode = MGL_XOR_MODE; break; default: return GL_FALSE; } DC.r.setWriteMode(mode); return GL_TRUE; #else return GL_FALSE; #endif } PRIVATE void dither(GLcontext *ctx, GLboolean enable) /**************************************************************************** * * Function: dither * Parameters: enable - True to enable dithering, false to disable it * * Description: Enables dithering mode if applicable. For the moment if * dithering is enabled we will simply fall back on Mesa's * software rendering until we have support for this. * ****************************************************************************/ { if (enable) RC.pixelformat = RC.dithered_pf; else RC.pixelformat = RC.undithered_pf; setup_DD_pointers(ctx); } PRIVATE GLboolean set_buffer(GLcontext *ctx, GLenum mode) /**************************************************************************** * * Function: set_buffer * Parameters: mode - Buffer mode to enable * * Description: Sets the buffer access mode to the front buffer or the * back buffer for the application. The MGL always allows * direct access to both buffers in double buffered fullscreen * modes, but when rendering to a memory device context (ie: * when rendering in a window in the windows environment) we * only have a single buffer available. * ****************************************************************************/ { if (!RC.gl_vis->DBflag) { MGL_makeCurrentDC(RC.dc); return (mode = GL_FRONT); } if (RC.dc->mi.maxPage > 0) { /* Hardware page flipping */ if (mode == GL_FRONT) MGL_setActivePage(RC.dc,RC.frontbuffer); else if (mode == GL_BACK) MGL_setActivePage(RC.dc,RC.backbuffer); else return GL_FALSE; } if (RC.memdc) { /* Software double buffering using a memory DC. In some cases * we may not be able to access the display memory surface for the * front buffer in which case this will fail. */ if (mode == GL_FRONT && (MGL_surfaceAccessType(RC.dc) != MGL_NO_ACCESS)) MGL_makeCurrentDC(RC.dc); else if (mode == GL_BACK) MGL_makeCurrentDC(RC.memdc); else return GL_FALSE; } else { /* Hardware page flipping only */ MGL_makeCurrentDC(RC.dc); } RC.bufferMode = mode; setup_DD_pointers(ctx); return GL_TRUE; } PRIVATE void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height) /**************************************************************************** * * Function: get_buffer_size * Parameters: width - Place to store buffer width * height - Place to store buffer height * * Description: Returns the current buffer width and height. We simply * return the currently active device context's width and * height, which will change if the buffer is resized in a * windowed environment. * ****************************************************************************/ { if (MI.xRes != RC.dispdc->mi.xRes || MI.yRes != RC.dispdc->mi.yRes) { MI.xRes = RC.dispdc->mi.xRes; MI.yRes = RC.dispdc->mi.yRes; /* Resize our system memory back buffer if we have one */ if (RC.memdc) { MGL_destroyDC(RC.memdc); RC.memdc = MGL_createMemoryDC(MI.xRes+1,MI.yRes+1,MI.bitsPerPixel,&PF); if (!RC.memdc) exit(1); RC.dc = RC.memdc; if (RC.dispdc->mi.bitsPerPixel == 8) { palette_t pal[256]; MGL_getPalette(RC.dispdc,pal,256,0); MGL_setPalette(RC.memdc,pal,256,0); MGL_realizePalette(RC.memdc,256,0,-1); } MI = RC.dc->mi; } } *width = MI.xRes+1; *height = MI.yRes+1; RC.bottom = MI.yRes; } /**********************************************************************/ /*** Point rendering ***/ /**********************************************************************/ PUBLIC points_func mmesa_get_points_func(GLcontext *ctx) /**************************************************************************** * * Function: mmesa_get_points_func * Parameters: ctx - Context to examine * * Description: Analyze context state to see if we can provide a fast points * drawing function, like those in points.c. Otherwise, return * NULL. * ****************************************************************************/ { #if 0 if (ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask == 0 && !ctx->Texture.Enabled) { return draw_points; } #endif return NULL; } /**********************************************************************/ /*** Line rendering ***/ /**********************************************************************/ PUBLIC line_func mmesa_get_line_func(GLcontext *ctx) /**************************************************************************** * * Function: mmesa_get_line_func * Parameters: ctx - Context to examine * * Description: Analyze context state to see if we can provide a fast line * drawing function, like those in lines.c. Otherwise, return * NULL. * ****************************************************************************/ { #if 0 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; int depth = xmesa->xm_visual->visinfo->depth; if (ctx->Line.SmoothFlag) return NULL; if (ctx->Texture.Enabled) return NULL; if (ctx->Light.ShadeModel!=GL_FLAT) return NULL; if (xmesa->xm_buffer->buffer==XIMAGE && ctx->RasterMask==DEPTH_BIT && ctx->Depth.Func==GL_LESS && ctx->Depth.Mask==GL_TRUE && ctx->Line.Width==1.0F && ctx->Line.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return flat_TRUECOLOR_z_line; case PF_8A8B8G8R: return flat_8A8B8G8R_z_line; case PF_8R8G8B: return flat_8R8G8B_z_line; case PF_5R6G5B: return flat_5R6G5B_z_line; case PF_DITHER: return (depth==8) ? flat_DITHER8_z_line : NULL; case PF_LOOKUP: return (depth==8) ? flat_LOOKUP8_z_line : NULL; case PF_HPCR: return flat_HPCR_z_line; default: return NULL; } } if (xmesa->xm_buffer->buffer==XIMAGE && ctx->RasterMask==0 && ctx->Line.Width==1.0F && ctx->Line.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return flat_TRUECOLOR_line; case PF_8A8B8G8R: return flat_8A8B8G8R_line; case PF_8R8G8B: return flat_8R8G8B_line; case PF_5R6G5B: return flat_5R6G5B_line; case PF_DITHER: return (depth==8) ? flat_DITHER8_line : NULL; case PF_LOOKUP: return (depth==8) ? flat_LOOKUP8_line : NULL; case PF_HPCR: return flat_HPCR_line; default: return NULL; } } if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) { setup_x_line_options( ctx ); return flat_pixmap_line; } #endif return NULL; } /**********************************************************************/ /*** Triangle rendering ***/ /**********************************************************************/ triangle_func mmesa_get_triangle_func(GLcontext *ctx) { #if 0 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; int depth = xmesa->xm_visual->visinfo->depth; if (ctx->Polygon.SmoothFlag) return NULL; if (ctx->Texture.Enabled) return NULL; if (xmesa->xm_buffer->buffer==XIMAGE) { if ( ctx->Light.ShadeModel==GL_SMOOTH && ctx->RasterMask==DEPTH_BIT && ctx->Depth.Func==GL_LESS && ctx->Depth.Mask==GL_TRUE && ctx->Polygon.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return smooth_TRUECOLOR_z_triangle; case PF_8A8B8G8R: return smooth_8A8B8G8R_z_triangle; case PF_8R8G8B: return smooth_8R8G8B_z_triangle; case PF_5R6G5B: return smooth_5R6G5B_z_triangle; case PF_HPCR: return smooth_HPCR_z_triangle; case PF_DITHER: return (depth==8) ? smooth_DITHER8_z_triangle : smooth_DITHER_z_triangle; case PF_LOOKUP: return (depth==8) ? smooth_LOOKUP8_z_triangle : NULL; default: return NULL; } } if ( ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==DEPTH_BIT && ctx->Depth.Func==GL_LESS && ctx->Depth.Mask==GL_TRUE && ctx->Polygon.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return flat_TRUECOLOR_z_triangle; case PF_8A8B8G8R: return flat_8A8B8G8R_z_triangle; case PF_8R8G8B: return flat_8R8G8B_z_triangle; case PF_5R6G5B: return flat_5R6G5B_z_triangle; case PF_HPCR: return flat_HPCR_z_triangle; case PF_DITHER: return (depth==8) ? flat_DITHER8_z_triangle : flat_DITHER_z_triangle; case PF_LOOKUP: return (depth==8) ? flat_LOOKUP8_z_triangle : NULL; default: return NULL; } } if ( ctx->RasterMask==0 /* no depth test */ && ctx->Light.ShadeModel==GL_SMOOTH && ctx->Polygon.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return smooth_TRUECOLOR_triangle; case PF_8A8B8G8R: return smooth_8A8B8G8R_triangle; case PF_8R8G8B: return smooth_8R8G8B_triangle; case PF_5R6G5B: return smooth_5R6G5B_triangle; case PF_HPCR: return smooth_HPCR_triangle; case PF_DITHER: return (depth==8) ? smooth_DITHER8_triangle : smooth_DITHER_triangle; case PF_LOOKUP: return (depth==8) ? smooth_LOOKUP8_triangle : NULL; default: return NULL; } } if ( ctx->RasterMask==0 /* no depth test */ && ctx->Light.ShadeModel==GL_FLAT && ctx->Polygon.StippleFlag==GL_FALSE) { switch (xmesa->pixelformat) { case PF_TRUECOLOR: return flat_TRUECOLOR_triangle; case PF_8A8B8G8R: return flat_8A8B8G8R_triangle; case PF_8R8G8B: return flat_8R8G8B_triangle; case PF_5R6G5B: return flat_5R6G5B_triangle; case PF_HPCR: return flat_HPCR_triangle; case PF_DITHER: return (depth==8) ? flat_DITHER8_triangle : flat_DITHER_triangle; case PF_LOOKUP: return (depth==8) ? flat_LOOKUP8_triangle : NULL; default: return NULL; } } return NULL; } else { /* pixmap */ if (ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0) { setup_x_polygon_options( ctx ); return flat_pixmap_triangle; } return NULL; } #endif return NULL; } /**********************************************************************/ /***** Miscellaneous functions *****/ /**********************************************************************/ PRIVATE void setup_DD_pointers(GLcontext *ctx) /**************************************************************************** * * Function: setup_DD_pointer * Parameters: ctx - Device context to setup pointers for * * Description: Sets up all the device driver rendering pointers for the * current rendering state. This function is where we swap in * high performance rendering functions when the rendering * state allows this. * ****************************************************************************/ { bool doDither = false; /* Always the same */ ctx->Driver.UpdateState = setup_DD_pointers; ctx->Driver.GetBufferSize = get_buffer_size; ctx->Driver.Begin = begin; ctx->Driver.End = end; ctx->Driver.Flush = flush; ctx->Driver.Finish = finish; ctx->Driver.SetBuffer = set_buffer; ctx->Driver.Index = set_index; ctx->Driver.Color = set_color; ctx->Driver.ClearIndex = clear_index; ctx->Driver.ClearColor = clear_color; ctx->Driver.Clear = clear; ctx->Driver.IndexMask = index_mask; ctx->Driver.ColorMask = color_mask; ctx->Driver.LogicOp = logicop; ctx->Driver.Dither = dither; /* Accelerated point, line and triangle functions */ ctx->Driver.PointsFunc = mmesa_get_points_func(ctx); ctx->Driver.LineFunc = mmesa_get_line_func(ctx); ctx->Driver.TriangleFunc = mmesa_get_triangle_func(ctx); /* Accelerated bitmap drawing functions */ #if 0 ctx->Driver.DrawPixels = draw_pixels; ctx->Driver.Bitmap = draw_bitmap; #endif /* Optimized pixel span reading/writing functions. Note that we use * a (void*) cast as we have removed the 'const'ness of the parameters * passed to these functions so we can use the pointers to step through * our arrays efficiently. */ switch (RC.pixelformat) { case PF_INDEX: ctx->Driver.WriteIndexSpan = (void*)_mmesa_write_span_ci; ctx->Driver.WriteMonoindexSpan = (void*)_mmesa_write_span_mono_ci; ctx->Driver.WriteIndexPixels = (void*)_mmesa_write_pixels_ci; ctx->Driver.WriteMonoindexPixels = (void*)_mmesa_write_pixels_mono_ci; ctx->Driver.ReadIndexSpan = (void*)_mmesa_read_span_ci; ctx->Driver.ReadIndexPixels = (void*)_mmesa_read_pixels_ci; break; case PF_RGB8: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_8_8; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_8; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_8_8; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_8; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_8; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_8; doDither = true; break; case PF_DITHER8: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_8_DITHER8; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_8_DITHER8; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_8_DITHER8; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_8_DITHER8; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_8; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_8; doDither = true; break; case PF_RGB555: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_16_555; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_16; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_16_555; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_16_555; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_16_555; break; case PF_DITHER555: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_16_DITHER555; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_16_DITHER555; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_16_DITHER555; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16_DITHER555; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_16_555; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_16_555; doDither = true; break; case PF_RGB565: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_16_565; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_16; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_16_565; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_16_565; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_16_565; break; case PF_DITHER565: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_16_DITHER565; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_16_DITHER565; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_16_DITHER565; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_16_DITHER565; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_16_565; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_16_565; doDither = true; break; case PF_RGB888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_24_RGB; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_24_RGB; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_24_RGB; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_24_RGB; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_24_RGB; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_24_RGB; break; case PF_BGR888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_24_BGR; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_24_BGR; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_24_BGR; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_24_BGR; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_24_BGR; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_24_BGR; break; case PF_ARGB8888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_32_ARGB; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_32; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_32_ARGB; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_32_ARGB; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_32_ARGB; break; case PF_ABGR8888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_32_ABGR; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_32; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_32_ABGR; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_32_ABGR; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_32_ABGR; break; case PF_RGBA8888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_32_RGBA; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_32; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_32_RGBA; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_32_RGBA; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_32_RGBA; break; case PF_BGRA8888: ctx->Driver.WriteColorSpan = (void*)_mmesa_write_span_32_BGRA; ctx->Driver.WriteMonocolorSpan = (void*)_mmesa_write_span_mono_32; ctx->Driver.WriteColorPixels = (void*)_mmesa_write_pixels_32_BGRA; ctx->Driver.WriteMonocolorPixels = (void*)_mmesa_write_pixels_mono_32; ctx->Driver.ReadColorSpan = (void*)_mmesa_read_span_32_BGRA; ctx->Driver.ReadColorPixels = (void*)_mmesa_read_pixels_32_BGRA; break; } /* Set the pixel format scale factos for dithering/non-dithering */ if (doDither) { ctx->Visual->RedScale = 255.0; ctx->Visual->GreenScale = 255.0; ctx->Visual->BlueScale = 255.0; } else { ctx->Visual->RedScale = (GLfloat)PF.redMask; ctx->Visual->GreenScale = (GLfloat)PF.greenMask; ctx->Visual->BlueScale = (GLfloat)PF.blueMask; } } /**********************************************************************/ /***** MGLMesa API Functions *****/ /**********************************************************************/ #ifdef __WINDOWS__ bool APIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version) /**************************************************************************** * * Function: MGLMesaInitDLL * Parameters: cb - MGL callbacks structure * version - MGL version this DLL was built for * * Description: This function is called by the MGL when the MESAGL.DLL * library is loaded under Windows. This registers a set of * callback functions that Mesa uses to call MGL API functions * so that we dont have to staticly link the MGL and Mesa into * the same DLL or application. * * We also pass back a copy of Mesa's internal global MGL * device context which Mesa uses to directly access the MGL * internal functions and structures. The MGL uses this pointer * to maintain Mesa's internal structures * * Note that because we use the MGL's internal structures we * also do a check to ensure that the MGL library calling us * is the same version that we were built with. * ****************************************************************************/ { /* Check for the correct MGL version */ if (strcmp(version,MGL_VERSION_STR) != 0) return false; _MGL_callbacks = *cb; return true; } #endif void APIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual) /**************************************************************************** * * Function: MGLMesaChooseVisual * Parameters: dc - MGL device context * visual - Structure containing visual context information * * Description: This function examines the visual passed to use to * deteremine if we support the requested capabilities. If we * don't we will modify the structure for the capabilities that * we do support (ie: lowering the depth buffer size to 16 * bits etc). * ****************************************************************************/ { /* Force the depth buffer, stencil buffer and accum buffers to our sizes */ if (visual->depth_size) visual->depth_size = 8 * sizeof(GLdepth); if (visual->stencil_size) visual->stencil_size = 8 * sizeof(GLstencil); if (visual->accum_size) visual->accum_size = 8 * sizeof(GLaccum); /* Force RGB mode for DirectColor and TrueColor modes */ if (dc->mi.bitsPerPixel > 8) visual->rgb_flag = GL_TRUE; if (MGL_isMemoryDC(dc)) visual->db_flag = GL_FALSE; if (MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS) visual->db_flag = GL_TRUE; } PRIVATE int countBits(uint mask) /**************************************************************************** * * Function: countBits * Parameters: mask - * Returns: number of set bits. * * Description: Counts the number of set bits in a mask and determines the * shift amount. * ****************************************************************************/ { int i=0; if (mask) { /* count set bits */ while ( mask & (1 << i)) { i++; }; } return i; } bool APIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *vis) /**************************************************************************** * * Function: MGLMesaSetVisual * Parameters: dc - MGL device context * visual - Structure containing visual context information * Returns: True on success, false if visual creation failed * * Description: This function attempts to create a Mesa visual for the * device context. If this succeeds then Mesa can properly * handle the requested visual. * ****************************************************************************/ { GLfloat red_scale, green_scale, blue_scale, alpha_scale; GLint red_bits, green_bits, blue_bits, alpha_bits; /* Do quick check on incoming visual */ if (dc->mi.bitsPerPixel > 8 && !vis->rgb_flag) return false; if (dc->mi.bitsPerPixel < 8) return false; if ((dc->mi.xRes+1 > MAX_WIDTH) || (dc->mi.yRes+1 > MAX_HEIGHT)) return false; if (MGL_isMemoryDC(dc) && vis->db_flag) return false; if ((MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS) && !vis->db_flag) return false; /* Create color channel scale factors from pixel format info */ red_scale = (GLfloat)dc->pf.redMask; green_scale = (GLfloat)dc->pf.greenMask; blue_scale = (GLfloat)dc->pf.blueMask; alpha_scale = 255.0; red_bits = countBits(dc->pf.redMask); green_bits = countBits(dc->pf.greenMask); blue_bits = countBits(dc->pf.blueMask); alpha_bits = countBits(dc->pf.rsvdMask); MGL_clearCurrentDC(); dc->visual = gl_create_visual( vis->rgb_flag, vis->alpha_flag, vis->db_flag, vis->depth_size, vis->stencil_size, vis->accum_size, dc->mi.bitsPerPixel, red_scale, green_scale, blue_scale, alpha_scale, red_bits, green_bits, blue_bits, alpha_bits); return (dc->visual != NULL); } bool APIENTRY MGLMesaCreateContext(MGLDC *dc,bool forceMemDC) /**************************************************************************** * * Function: MGLMesaCreateContext * Parameters: dc - MGLDC to create rendering context for * forceMemDC - True to force rendering to memory back buffer * Returns: True on success, false on failure. * * Description: Attempts to create a Mesa rendering context for the * device context. The application programmer must first * call MGLMesaSetVisual on the MGLDC to set the visual format * before calling this function. * * If we dont have hardware page flipping or the user has * forced memory buffering with the forceMemDC function then * we will allocate a system memory back buffer for double * buffering. Note that if we have hardware page flipping * and system buffering has been forced, we will still flip * between hardware pages to eliminate all tearing. This * option is intended mainly as a performance option for * systems where system memory rendering is faster. * ****************************************************************************/ { palette_t pal[256]; /* Ensure that the visual has been created first */ MGL_clearCurrentDC(); if (!dc->visual) return false; /* Allocate memory for the rendering context structure and create it */ if ((dc->rc = (void*)calloc(1,sizeof(MGLRC))) == NULL) goto Error; dc->rc->dispdc = dc; dc->rc->gl_ctx = gl_create_context(dc->visual,NULL,(void*)dc->rc); if (!dc->rc) goto Error; /* Allocate the ancillary buffers */ if ((dc->rc->gl_buffer = gl_create_framebuffer(dc->visual)) == NULL) goto Error; /* Allocate back memory DC buffer if necessary */ if ((dc->visual->DBflag && dc->mi.maxPage == 0) || forceMemDC || (MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)) { dc->rc->memdc = MGL_createMemoryDC(dc->mi.xRes+1,dc->mi.yRes+1,dc->mi.bitsPerPixel,&dc->pf); if (!dc->rc->memdc) goto Error; dc->rc->dc = dc->rc->memdc; } else dc->rc->dc = dc->rc->dispdc; /* Initialize double buffering */ if (dc->visual->DBflag && dc->mi.maxPage > 0) { MGL_setVisualPage(dc,dc->rc->frontbuffer = 0,false); MGL_setActivePage(dc,dc->rc->backbuffer = 1); } /* Initialize the private rendering context information */ if (!dc->visual->RGBAflag) { dc->rc->dithered_pf = dc->rc->undithered_pf = PF_INDEX; MGL_getPalette(dc,pal,256,0); } else { if (dc->mi.bitsPerPixel > 8) { /* DirectColor or TrueColor display */ if (dc->mi.bitsPerPixel == 15) { dc->rc->undithered_pf = PF_RGB555; dc->rc->dithered_pf = PF_DITHER555; } else if (dc->mi.bitsPerPixel == 16) { dc->rc->undithered_pf = PF_RGB565; dc->rc->dithered_pf = PF_DITHER565; } else if (dc->mi.bitsPerPixel == 24) { if (dc->pf.redPos == 0) dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGR888; else dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGB888; } else { if (dc->pf.redPos == 0) dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ABGR8888; else if (dc->pf.redPos == 8) dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGRA8888; else if (dc->pf.redPos == 16) dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ARGB8888; else dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGBA8888; } } else { /* 8bpp RGB display */ dc->rc->undithered_pf = PF_RGB8; dc->rc->dithered_pf = PF_DITHER8; MGL_getHalfTonePalette(pal); } } dc->rc->gl_vis = dc->visual; dc->rc->bottom = dc->mi.yRes+1; dc->rc->pixelformat = dc->rc->dithered_pf; dc->rc->bufferMode = dc->visual->DBflag ? GL_BACK : GL_FRONT; setup_DD_pointers(dc->rc->gl_ctx); /* Setup the default palette for the device context */ if (dc->mi.bitsPerPixel == 8) { MGLMesaSetPalette(dc,pal,256,0); MGLMesaRealizePalette(dc,256,0,false); } return true; Error: MGLMesaDestroyContext(dc); return false; } void APIENTRY MGLMesaDestroyContext(MGLDC *dc) /**************************************************************************** * * Function: MGLMesaDestroyContext * Parameters: dc - MGLDC to destroy rendering context for * * Description: Destroys the rendering context and returns the MGLDC back * to it's original state before 3D rendering was enabled. * ****************************************************************************/ { if (dc->rc) { if (dc->rc->memdc) MGL_destroyDC(dc->rc->memdc); gl_destroy_framebuffer(dc->rc->gl_buffer); gl_destroy_context(dc->rc->gl_ctx); free(dc->rc); } dc->rc = NULL; gl_destroy_visual(dc->visual); dc->visual = NULL; } void APIENTRY MGLMesaMakeCurrent(MGLDC *dc) /**************************************************************************** * * Function: MGLMesaMakeCurrent * Parameters: dc - MGLDC to make current * * Description: Makes the passed in MGLDC the current rendering context * for OpenGL functions. Note that we cache a global copy * of this rendering context for speed (we are single threaded) * so we flush this back when the context is made a different * one. * ****************************************************************************/ { if (dc && dc->rc == _MM_rcPtr) return; if (_MM_rcPtr) { *_MM_rcPtr = RC; /* 'Write back' the old RC */ _MM_rcPtr = NULL; /* This RC is no longer cached */ gl_make_current(NULL, NULL); MGL_clearCurrentDC(); } if (dc) { gl_make_current(dc->rc->gl_ctx, dc->rc->gl_buffer); _MM_rcPtr = dc->rc; /* Cache DC in global structure */ RC = *dc->rc; /* Save pointer to original DC */ MI = RC.dc->mi; /* Save cached MGL internals */ PF = RC.dc->pf; VECS = RC.dc->r; set_buffer(dc->rc->gl_ctx,RC.bufferMode); if (RC.gl_ctx->Viewport.Width == 0) { /* initialize viewport to window size */ gl_Viewport(RC.gl_ctx, 0, 0, MI.xRes+1, MI.yRes+1); RC.gl_ctx->Scissor.Width = MI.xRes+1; RC.gl_ctx->Scissor.Height = MI.yRes+1; } } } void APIENTRY MGLMesaSwapBuffers(MGLDC *dc,bool waitVRT) /**************************************************************************** * * Function: MGLMesaSwapBuffers * Parameters: dc - MGLDC to swap buffers for * waitVRT - True to wait for vertical retrace * * Description: Swaps the display buffers for the MGL device context. If * we have a memory DC this is blitted to the display, and * if we have harware page flipping we flip hardware display * pages. * ****************************************************************************/ { if (!RC.gl_vis->DBflag) return; if (RC.memdc) { /* We have a memory buffer so blit it to the screen */ MGL_bitBltCoord(RC.dispdc,RC.memdc,0,0,MI.xRes+1,MI.yRes+1,0,0,MGL_REPLACE_MODE); } if (RC.dc->mi.maxPage > 0) { /* Hardware page flipping */ RC.frontbuffer ^= 1; RC.backbuffer = RC.frontbuffer ^ 1; if (RC.bufferMode == GL_FRONT) MGL_setActivePage(RC.dc,RC.frontbuffer); else MGL_setActivePage(RC.dc,RC.backbuffer); MGL_setVisualPage(RC.dc,RC.frontbuffer,waitVRT); } } void APIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue) /**************************************************************************** * * Function: MGLMesaSetPaletteEntry * Parameters: dc - MGLDC to destroy rendering context for * entry - Index of entry to set * red,... - Color values for palette entry * * Description: Sets a single color palette entry in the device context. * ****************************************************************************/ { MGL_setPaletteEntry(dc,entry,red,green,blue); if (dc->rc && dc->rc->memdc) MGL_setPaletteEntry(dc->rc->memdc,entry,red,green,blue); } void APIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex) /**************************************************************************** * * Function: MGLMesaDestroyContext * Parameters: dc - MGLDC to destroy rendering context for * * Description: Destroys the rendering context and returns the MGLDC back * to it's original state before 3D rendering was enabled. * ****************************************************************************/ { MGL_setPalette(dc,pal,numColors,startIndex); if (dc->rc && dc->rc->memdc) MGL_setPalette(dc->rc->memdc,pal,numColors,startIndex); } void APIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT) /**************************************************************************** * * Function: MGLMesaDestroyContext * Parameters: dc - MGLDC to destroy rendering context for * * Description: Destroys the rendering context and returns the MGLDC back * to it's original state before 3D rendering was enabled. * ****************************************************************************/ { MGL_realizePalette(dc,numColors,startIndex,waitVRT); if (dc->rc && dc->rc->memdc) MGL_realizePalette(dc->rc->memdc,numColors,startIndex,waitVRT); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.