📄 mgmesa.c
字号:
struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ){ GLuint i, pixel; WORD* lpw; mgMesaContext pwc = mgmesa_context(ctx); mgMesaFramebuffer pwfb = mgmesa_framebuffer(ctx->DrawBuffer); y = FLIP(y); lpw = ((WORD*)(pwfb->pixels + pwfb->pitch * y)) + x; for (i=0; i<n; i++) { pixel = lpw[i]; Pixel2RGB (pwfb->memdc, pixel, &rgba[i][RCOMP], &rgba[i][GCOMP], &rgba[i][BCOMP]); 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; WORD* lpw; mgMesaContext pwc = mgmesa_context(ctx); mgMesaFramebuffer pwfb = mgmesa_framebuffer(ctx->DrawBuffer); for (i=0; i<n; i++) { GLint y2 = FLIP(y[i]); lpw = ((WORD*)(pwfb->pixels + pwfb->pitch * y2)) + x[i]; pixel = lpw[i]; Pixel2RGB (pwfb->memdc, pixel, &rgba[i][RCOMP], &rgba[i][GCOMP], &rgba[i][BCOMP]); rgba[i][ACOMP] = 255; }}/**********************************************************************//***** BUFFER Functions *****//**********************************************************************/static voidmgmesa_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 GLbooleanmgmesa_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 mgmesa_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 MiniGUI 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 voidmgmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, GLuint width, GLuint height){ mgMesaContext pwc = mgmesa_context(ctx); mgMesaFramebuffer pwfb = mgmesa_framebuffer(buffer); if (pwfb->Base.Width != width || pwfb->Base.Height != height) { /* Realloc back buffer */ if (ctx->Visual.doubleBufferMode == 1) { mgDeleteBackingStore(pwfb); mgCreateBackingStore(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 mgmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height){ mgMesaContext pwc = mgmesa_context(ctx); GLuint new_width, new_height; mgmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); /** * Resize buffers if the window size changed. */ mgmesa_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 mgmesa_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) { }}/**********************************************************************//***** MGMESA Functions *****//**********************************************************************/mgMesaContext mgMesaCreateContext(HDC dc, HPALETTE* Pal, GLboolean rgb_flag, GLboolean db_flag, GLboolean alpha_flag){ mgMesaContext 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 mgmesa context */ c = CALLOC_STRUCT(mgmesa_context); if (!c) return NULL;#if 0 /* I do not understand this contributed code */ /* Support memory and device contexts */ if(WindowFromDC(dc) != NULL) { c->dc = GetDC(WindowFromDC(dc)); /* huh ???? */ } else { c->dc = dc; }#else c->dc = dc;#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 (GetGDCapability (c->dc, GDCAP_BITSPP)) { case 16: red_bits = blue_bits = 5; green_bits = 6; 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 = mgmesa_get_string; functions.UpdateState = mgmesa_update_state; functions.GetBufferSize = mgmesa_get_buffer_size; functions.Flush = mgmesa_flush; functions.Clear = clear; functions.ClearIndex = clear_index; functions.ClearColor = clear_color; functions.ResizeBuffers = mgmesa_resize_buffers; functions.Viewport = mgmesa_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 mgMesaDestroyContext( mgMesaContext pwc ){ GLcontext *ctx = &pwc->gl_ctx; mgMesaFramebuffer pwfb; GET_CURRENT_CONTEXT(cur_ctx); if (cur_ctx == ctx) { /* unbind current if deleting current context */ mgMesaMakeCurrent(NULL, 0); } /* clean up frame buffer resources */ pwfb = mgmesa_lookup_framebuffer(pwc->dc); if (pwfb) { if (ctx->Visual.doubleBufferMode == 1) mgDeleteBackingStore(pwfb); mgmesa_free_framebuffer(pwc->dc); } /* Release for device, not memory contexts */ if (WindowFromDC(pwc->dc) != HWND_NULL) { ReleaseDC (pwc->dc); } _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 *mgmesa_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 = mgmesa_delete_renderbuffer; rb->AllocStorage = mgmesa_renderbuffer_storage; return rb;}void mgMesaMakeCurrent(mgMesaContext c, HDC hdc){ mgMesaFramebuffer pwfb; { /* return if already current */ GET_CURRENT_CONTEXT(ctx); mgMesaContext pwc = mgmesa_context(ctx); if (c == pwc && pwc->dc == hdc) return; } pwfb = mgmesa_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); pwfb = mgmesa_new_framebuffer(hdc, visual); /* Create back buffer if double buffered */ if (visual->doubleBufferMode == 1) { mgCreateBackingStore(pwfb, width, height); } /* make render buffers */ if (visual->doubleBufferMode == 1) { rb = mgmesa_new_renderbuffer(); _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb); mgmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1); } rb = mgmesa_new_renderbuffer(); _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); mgmesa_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 mgMesaSwapBuffers (HDC hdc){ GET_CURRENT_CONTEXT (ctx); mgMesaContext pwc = mgmesa_context (ctx); mgMesaFramebuffer pwfb = mgmesa_lookup_framebuffer (hdc); if (!pwfb) { _mesa_problem (NULL, "mgmesa: 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->dc == hdc) { _mesa_notifySwapBuffers(ctx); if (pwfb->memdc) BitBlt (pwfb->memdc, 0, 0, pwfb->Base.Width, pwfb->Base.Height, pwfb->dc, 0, 0, 0); } else { /* XXX for now only allow swapping current window */ _mesa_problem (NULL, "mgmesa: can't swap non-current window"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -