📄 osmesa.c
字号:
/* override with our functions */ functions.GetString = get_string; functions.UpdateState = osmesa_update_state; functions.GetBufferSize = NULL; if (!_mesa_initialize_context(&osmesa->mesa, osmesa->gl_visual, sharelist ? &sharelist->mesa : (GLcontext *) NULL, &functions, (void *) osmesa)) { _mesa_destroy_visual( osmesa->gl_visual ); _mesa_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)); _mesa_enable_2_0_extensions(&(osmesa->mesa)); _mesa_enable_2_1_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 ); _mesa_free(osmesa); return NULL; } /* create front color buffer in user-provided memory (no back buffer) */ osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, format, type); _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); assert(osmesa->rb->RefCount == 2); _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->userRowLength = 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 ) || !_vbo_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. * * \param osmesa the context to destroy */GLAPI void GLAPIENTRYOSMesaDestroyContext( OSMesaContext osmesa ){ if (osmesa) { if (osmesa->rb) _mesa_reference_renderbuffer(&osmesa->rb, NULL); _swsetup_DestroyContext( &osmesa->mesa ); _tnl_DestroyContext( &osmesa->mesa ); _vbo_DestroyContext( &osmesa->mesa ); _swrast_DestroyContext( &osmesa->mesa ); _mesa_destroy_visual( osmesa->gl_visual ); _mesa_unreference_framebuffer( &osmesa->gl_buffer ); _mesa_free_context_data( &osmesa->mesa ); _mesa_free( osmesa ); }}/** * 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: osmesa - 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 may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. And if * Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT, * GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. * width, height - size of image buffer in pixels, at least 1 * Return: GL_TRUE if success, GL_FALSE if error because of invalid osmesa, * invalid buffer address, invalid type, width<1, height<1, * width>internal limit or height>internal limit. */GLAPI GLboolean GLAPIENTRYOSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, GLsizei width, GLsizei height ){ if (!osmesa || !buffer || width < 1 || height < 1 || width > MAX_WIDTH || height > MAX_HEIGHT) { return GL_FALSE; } if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) { return GL_FALSE; }#if 0 if (!(type == GL_UNSIGNED_BYTE || (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) || (type == GL_FLOAT && CHAN_BITS == 32))) { /* i.e. is sizeof(type) * 8 > CHAN_BITS? */ return GL_FALSE; }#endif osmesa_update_state( &osmesa->mesa, 0 ); /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ _glapi_check_multithread(); /* Set renderbuffer fields. Set width/height = 0 to force * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer() */ osmesa->rb->Data = buffer; osmesa->rb->DataType = type; osmesa->rb->Width = osmesa->rb->Height = 0; /* Set the framebuffer's size. This causes the * osmesa_renderbuffer_storage() function to get called. */ _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); osmesa->gl_buffer->Initialized = GL_TRUE; /* XXX TEMPORARY? */ _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer ); /* Remove renderbuffer attachment, then re-add. This installs the * renderbuffer adaptor/wrapper if needed (for bpp conversion). */ _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); /* this updates the visual's red/green/blue/alphaBits fields */ _mesa_update_framebuffer_visual(osmesa->gl_buffer); /* update the framebuffer size */ _mesa_resize_framebuffer(&osmesa->mesa, osmesa->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; 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: if (osmesa->gl_buffer) *value = osmesa->gl_buffer->Width; else *value = 0; return; case OSMESA_HEIGHT: if (osmesa->gl_buffer) *value = osmesa->gl_buffer->Height; else *value = 0; return; case OSMESA_FORMAT: *value = osmesa->format; return; case OSMESA_TYPE: /* current color buffer's data type */ if (osmesa->rb) { *value = osmesa->rb->DataType; } else { *value = 0; } 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) { *width = 0; *height = 0; *bytesPerValue = 0; *buffer = 0; return GL_FALSE; } else { *width = rb->Width; *height = rb->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 osmesa, GLint *width, GLint *height, GLint *format, void **buffer ){ if (osmesa->rb && osmesa->rb->Data) { *width = osmesa->rb->Width; *height = osmesa->rb->Height; *format = osmesa->format; *buffer = osmesa->rb->Data; return GL_TRUE; } else { *width = 0; *height = 0; *format = 0; *buffer = 0; return GL_FALSE; }}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 }, { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp }, { 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 + -