⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmesa.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
			 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 + -