📄 osmesa.c
字号:
accumBits, accumBits, alphaBits ? accumBits : 0, 1 /* num samples */ ); if (!osmesa->gl_visual) { FREE(osmesa); return NULL; } /* Initialize device driver function table */ _mesa_init_driver_functions(&functions); /* override with our functions */ functions.GetString = get_string; functions.UpdateState = osmesa_update_state; functions.GetBufferSize = get_buffer_size; if (!_mesa_initialize_context(&osmesa->mesa, osmesa->gl_visual, sharelist ? &sharelist->mesa : (GLcontext *) NULL, &functions, (void *) osmesa)) { _mesa_destroy_visual( osmesa->gl_visual ); FREE(osmesa); return NULL; } _mesa_enable_sw_extensions(&(osmesa->mesa)); _mesa_enable_1_3_extensions(&(osmesa->mesa)); _mesa_enable_1_4_extensions(&(osmesa->mesa)); _mesa_enable_1_5_extensions(&(osmesa->mesa)); osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual); if (!osmesa->gl_buffer) { _mesa_destroy_visual( osmesa->gl_visual ); _mesa_free_context_data( &osmesa->mesa ); FREE(osmesa); return NULL; } /* create front color buffer in user-provided memory (no back buffer) */ _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, new_osmesa_renderbuffer(format)); _mesa_add_soft_renderbuffers(osmesa->gl_buffer, GL_FALSE, /* color */ osmesa->gl_visual->haveDepthBuffer, osmesa->gl_visual->haveStencilBuffer, osmesa->gl_visual->haveAccumBuffer, GL_FALSE, /* alpha */ GL_FALSE /* aux */ ); osmesa->format = format; osmesa->buffer = NULL; osmesa->width = 0; osmesa->height = 0; osmesa->userRowLength = 0; osmesa->rowlength = 0; osmesa->yup = GL_TRUE; osmesa->rInd = rind; osmesa->gInd = gind; osmesa->bInd = bind; osmesa->aInd = aind; /* Initialize the software rasterizer and helper modules. */ { GLcontext *ctx = &osmesa->mesa; SWcontext *swrast; TNLcontext *tnl; if (!_swrast_CreateContext( ctx ) || !_ac_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(osmesa->gl_visual); _mesa_free_context_data(ctx); _mesa_free(osmesa); return NULL; } _swsetup_Wakeup( ctx ); /* use default TCL pipeline */ tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; /* Extend the software rasterizer with our optimized line and triangle * drawing functions. */ swrast = SWRAST_CONTEXT( ctx ); swrast->choose_line = osmesa_choose_line; swrast->choose_triangle = osmesa_choose_triangle; } } return osmesa;}/* * Destroy an Off-Screen Mesa rendering context. * * Input: ctx - the context to destroy */GLAPI void GLAPIENTRYOSMesaDestroyContext( OSMesaContext ctx ){ if (ctx) { _swsetup_DestroyContext( &ctx->mesa ); _tnl_DestroyContext( &ctx->mesa ); _ac_DestroyContext( &ctx->mesa ); _swrast_DestroyContext( &ctx->mesa ); _mesa_destroy_visual( ctx->gl_visual ); _mesa_destroy_framebuffer( ctx->gl_buffer ); _mesa_free_context_data( &ctx->mesa ); FREE( ctx ); }}/* * Recompute the values of the context's rowaddr array. */static voidcompute_row_addresses( OSMesaContext ctx ){ GLint bytesPerPixel, bytesPerRow, i; GLubyte *origin = (GLubyte *) ctx->buffer; if (ctx->format == OSMESA_COLOR_INDEX) { /* CI mode */ bytesPerPixel = 1 * sizeof(GLubyte); } else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) { /* RGB mode */ bytesPerPixel = 3 * sizeof(GLchan); } else if (ctx->format == OSMESA_RGB_565) { /* 5/6/5 RGB pixel in 16 bits */ bytesPerPixel = 2; } else { /* RGBA mode */ bytesPerPixel = 4 * sizeof(GLchan); } bytesPerRow = ctx->rowlength * bytesPerPixel; if (ctx->yup) { /* Y=0 is bottom line of window */ for (i = 0; i < MAX_HEIGHT; i++) { ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow); } } else { /* Y=0 is top line of window */ for (i = 0; i < MAX_HEIGHT; i++) { GLint j = ctx->height - i - 1; ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow); } }}/* * Bind an OSMesaContext to an image buffer. The image buffer is just a * block of memory which the client provides. Its size must be at least * as large as width*height*sizeof(type). Its address should be a multiple * of 4 if using RGBA mode. * * Image data is stored in the order of glDrawPixels: row-major order * with the lower-left image pixel stored in the first array position * (ie. bottom-to-top). * * If the context's viewport hasn't been initialized yet, it will now be * initialized to (0,0,width,height). * * Input: ctx - the rendering context * buffer - the image buffer memory * type - data type for pixel components * Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5 * are supported. But if Mesa's been compiled with CHAN_BITS==16 * then type must be GL_UNSIGNED_SHORT. And if Mesa's been build * with CHAN_BITS==32 then type must be GL_FLOAT. * width, height - size of image buffer in pixels, at least 1 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, * invalid buffer address, invalid type, width<1, height<1, * width>internal limit or height>internal limit. */GLAPI GLboolean GLAPIENTRYOSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height ){ if (!ctx || !buffer || width < 1 || height < 1 || width > MAX_WIDTH || height > MAX_HEIGHT) { return GL_FALSE; } if (ctx->format == OSMESA_RGB_565) { if (type != GL_UNSIGNED_SHORT_5_6_5) return GL_FALSE; } else if (type != CHAN_TYPE) { return GL_FALSE; } /* Need to set these before calling _mesa_make_current() since the first * time the context is bound, _mesa_make_current() will call our * get_buffer_size() function to initialize the viewport. These are the * values returned by get_buffer_size(): */ ctx->buffer = buffer; ctx->width = width; ctx->height = height; osmesa_update_state( &ctx->mesa, 0 ); /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ _glapi_check_multithread(); _mesa_make_current( &ctx->mesa, ctx->gl_buffer, ctx->gl_buffer ); if (ctx->userRowLength) ctx->rowlength = ctx->userRowLength; else ctx->rowlength = width; compute_row_addresses( ctx ); /* this will make ensure we recognize the new buffer size */ _mesa_resize_framebuffer(&ctx->mesa, ctx->gl_buffer, width, height); return GL_TRUE;}GLAPI OSMesaContext GLAPIENTRYOSMesaGetCurrentContext( void ){ GLcontext *ctx = _mesa_get_current_context(); if (ctx) return (OSMesaContext) ctx; else return NULL;}GLAPI void GLAPIENTRYOSMesaPixelStore( GLint pname, GLint value ){ OSMesaContext osmesa = OSMesaGetCurrentContext(); switch (pname) { case OSMESA_ROW_LENGTH: if (value<0) { _mesa_error( &osmesa->mesa, GL_INVALID_VALUE, "OSMesaPixelStore(value)" ); return; } osmesa->userRowLength = value; osmesa->rowlength = value ? value : osmesa->width; break; case OSMESA_Y_UP: osmesa->yup = value ? GL_TRUE : GL_FALSE; break; default: _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" ); return; } compute_row_addresses( osmesa );}GLAPI void GLAPIENTRYOSMesaGetIntegerv( GLint pname, GLint *value ){ OSMesaContext osmesa = OSMesaGetCurrentContext(); switch (pname) { case OSMESA_WIDTH: *value = osmesa->width; return; case OSMESA_HEIGHT: *value = osmesa->height; return; case OSMESA_FORMAT: *value = osmesa->format; return; case OSMESA_TYPE: *value = CHAN_TYPE; return; case OSMESA_ROW_LENGTH: *value = osmesa->userRowLength; return; case OSMESA_Y_UP: *value = osmesa->yup; return; case OSMESA_MAX_WIDTH: *value = MAX_WIDTH; return; case OSMESA_MAX_HEIGHT: *value = MAX_HEIGHT; return; default: _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)"); return; }}/* * Return the depth buffer associated with an OSMesa context. * Input: c - the OSMesa context * Output: width, height - size of buffer in pixels * bytesPerValue - bytes per depth value (2 or 4) * buffer - pointer to depth buffer values * Return: GL_TRUE or GL_FALSE to indicate success or failure. */GLAPI GLboolean GLAPIENTRYOSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, GLint *bytesPerValue, void **buffer ){ struct gl_renderbuffer *rb = NULL; if (c->gl_buffer) rb = c->gl_buffer->Attachment[BUFFER_DEPTH].Renderbuffer; if (!rb || !rb->Data) { /*if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {*/ *width = 0; *height = 0; *bytesPerValue = 0; *buffer = 0; return GL_FALSE; } else { *width = c->gl_buffer->Width; *height = c->gl_buffer->Height; if (c->gl_visual->depthBits <= 16) *bytesPerValue = sizeof(GLushort); else *bytesPerValue = sizeof(GLuint); *buffer = rb->Data; return GL_TRUE; }}/* * Return the color buffer associated with an OSMesa context. * Input: c - the OSMesa context * Output: width, height - size of buffer in pixels * format - the pixel format (OSMESA_FORMAT) * buffer - pointer to color buffer values * Return: GL_TRUE or GL_FALSE to indicate success or failure. */GLAPI GLboolean GLAPIENTRYOSMesaGetColorBuffer( OSMesaContext c, GLint *width, GLint *height, GLint *format, void **buffer ){ if (!c->buffer) { *width = 0; *height = 0; *format = 0; *buffer = 0; return GL_FALSE; } else { *width = c->width; *height = c->height; *format = c->format; *buffer = c->buffer; return GL_TRUE; }}struct name_function{ const char *Name; OSMESAproc Function;};static struct name_function functions[] = { { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext }, { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt }, { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext }, { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent }, { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext }, { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore }, { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv }, { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer }, { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer }, { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress }, { NULL, NULL }};GLAPI OSMESAproc GLAPIENTRYOSMesaGetProcAddress( const char *funcName ){ int i; for (i = 0; functions[i].Name; i++) { if (_mesa_strcmp(functions[i].Name, funcName) == 0) return functions[i].Function; } return _glapi_get_proc_address(funcName);}GLAPI void GLAPIENTRYOSMesaColorClamp(GLboolean enable){ OSMesaContext osmesa = OSMesaGetCurrentContext(); if (enable == GL_TRUE) { osmesa->mesa.Color.ClampFragmentColor = GL_TRUE; } else { osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -