This is wmesa.c in view mode; [Download] [Up]
/* $Id: wmesa.c,v 1.3 1996/09/27 17:20:42 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 2.0
* Copyright (C) 1995-1996 Brian Paul
*
* 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.
*
* Windows driver by: Mark E. Peterson (markp@ic.mankato.mn.us)
* Updated for Mesa 2.0 by: Barry Roberts (blroberts@xactware.com)
*/
/*
* $Log: wmesa.c,v $
* Revision 1.3 1996/09/27 17:20:42 brianp
* updated copyright
*
* Revision 1.2 1996/09/27 17:19:49 brianp
* updated for 2.0 by Barry Roberts
*
*/
#include <stdlib.h>
#include <windows.h>
#include "gl\wmesa.h"
#include "context.h"
#include "types.h"
#include "xform.h"
#include "vb.h"
#include "wing.h"
/* Bit's used for dest: */
#define FRONT_PIXMAP 1
#define BACK_PIXMAP 2
#define BACK_XIMAGE 4
struct wmesa_context
{
struct gl_context *gl_ctx; /* the main library context */
HWND Window;
HDC Compat_DC; /* Display context for double buffering. */
HBITMAP Old_Compat_BM,Compat_BM; /* Bitmap for double buffering */
GLuint width, height,ScanWidth;
GLboolean db_flag; /* double buffered? */
GLboolean rgb_flag; /* RGB mode? */
GLuint depth; /* bits per pixel (1, 8, 24, etc) */
unsigned long pixel; /* current color index or RGBA pixel value */
unsigned long clearpixel; /* pixel for clearing the color buffers */
char *ScreenMem; // WinG memory
BITMAPINFO *IndexFormat;
HPALETTE hPal; // Current Palette
};
#ifdef NDEBUG
#define assert(ignore) ((void) 0)
#else
void Mesa_Assert(void *Cond,void *File,unsigned Line)
{
char Msg[512];
sprintf(Msg,"%s %s %d",Cond,File,Line);
MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
exit(1);
}
#define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
#endif
#define DD_GETDC ((Current->db_flag) ? Current->Compat_DC : GetDC(Current->Window))
#define DD_RELEASEDC if (!Current->db_flag) ReleaseDC(Current->Window,DC)
static WMesaContext Current = NULL;
#ifdef __SYMANTEC_BUGS
struct dd_function_table DD;
#endif
#define FLIP(Y) (Current->height-(Y)-1)
/* Finish all pending operations and synchronize. */
void finish(GLcontext *ctx)
{
/* no op */
}
void flush(GLcontext *ctx)
{
/* no op */
}
/*
* Set the color index used to clear the color buffer.
*/
void clear_index(GLcontext *ctx, GLuint index)
{
Current = ctx->DriverCtx;
Current->clearpixel = index;
}
/*
* Set the color used to clear the color buffer.
*/
void clear_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
Current = ctx->DriverCtx;
Current->clearpixel=RGB(r, g, b );
}
/*
* Clear the specified region of the color buffer using the clear color
* or index as specified by one of the two functions above.
*/
void clear(GLcontext *ctx, GLboolean all,GLint x, GLint y, GLint width, GLint height )
{
Current = ctx->DriverCtx;
if (all)
{
x=y=0;
width=Current->width;
height=Current->height;
}
if (Current->rgb_flag==GL_TRUE)
{
HDC DC=DD_GETDC;
HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
HPEN Old_Pen=SelectObject(DC,Pen);
HBRUSH Old_Brush=SelectObject(DC,Brush);
Rectangle(DC,x,y,x+width,y+height);
SelectObject(DC,Old_Pen);
SelectObject(DC,Old_Brush);
DeleteObject(Pen);
DeleteObject(Brush);
DD_RELEASEDC;
}
else
{
int i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
for (i=0; i<height; i++)
{
memset(Mem,Current->clearpixel,width);
Mem+=width;
}
}
}
/* Set the current color index. */
void set_index(GLcontext *ctx, GLuint index)
{
Current = ctx->DriverCtx;
Current->pixel=index;
}
/* Set the current RGBA color. */
void set_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
Current = ctx->DriverCtx;
Current->pixel = RGB( r, g, b );
}
/* Set the index mode bitplane mask. */
GLboolean index_mask(GLcontext *ctx, GLuint mask)
{
/* can't implement */
return GL_FALSE;
}
/* Set the RGBA drawing mask. */
GLboolean color_mask( GLcontext *ctx,
GLboolean rmask, GLboolean gmask,
GLboolean bmask, GLboolean amask)
{
/* can't implement */
return GL_FALSE;
}
/*
* Set the pixel logic operation. Return GL_TRUE if the device driver
* can perform the operation, otherwise return GL_FALSE. If GL_FALSE
* is returned, the logic op will be done in software by Mesa.
*/
GLboolean logicop( GLcontext *ctx, GLenum op )
{
/* can't implement */
return GL_FALSE;
}
void dither( GLcontext *ctx, GLboolean enable )
{
/* No op */
}
GLboolean set_buffer(GLcontext *ctx, GLenum mode )
{
/* TODO: this could be better */
if (mode==GL_FRONT || mode==GL_BACK) {
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
/* Return characteristics of the output buffer. */
void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
{
int New_Size;
RECT CR;
Current = ctx->DriverCtx;
GetClientRect(Current->Window,&CR);
*width=CR.right;
*height=CR.bottom;
New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
if (New_Size)
{
Current->width=*width;
Current->ScanWidth=Current->width;
if ((Current->ScanWidth%sizeof(long))!=0)
Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
Current->height=*height;
if (Current->db_flag)
{
if (Current->rgb_flag==GL_TRUE)
Current->Compat_BM=CreateCompatibleBitmap(Current->Compat_DC,Current->width,Current->height);
else
{
Current->IndexFormat->bmiHeader.biWidth=Current->width;
if (Current->IndexFormat->bmiHeader.biHeight<0)
Current->IndexFormat->bmiHeader.biHeight=-Current->height;
else
Current->IndexFormat->bmiHeader.biHeight=Current->height;
Current->Compat_BM=WinGCreateBitmap(Current->Compat_DC,Current->IndexFormat,&((void *) Current->ScreenMem));
}
DeleteObject(SelectObject(Current->Compat_DC,Current->Compat_BM));
}
}
}
/**********************************************************************/
/***** Accelerated point, line, polygon rendering *****/
/**********************************************************************/
static void fast_rgb_points(GLcontext *ctx, GLuint first, GLuint last )
{
int i;
HDC DC=DD_GETDC;
struct vertex_buffer* VB = ctx->VB;
Current = ctx->DriverCtx;
if (VB->MonoColor) {
/* all drawn with current color */
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
int x, y;
x = (GLint) VB->Win[i][0];
y = FLIP( (GLint) VB->Win[i][1] );
SetPixel(DC,x,y,Current->pixel);
}
}
}
else {
/* draw points of different colors */
HPEN Pen=CreatePen(PS_SOLID,1,Current->pixel);
HPEN Old_Pen=SelectObject(DC,Pen);
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
int x, y;
unsigned long pixel=RGB(VB->Color[i][0]*255.0,
VB->Color[i][1]*255.0,
VB->Color[i][2]*255.0);
x = (GLint) VB->Win[i][0];
y = FLIP( (GLint) VB->Win[i][1] );
SetPixel(DC,x,y,pixel);
}
}
SelectObject(DC,Old_Pen);
DeleteObject(Pen);
}
DD_RELEASEDC;
}
/* Return pointer to accerated points function */
static points_func choose_points_function(void)
{
if (CC->Point.Size==1.0 && !CC->Point.SmoothFlag && CC->RasterMask==0
&& !CC->Texture.Enabled && Current->rgb_flag) {
return fast_rgb_points;
}
else {
return NULL;
}
}
/* Draw a line using the color specified by VB->Color[pv] */
static void fast_flat_rgb_line(GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
int x0, y0, x1, y1;
unsigned long pixel;
HDC DC=DD_GETDC;
HPEN Pen;
HPEN Old_Pen;
struct vertex_buffer* VB = ctx->VB;
Current = ctx->DriverCtx;
if (VB->MonoColor) {
pixel = Current->pixel; /* use current color */
}
else {
pixel = RGB(VB->Color[pv][0]*255.0, VB->Color[pv][1]*255.0, VB->Color[pv][2]*255.0);
}
x0 = (int) VB->Win[v0][0];
y0 = FLIP( (int) VB->Win[v0][1] );
x1 = (int) VB->Win[v1][0];
y1 = FLIP( (int) VB->Win[v1][1] );
Pen=CreatePen(PS_SOLID,1,pixel);
Old_Pen=SelectObject(DC,Pen);
MoveToEx(DC,x0,y0,NULL);
LineTo(DC,x1,y1);
SelectObject(DC,Old_Pen);
DeleteObject(Pen);
DD_RELEASEDC;
}
/* Return pointer to accerated line function */
static line_func choose_line_function(void)
{
if (CC->Line.Width==1.0 && !CC->Line.SmoothFlag && !CC->Line.StippleFlag
&& CC->Light.ShadeModel==GL_FLAT && CC->RasterMask==0
&& !CC->Texture.Enabled && Current->rgb_flag) {
return fast_flat_rgb_line;
}
else {
return NULL;
}
}
/* Draw a convex polygon using color VB->Color[pv] */
static void fast_flat_rgb_polygon(GLcontext *ctx, GLuint n, GLuint vlist[], GLuint pv )
{
POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
HDC DC=DD_GETDC;
HPEN Pen;
HBRUSH Brush;
HPEN Old_Pen;
HBRUSH Old_Brush;
GLint pixel;
int i;
struct vertex_buffer* VB = ctx->VB;
Current = ctx->DriverCtx;
if (VB->MonoColor) {
pixel = Current->pixel; /* use current color */
}
else {
pixel = RGB(VB->Color[pv][0]*255.0, VB->Color[pv][1]*255.0, VB->Color[pv][2]*255.0);
}
Pen=CreatePen(PS_SOLID,1,pixel);
Brush=CreateSolidBrush(pixel);
Old_Pen=SelectObject(DC,Pen);
Old_Brush=SelectObject(DC,Brush);
for (i=0; i<n; i++) {
int j = vlist[i];
Pts[i].x = (int) VB->Win[j][0];
Pts[i].y = FLIP( (int) VB->Win[j][1] );
}
Polygon(DC,Pts,n);
SelectObject(DC,Old_Pen);
SelectObject(DC,Old_Brush);
DeleteObject(Pen);
DeleteObject(Brush);
DD_RELEASEDC;
free(Pts);
}
/* Return pointer to accerated polygon function */
static polygon_func choose_polygon_function( void )
{
if (!CC->Polygon.SmoothFlag && !CC->Polygon.StippleFlag
&& CC->Light.ShadeModel==GL_FLAT && CC->RasterMask==0
&& !CC->Texture.Enabled && Current->rgb_flag==GL_TRUE) {
return fast_flat_rgb_polygon;
}
else {
return NULL;
}
}
/**********************************************************************/
/***** Span-based pixel drawing *****/
/**********************************************************************/
/* Write a horizontal span of color-index pixels with a boolean mask. */
void write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLuint index[],
const GLubyte mask[] )
{
int i;
char *Mem;
Current = ctx->DriverCtx;
Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=index[i];
}
/*
* Write a horizontal span of pixels with a boolean mask. The current
* color index is used for all pixels.
*/
void write_monoindex_span(GLcontext *ctx, GLuint n,GLint x,GLint y,const GLubyte mask[])
{
int i;
char *Mem;
Current = ctx->DriverCtx;
Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=Current->pixel;
}
/* Write a horizontal span of color pixels with a boolean mask. */
void write_color_span(GLcontext *ctx,
GLuint n, GLint x, GLint y,
const GLubyte red[], const GLubyte green[],
const GLubyte blue[], const GLubyte alpha[],
const GLubyte mask[] )
{
Current = ctx->DriverCtx;
if (Current->rgb_flag==GL_TRUE)
{
int i;
HDC DC=DD_GETDC;
y=FLIP(y);
if (mask) {
for (i=0; i<n; i++)
if (mask[i])
SetPixel(DC,x+i,y,RGB(red[i],green[i],blue[i]));
}
else {
for (i=0; i<n; i++)
SetPixel(DC,x+i,y,RGB(red[i],green[i],blue[i]));
}
DD_RELEASEDC;
}
else
{
int i;
char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
if (mask) {
for (i=0; i<n; i++)
if (mask[i])
Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
}
else {
for (i=0; i<n; i++)
Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
}
}
}
/*
* Write a horizontal span of pixels with a boolean mask. The current color
* is used for all pixels.
*/
void write_monocolor_span(GLcontext *ctx,
GLuint n, GLint x, GLint y,const GLubyte mask[])
{
int i;
HDC DC=DD_GETDC;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_TRUE);
y=FLIP(y);
for (i=0; i<n; i++)
if (mask[i])
SetPixel(DC,x+i,y,Current->pixel);
DD_RELEASEDC;
}
/**********************************************************************/
/***** Array-based pixel drawing *****/
/**********************************************************************/
/* Write an array of pixels with a boolean mask. */
void write_index_pixels( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
const GLuint index[], const GLubyte mask[] )
{
int i;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
*Mem = index[i];
}
}
}
/*
* Write an array of pixels with a boolean mask. The current color
* index is used for all pixels.
*/
void write_monoindex_pixels( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLubyte mask[] )
{
int i;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
*Mem = Current->pixel;
}
}
}
/* Write an array of pixels with a boolean mask. */
void write_color_pixels( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
const GLubyte r[], const GLubyte g[],
const GLubyte b[], const GLubyte a[],
const GLubyte mask[] )
{
int i;
HDC DC=DD_GETDC;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++)
if (mask[i])
SetPixel(DC,x[i],FLIP(y[i]),RGB(r[i],g[i],b[i]));
DD_RELEASEDC;
}
/*
* Write an array of pixels with a boolean mask. The current color
* is used for all pixels.
*/
void write_monocolor_pixels( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLubyte mask[] )
{
int i;
HDC DC=DD_GETDC;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++)
if (mask[i])
SetPixel(DC,x[i],FLIP(y[i]),Current->pixel);
DD_RELEASEDC;
}
/**********************************************************************/
/***** Read spans/arrays of pixels *****/
/**********************************************************************/
/* Read a horizontal span of color-index pixels. */
void read_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, GLuint index[])
{
int i;
char *Mem;
Current = ctx->DriverCtx;
Mem=Current->ScreenMem+y*Current->ScanWidth+x;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++)
index[i]=Mem[i];
}
/* Read an array of color index pixels. */
void read_index_pixels( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
GLuint indx[], const GLubyte mask[] )
{
int i;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_FALSE);
for (i=0; i<n; i++) {
if (mask[i]) {
indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
}
}
}
/* Read a horizontal span of color pixels. */
void read_color_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLubyte red[], GLubyte green[],
GLubyte blue[], GLubyte alpha[] )
{
int i;
COLORREF Color;
HDC DC=DD_GETDC;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_TRUE);
y=FLIP(y);
for (i=0; i<n; i++)
{
Color=GetPixel(DC,x+i,y);
red[i]=GetRValue(Color);
green[i]=GetGValue(Color);
blue[i]=GetBValue(Color);
alpha[i]=255;
}
DD_RELEASEDC;
memset(alpha,0,n*sizeof(GLint));
}
/* Read an array of color pixels. */
void read_color_pixels( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
GLubyte red[], GLubyte green[],
GLubyte blue[], GLubyte alpha[],
const GLubyte mask[] )
{
int i;
COLORREF Color;
HDC DC=DD_GETDC;
Current = ctx->DriverCtx;
assert(Current->rgb_flag==GL_TRUE);
for (i=0; i<n; i++) {
if (mask[i]) {
Color=GetPixel(DC,x[i],FLIP(y[i]));
red[i]=GetRValue(Color);
green[i]=GetGValue(Color);
blue[i]=GetBValue(Color);
alpha[i]=255;
}
}
DD_RELEASEDC;
memset(alpha,0,n*sizeof(GLint));
}
/**********************************************************************/
/**********************************************************************/
void wmesa_setup_DD_pointers( GLcontext *ctx )
{
ctx->Driver.UpdateState = wmesa_setup_DD_pointers;
ctx->Driver.ClearIndex = clear_index;
ctx->Driver.ClearColor = clear_color;
ctx->Driver.Clear = clear;
ctx->Driver.Index = set_index;
ctx->Driver.Color = set_color;
ctx->Driver.SetBuffer = set_buffer;
ctx->Driver.GetBufferSize = buffer_size;
/* Pixel/span writing functions: */
ctx->Driver.WriteColorSpan = write_color_span;
ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
ctx->Driver.WriteColorPixels = write_color_pixels;
ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
ctx->Driver.WriteIndexSpan = write_index_span;
ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
ctx->Driver.WriteIndexPixels = write_index_pixels;
ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
/* Pixel/span reading functions: */
ctx->Driver.ReadIndexSpan = read_index_span;
ctx->Driver.ReadColorSpan = read_color_span;
ctx->Driver.ReadIndexPixels = read_index_pixels;
ctx->Driver.ReadColorPixels = read_color_pixels;
ctx->Driver.Finish = finish;
ctx->Driver.Flush = flush;
ctx->Driver.IndexMask = index_mask;
ctx->Driver.ColorMask = color_mask;
ctx->Driver.LogicOp = logicop;
ctx->Driver.Dither = dither;
CC = ctx;
// ctx->Driver.PointsFunc = choose_points_function(ctx);
// ctx->Driver.LineFunc = choose_line_function(ctx);
}
/**********************************************************************/
/***** WMesa API Functions *****/
/**********************************************************************/
#define PAL_SIZE 256
static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
{
int i;
HDC hdc;
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[PAL_SIZE];
} Palette =
{
0x300,
PAL_SIZE
};
hdc=GetDC(NULL);
if (Pal!=NULL)
GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
else
GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
{
for(i = 0; i <PAL_SIZE; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
Palette.aEntries[255].peRed = 255;
Palette.aEntries[255].peGreen = 255;
Palette.aEntries[255].peBlue = 255;
Palette.aEntries[255].peFlags = 0;
Palette.aEntries[0].peRed = 0;
Palette.aEntries[0].peGreen = 0;
Palette.aEntries[0].peBlue = 0;
Palette.aEntries[0].peFlags = 0;
}
else
{
int nStaticColors;
int nUsableColors;
nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
for (i=0; i<nStaticColors; i++)
Palette.aEntries[i].peFlags = 0;
nUsableColors = PAL_SIZE-nStaticColors;
for (; i<nUsableColors; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
for (; i<PAL_SIZE-nStaticColors; i++)
Palette.aEntries[i].peFlags = PC_RESERVED;
for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
Palette.aEntries[i].peFlags = 0;
}
ReleaseDC(NULL,hdc);
for (i=0; i<PAL_SIZE; i++)
{
aRGB[i].rgbRed=Palette.aEntries[i].peRed;
aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
}
}
WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE Pal, GLboolean rgb_flag,
GLboolean db_flag )
{
BITMAPINFO *Rec;
HDC DC;
RECT CR;
WMesaContext c;
GLfloat rscale, gscale, bscale, ascale;
GLint index_bits;
c = (struct wmesa_context *) calloc(1,sizeof(struct wmesa_context));
if (!c)
return NULL;
c->Window=hWnd;
if (rgb_flag==GL_FALSE)
{
c->rgb_flag = GL_FALSE;
c->pixel = 1;
db_flag=GL_TRUE; // WinG requires double buffering
//c->gl_ctx->BufferDepth = windepth;
}
else
{
c->rgb_flag = GL_TRUE;
c->pixel = 0;
}
GetClientRect(c->Window,&CR);
c->width=CR.right;
c->height=CR.bottom;
if (db_flag)
{
c->db_flag = 1;
/* Double buffered */
if (c->rgb_flag==GL_TRUE)
{
DC=GetDC(c->Window);
c->Compat_DC=CreateCompatibleDC(DC);
c->Compat_BM=CreateCompatibleBitmap(DC,c->width,c->height);
ReleaseDC(c->Window,DC);
c->Old_Compat_BM=SelectObject(c->Compat_DC,c->Compat_BM);
}
else
{
c->Compat_DC=WinGCreateDC();
Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
c->hPal=Pal;
GetPalette(Pal,Rec->bmiColors);
WinGRecommendDIBFormat(Rec);
Rec->bmiHeader.biWidth=c->width;
Rec->bmiHeader.biHeight*=c->height;
Rec->bmiHeader.biClrUsed=PAL_SIZE;
if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
{
MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
exit(1);
}
c->Compat_BM=WinGCreateBitmap(c->Compat_DC,Rec,&((void *) c->ScreenMem));
c->Old_Compat_BM=SelectObject(c->Compat_DC,c->Compat_BM);
WinGSetDIBColorTable(c->Compat_DC,0,PAL_SIZE,Rec->bmiColors);
c->IndexFormat=Rec;
c->ScanWidth=c->width;
if ((c->ScanWidth%sizeof(long))!=0)
c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
}
}
else
{
/* Single Buffered */
c->db_flag = 0;
}
if (rgb_flag) {
rscale = 255.0;
gscale = 255.0;
bscale = 255.0;
ascale = 255.0;
index_bits = 0;
}
else {
rscale = 0.0;
gscale = 0.0;
bscale = 0.0;
ascale = 0.0;
index_bits = 8;
}
/* allocate a new Mesa context */
c->gl_ctx = gl_create_context( (rgb_flag) ? GL_TRUE : GL_FALSE,
GL_FALSE, /* software alpha */
GL_FALSE, /* db_flag */
16, /* depth_bits */
8, /* stencil_bits */
8, /* accum_bits */
index_bits,
rscale,
gscale,
bscale,
ascale,
NULL,
(void *) c);
wmesa_setup_DD_pointers(c->gl_ctx);
return c;
}
void WMesaDestroyContext( WMesaContext c )
{
gl_destroy_context( c->gl_ctx );
if (c->db_flag)
{
SelectObject(c->Compat_DC,c->Old_Compat_BM);
DeleteDC(c->Compat_DC);
DeleteObject(c->Compat_BM);
}
free( (void *) c );
}
void WMesaMakeCurrent( WMesaContext c )
{
gl_make_current( c->gl_ctx );
Current = c;
wmesa_setup_DD_pointers(c->gl_ctx);
if (Current->gl_ctx->Viewport.Width==0) {
/* initialize viewport to window size */
glViewport( 0, 0, Current->width, Current->height );
}
}
void WMesaSwapBuffers( void )
{
// *** Perhaps the DC should be saved in WMesaContext?
HDC DC;
if (Current->db_flag)
{
DC=GetDC(Current->Window);
if (Current->rgb_flag)
BitBlt(DC,0,0,Current->width,Current->height,Current->Compat_DC,0,0,SRCCOPY);
else
WinGBitBlt(DC,0,0,Current->width,Current->height,Current->Compat_DC,0,0);
ReleaseDC(Current->Window,DC);
}
}
void WMesaPaletteChange(HPALETTE Pal)
{
if (Current && Current->rgb_flag==GL_FALSE)
{
Current->hPal=Pal;
GetPalette(Pal,Current->IndexFormat->bmiColors);
WinGSetDIBColorTable(Current->Compat_DC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.