📄 wmesa.c
字号:
GLubyte rgba[][4] ){ GLuint i, pixel; LPWORD lpw; WMesaContext pwc = wmesa_context(ctx); WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); y = FLIP(y); lpw = ((LPWORD)(pwfb->pbPixels + pwfb->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; WMesaContext pwc = wmesa_context(ctx); WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); for (i=0; i<n; i++) { GLint y2 = FLIP(y[i]); lpw = ((LPWORD)(pwfb->pbPixels + pwfb->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 voidwmesa_delete_renderbuffer(struct gl_renderbuffer *rb){ _mesa_free(rb);}/** * This is called by Mesa whenever it determines that the window size * has changed. Do whatever's needed to cope with that. */static GLbooleanwmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height){ rb->Width = width; rb->Height = height; return GL_TRUE;}/** * 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){ if (double_buffer) { /* back buffer */ /* Picking the correct span functions is important because * the DIB was allocated with the indicated depth. */ switch(pixelformat) { case PF_5R6G5B: 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; 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; rb->RedBits = 8; rb->GreenBits = 8; rb->BlueBits = 8; break; default: break; } } else { /* front buffer (actual Windows window) */ rb->PutRow = write_rgba_span_front; rb->PutRowRGB = write_rgb_span_front; rb->PutMonoRow = write_mono_rgba_span_front; rb->PutValues = write_rgba_pixels_front; rb->PutMonoValues = write_mono_rgba_pixels_front; rb->GetRow = read_rgba_span_front; rb->GetValues = read_rgba_pixels_front; rb->RedBits = 8; /* XXX fix these (565?) */ rb->GreenBits = 8; rb->BlueBits = 8; }}/** * Called by ctx->Driver.ResizeBuffers() * Resize the front/back colorbuffers to match the latest window size. */static voidwmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, GLuint width, GLuint height){ WMesaContext pwc = wmesa_context(ctx); WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); if (pwfb->Base.Width != width || pwfb->Base.Height != height) { /* Realloc back buffer */ if (ctx->Visual.doubleBufferMode == 1) { wmDeleteBackingStore(pwfb); wmCreateBackingStore(pwfb, width, height); } } _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. * MakeCurrent also ends up making a call here, so that ensures * we get the viewport set correctly, even if the app does not call * glViewport and relies on the defaults. */static void wmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height){ WMesaContext pwc = wmesa_context(ctx); GLuint new_width, new_height; wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); /** * Resize buffers if the window size changed. */ wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_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 - This code is not complete yet because I * don't know what to do for all state updates. */ if (new_state & _NEW_BUFFERS) { }}/**********************************************************************//***** WMESA Functions *****//**********************************************************************/WMesaContext WMesaCreateContext(HDC hDC, HPALETTE* Pal, GLboolean rgb_flag, GLboolean db_flag, GLboolean alpha_flag){ WMesaContext c; struct dd_function_table functions; GLint red_bits, green_bits, blue_bits, alpha_bits; GLcontext *ctx; GLvisual *visual; (void) Pal; /* Indexed mode not supported */ if (!rgb_flag) return NULL; /* Allocate wmesa context */ c = CALLOC_STRUCT(wmesa_context); if (!c) return NULL;#if 0 /* I do not understand this contributed code */ /* Support memory and device contexts */ if(WindowFromDC(hDC) != NULL) { c->hDC = GetDC(WindowFromDC(hDC)); // huh ???? } else { c->hDC = hDC; }#else c->hDC = hDC;#endif /* Get data for visual */ /* Dealing with this is actually a bit of overkill because Mesa will end * up treating all color component size requests less than 8 by using * a single byte per channel. In addition, the interface to the span * routines passes colors as an entire byte per channel anyway, so there * is nothing to be saved by telling the visual to be 16 bits if the device * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per * channel anyway. * But we go through the motions here anyway. */ switch (GetDeviceCaps(c->hDC, BITSPIXEL)) { case 16: red_bits = green_bits = blue_bits = 5; alpha_bits = 0; break; default: red_bits = green_bits = blue_bits = 8; alpha_bits = 8; break; } /* Create visual based on flags */ visual = _mesa_create_visual(rgb_flag, db_flag, /* db_flag */ GL_FALSE, /* stereo */ red_bits, green_bits, blue_bits, /* color RGB */ alpha_flag ? alpha_bits : 0, /* color A */ 0, /* index bits */ DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ 8, /* stencil_bits */ 16,16,16, /* accum RGB */ alpha_flag ? 16 : 0, /* accum A */ 1); /* num samples */ if (!visual) { _mesa_free(c); return NULL; } /* Set up driver functions */ _mesa_init_driver_functions(&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; /* initialize the Mesa context data */ ctx = &c->gl_ctx; _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c); _mesa_enable_sw_extensions(ctx); _mesa_enable_1_3_extensions(ctx); _mesa_enable_1_4_extensions(ctx); _mesa_enable_1_5_extensions(ctx); _mesa_enable_2_0_extensions(ctx); /* Initialize the software rasterizer and helper modules. */ if (!_swrast_CreateContext(ctx) || !_ac_CreateContext(ctx) || !_tnl_CreateContext(ctx) || !_swsetup_CreateContext(ctx)) { _mesa_free_context_data(ctx); _mesa_free(c); return NULL; } _swsetup_Wakeup(ctx); TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; return c;}void WMesaDestroyContext( WMesaContext pwc ){ GLcontext *ctx = &pwc->gl_ctx; WMesaFramebuffer pwfb; GET_CURRENT_CONTEXT(cur_ctx); if (cur_ctx == ctx) { /* unbind current if deleting current context */ WMesaMakeCurrent(NULL, NULL); } /* clean up frame buffer resources */ pwfb = wmesa_lookup_framebuffer(pwc->hDC); if (pwfb) { if (ctx->Visual.doubleBufferMode == 1) wmDeleteBackingStore(pwfb); wmesa_free_framebuffer(pwc->hDC); } /* Release for device, not memory contexts */ if (WindowFromDC(pwc->hDC) != NULL) { ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); } DeleteObject(pwc->clearPen); DeleteObject(pwc->clearBrush); _swsetup_DestroyContext(ctx); _tnl_DestroyContext(ctx); _ac_DestroyContext(ctx); _swrast_DestroyContext(ctx); _mesa_free_context_data(ctx); _mesa_free(pwc);}/** * Create a new color renderbuffer. */struct gl_renderbuffer *wmesa_new_renderbuffer(void){ struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); if (!rb) 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; return rb;}void WMesaMakeCurrent(WMesaContext c, HDC hdc){ WMesaFramebuffer pwfb; { /* return if already current */ GET_CURRENT_CONTEXT(ctx); WMesaContext pwc = wmesa_context(ctx); if (c == pwc && pwc->hDC == hdc) return; } pwfb = wmesa_lookup_framebuffer(hdc); /* Lazy creation of framebuffers */ if (c && !pwfb && hdc) { struct gl_renderbuffer *rb; GLvisual *visual = &c->gl_ctx.Visual; GLuint width, height; get_window_size(hdc, &width, &height); c->clearPen = CreatePen(PS_SOLID, 1, 0); c->clearBrush = CreateSolidBrush(0); pwfb = wmesa_new_framebuffer(hdc, visual); /* Create back buffer if double buffered */ if (visual->doubleBufferMode == 1) { wmCreateBackingStore(pwfb, width, height); } /* 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); } rb = wmesa_new_renderbuffer(); _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0); /* Let Mesa own the Depth, Stencil, and Accum buffers */ _mesa_add_soft_renderbuffers(&pwfb->Base, GL_FALSE, /* color */ visual->depthBits > 0, visual->stencilBits > 0, visual->accumRedBits > 0, visual->alphaBits >0, GL_FALSE); } if (c && pwfb) _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base); else _mesa_make_current(NULL, NULL, NULL);}void WMesaSwapBuffers( HDC hdc ){ GET_CURRENT_CONTEXT(ctx); WMesaContext pwc = wmesa_context(ctx); WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); if (!pwfb) { _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); return; } /* If we're swapping the buffer associated with the current context * we have to flush any pending rendering commands first. */ if (pwc->hDC == hdc) { _mesa_notifySwapBuffers(ctx); BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, pwfb->dib_hDC, 0, 0, SRCCOPY); } else { /* XXX for now only allow swapping current window */ _mesa_problem(NULL, "wmesa: can't swap non-current window"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -