📄 wmesa.c
字号:
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_16(const GLcontext* ctx,
struct gl_renderbuffer *rb,
GLuint n,
const GLint x[], const GLint y[],
const GLchan color[4],
const GLubyte mask[])
{
GLuint i;
PWMC pwc = Current;
(void) ctx;
for (i=0; i<n; i++)
if (mask[i])
WMSETPIXEL16(pwc, FLIP(y[i]),x[i],color[RCOMP],
color[GCOMP], color[BCOMP]);
}
/* Read a horizontal span of color pixels. */
static void read_rgba_span_16(const GLcontext* ctx,
struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4] )
{
GLuint i, pixel;
LPWORD lpw;
PWMC pwc = Current;
y = FLIP(y);
lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x;
for (i=0; i<n; i++) {
pixel = lpw[i];
/* Windows uses 5,5,5 for 16-bit */
rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
rgba[i][BCOMP] = (pixel & 0x001f) << 3;
rgba[i][ACOMP] = 255;
}
}
/* Read an array of color pixels. */
static void read_rgba_pixels_16(const GLcontext* ctx,
struct gl_renderbuffer *rb,
GLuint n, const GLint x[], const GLint y[],
GLubyte rgba[][4])
{
GLuint i, pixel;
LPWORD lpw;
PWMC pwc = Current;
for (i=0; i<n; i++) {
GLint y2 = FLIP(y[i]);
lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * y2)) + x[i];
pixel = lpw[i];
/* Windows uses 5,5,5 for 16-bit */
rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
rgba[i][BCOMP] = (pixel & 0x001f) << 3;
rgba[i][ACOMP] = 255;
}
}
/**********************************************************************/
/***** BUFFER Functions *****/
/**********************************************************************/
static void
wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
{
_mesa_free(rb);
}
static GLboolean
wmesa_renderbuffer_storage(GLcontext *ctx,
struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width,
GLuint height)
{
return GL_TRUE;
}
/**
* Called by ctx->Driver.ResizeBuffers()
* Resize the front/back colorbuffers to match the latest window size.
*/
static void
wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
GLuint width, GLuint height)
{
RECT CR;
if (Current->width != width || Current->height != height) {
Current->width = width;
Current->height = height;
/* Realloc back buffer */
if (Current->db_flag) {
wmDeleteBackingStore(Current);
wmCreateBackingStore(Current, width, height);
}
GetClientRect(Current->Window, &CR);
Current->width = CR.right;
Current->height = CR.bottom;
}
_mesa_resize_framebuffer(ctx, buffer, width, height);
}
/**
* Called by glViewport.
* This is a good time for us to poll the current window size and adjust
* our renderbuffers to match the current window size.
* Remember, we have no opportunity to respond to conventional
* resize events since the driver has no event loop.
* Thus, we poll.
* Note that this trick isn't fool-proof. If the application never calls
* glViewport, our notion of the current window size may be incorrect.
*/
static void wmesa_viewport(GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height)
{
if (Current->width != width || Current->height != height) {
wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, width, height);
ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */
}
}
/**
* Called when the driver should update it's state, based on the new_state
* flags.
*/
static void wmesa_update_state(GLcontext *ctx, GLuint new_state)
{
_swrast_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
_ac_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
/* TODO - need code to update the span functions in case the
* renderer changes the target buffer (like a DB app writing to
* the front buffer). */
}
/**********************************************************************/
/***** WMESA Functions *****/
/**********************************************************************/
WMesaContext WMesaCreateContext(HWND hWnd,
HPALETTE* Pal,
GLboolean rgb_flag,
GLboolean db_flag,
GLboolean alpha_flag)
{
RECT CR;
WMesaContext c;
struct dd_function_table functions;
struct gl_renderbuffer *rb;
(void) Pal;
/* Indexed mode not supported */
if (!rgb_flag)
return NULL;
c = CALLOC_STRUCT(wmesa_context);
if (!c)
return NULL;
c->Window = hWnd;
c->hDC = GetDC(hWnd);
GetClientRect(c->Window, &CR);
c->width = CR.right;
c->height = CR.bottom;
c->clearPen = CreatePen(PS_SOLID, 1, 0);
c->clearBrush = CreateSolidBrush(0);
/* Create back buffer if double buffered */
if (db_flag) {
c->db_flag = 1;
wmCreateBackingStore(c, c->width, c->height);
}
c->gl_visual = _mesa_create_visual(rgb_flag,
db_flag, /* db_flag */
GL_FALSE, /* stereo */
8,8,8, /* color RGB */
alpha_flag ? 8 : 0, /* color A */
0, /* index bits */
16, /* depth_bits */
8, /* stencil_bits */
16,16,16, /* accum RGB */
alpha_flag ? 16 : 0, /* accum A */
1);
if (!c->gl_visual) {
_mesa_free(c);
return NULL;
}
/* Set up driver functions */
_mesa_init_driver_functions(&functions);
/* Fill in required functions */
functions.GetString = wmesa_get_string;
functions.UpdateState = wmesa_update_state;
functions.GetBufferSize = wmesa_get_buffer_size;
functions.Flush = wmesa_flush;
functions.Clear = clear;
functions.ClearIndex = clear_index;
functions.ClearColor = clear_color;
functions.ResizeBuffers = wmesa_resize_buffers;
functions.Viewport = wmesa_viewport;
/* allocate a new Mesa context */
c->gl_ctx = _mesa_create_context(c->gl_visual, NULL,
&functions, (void *)c);
if (!c->gl_ctx) {
_mesa_destroy_visual( c->gl_visual );
_mesa_free(c);
return NULL;
}
_mesa_enable_sw_extensions(c->gl_ctx);
_mesa_enable_1_3_extensions(c->gl_ctx);
_mesa_enable_1_4_extensions(c->gl_ctx);
_mesa_enable_1_5_extensions(c->gl_ctx);
_mesa_enable_2_0_extensions(c->gl_ctx);
c->gl_buffer = _mesa_create_framebuffer(c->gl_visual);
if (!c->gl_buffer) {
_mesa_destroy_visual(c->gl_visual);
_mesa_free_context_data(c->gl_ctx);
_mesa_free(c);
return NULL;
}
rb = CALLOC_STRUCT(gl_renderbuffer);
if (!rb) {
_mesa_destroy_visual(c->gl_visual);
_mesa_destroy_framebuffer(c->gl_buffer);
_mesa_free_context_data(c->gl_ctx);
_mesa_free(c);
return NULL;
}
_mesa_init_renderbuffer(rb, (GLuint)0);
rb->_BaseFormat = GL_RGBA;
rb->InternalFormat = GL_RGBA;
rb->DataType = CHAN_TYPE;
rb->Delete = wmesa_delete_renderbuffer;
rb->AllocStorage = wmesa_renderbuffer_storage;
if (db_flag) {
switch(c->cColorBits) {
case 16:
rb->PutRow = write_rgba_span_16;
rb->PutRowRGB = write_rgb_span_16;
rb->PutMonoRow = write_mono_rgba_span_16;
rb->PutValues = write_rgba_pixels_16;
rb->PutMonoValues = write_mono_rgba_pixels_16;
rb->GetRow = read_rgba_span_16;
rb->GetValues = read_rgba_pixels_16;
break;
case 32:
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;
break;
default:
break;
}
_mesa_add_renderbuffer(c->gl_buffer, BUFFER_BACK_LEFT, rb);
}
else { /* single buffer */
rb->PutRow = write_rgba_span_single;
rb->PutRowRGB = write_rgb_span_single;
rb->PutMonoRow = write_mono_rgba_span_single;
rb->PutValues = write_rgba_pixels_single;
rb->PutMonoValues = write_mono_rgba_pixels_single;
rb->GetRow = read_rgba_span_single;
rb->GetValues = read_rgba_pixels_single;
}
_mesa_add_renderbuffer(c->gl_buffer, BUFFER_FRONT_LEFT, rb);
_mesa_add_soft_renderbuffers(c->gl_buffer,
GL_FALSE, /* color */
c->gl_visual->depthBits > 0,
c->gl_visual->stencilBits > 0,
c->gl_visual->accumRedBits > 0,
alpha_flag,
GL_FALSE);
/* Initialize the software rasterizer and helper modules. */
if (!_swrast_CreateContext(c->gl_ctx) ||
!_ac_CreateContext(c->gl_ctx) ||
!_tnl_CreateContext(c->gl_ctx) ||
!_swsetup_CreateContext(c->gl_ctx)) {
_mesa_destroy_visual(c->gl_visual);
_mesa_destroy_framebuffer(c->gl_buffer);
_mesa_free_context_data(c->gl_ctx);
_mesa_free(c);
return NULL;
}
_swsetup_Wakeup(c->gl_ctx);
TNL_CONTEXT(c->gl_ctx)->Driver.RunPipeline = _tnl_run_pipeline;
return c;
}
void WMesaDestroyContext( void )
{
WMesaContext c = Current;
WMesaMakeCurrent(NULL);
ReleaseDC(c->Window, c->hDC);
DeleteObject(c->clearPen);
DeleteObject(c->clearBrush);
if (c->db_flag)
wmDeleteBackingStore(c);
_swsetup_DestroyContext(c->gl_ctx);
_tnl_DestroyContext(c->gl_ctx);
_ac_DestroyContext(c->gl_ctx);
_swrast_DestroyContext(c->gl_ctx);
_mesa_destroy_visual(c->gl_visual);
_mesa_destroy_framebuffer(c->gl_buffer);
_mesa_free_context_data(c->gl_ctx);
_mesa_free(c->gl_ctx);
_mesa_free(c);
}
void WMesaMakeCurrent(WMesaContext c)
{
/* return if already current */
if (Current == c)
return;
if ((Current = c) != 0)
_mesa_make_current(c->gl_ctx, c->gl_buffer, c->gl_buffer);
}
void WMesaSwapBuffers( void )
{
GET_CURRENT_CONTEXT(ctx);
/* If we're swapping the buffer associated with the current context
* we have to flush any pending rendering commands first.
*/
if (Current && Current->gl_ctx == ctx)
_mesa_notifySwapBuffers(ctx);
if (Current->db_flag)
wmesa_flush(ctx);
}
/**********************************************************************/
/***** END *****/
/**********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -