📄 vbo_save_api.c
字号:
static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ){ GET_CURRENT_CONTEXT(ctx); (void) x1; (void) y1; (void) x2; (void) y2; _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );}static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ){ GET_CURRENT_CONTEXT(ctx); (void) mode; (void) i1; (void) i2; _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );}static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ){ GET_CURRENT_CONTEXT(ctx); (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );}static void GLAPIENTRY _save_Begin( GLenum mode ){ GET_CURRENT_CONTEXT( ctx ); (void) mode; _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );}/* Unlike the functions above, these are to be hooked into the vtxfmt * maintained in ctx->ListState, active when the list is known or * suspected to be outside any begin/end primitive. */static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ){ GET_CURRENT_CONTEXT(ctx); vbo_save_NotifyBegin( ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK ); CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); CALL_End(GET_DISPATCH(), ());}static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count){ GET_CURRENT_CONTEXT(ctx); GLint i; if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) return; _ae_map_vbos( ctx ); vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK ); for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (start + i)); CALL_End(GET_DISPATCH(), ()); _ae_unmap_vbos( ctx );}/* Could do better by copying the arrays and element list intact and * then emitting an indexed prim at runtime. */static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices){ GET_CURRENT_CONTEXT(ctx); GLint i; if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; _ae_map_vbos( ctx ); if (ctx->Array.ElementArrayBufferObj->Name) indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices); vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK ); switch (type) { case GL_UNSIGNED_BYTE: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); break; case GL_UNSIGNED_SHORT: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); break; case GL_UNSIGNED_INT: for (i = 0 ; i < count ; i++) CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); break; } CALL_End(GET_DISPATCH(), ()); _ae_unmap_vbos( ctx );}static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices){ GET_CURRENT_CONTEXT(ctx); if (_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) _save_OBE_DrawElements( mode, count, type, indices );}static void _save_vtxfmt_init( GLcontext *ctx ){ struct vbo_save_context *save = &vbo_context(ctx)->save; GLvertexformat *vfmt = &save->vtxfmt; vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ vfmt->Begin = _save_Begin; vfmt->Color3f = _save_Color3f; vfmt->Color3fv = _save_Color3fv; vfmt->Color4f = _save_Color4f; vfmt->Color4fv = _save_Color4fv; vfmt->EdgeFlag = _save_EdgeFlag; vfmt->End = _save_End; vfmt->FogCoordfEXT = _save_FogCoordfEXT; vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; vfmt->Indexf = _save_Indexf; vfmt->Indexfv = _save_Indexfv; vfmt->Materialfv = _save_Materialfv; vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; vfmt->Normal3f = _save_Normal3f; vfmt->Normal3fv = _save_Normal3fv; vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; vfmt->TexCoord1f = _save_TexCoord1f; vfmt->TexCoord1fv = _save_TexCoord1fv; vfmt->TexCoord2f = _save_TexCoord2f; vfmt->TexCoord2fv = _save_TexCoord2fv; vfmt->TexCoord3f = _save_TexCoord3f; vfmt->TexCoord3fv = _save_TexCoord3fv; vfmt->TexCoord4f = _save_TexCoord4f; vfmt->TexCoord4fv = _save_TexCoord4fv; vfmt->Vertex2f = _save_Vertex2f; vfmt->Vertex2fv = _save_Vertex2fv; vfmt->Vertex3f = _save_Vertex3f; vfmt->Vertex3fv = _save_Vertex3fv; vfmt->Vertex4f = _save_Vertex4f; vfmt->Vertex4fv = _save_Vertex4fv; vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; /* This will all require us to fallback to saving the list as opcodes: */ vfmt->CallList = _save_CallList; /* inside begin/end */ vfmt->CallLists = _save_CallLists; /* inside begin/end */ vfmt->EvalCoord1f = _save_EvalCoord1f; vfmt->EvalCoord1fv = _save_EvalCoord1fv; vfmt->EvalCoord2f = _save_EvalCoord2f; vfmt->EvalCoord2fv = _save_EvalCoord2fv; vfmt->EvalPoint1 = _save_EvalPoint1; vfmt->EvalPoint2 = _save_EvalPoint2; /* These are all errors as we at least know we are in some sort of * begin/end pair: */ vfmt->EvalMesh1 = _save_EvalMesh1; vfmt->EvalMesh2 = _save_EvalMesh2; vfmt->Begin = _save_Begin; vfmt->Rectf = _save_Rectf; vfmt->DrawArrays = _save_DrawArrays; vfmt->DrawElements = _save_DrawElements; vfmt->DrawRangeElements = _save_DrawRangeElements;}void vbo_save_SaveFlushVertices( GLcontext *ctx ){ struct vbo_save_context *save = &vbo_context(ctx)->save; /* Noop when we are actually active: */ if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) return; if (save->vert_count || save->prim_count) _save_compile_vertex_list( ctx ); _save_copy_to_current( ctx ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); ctx->Driver.SaveNeedFlush = 0;}void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ){ struct vbo_save_context *save = &vbo_context(ctx)->save; (void) list; (void) mode; if (!save->prim_store) save->prim_store = alloc_prim_store( ctx ); if (!save->vertex_store) save->vertex_store = alloc_vertex_store( ctx ); save->vbptr = map_vertex_store( ctx, save->vertex_store ); _save_reset_vertex( ctx ); _save_reset_counters( ctx ); ctx->Driver.SaveNeedFlush = 0;}void vbo_save_EndList( GLcontext *ctx ){ struct vbo_save_context *save = &vbo_context(ctx)->save; /* EndList called inside a (saved) Begin/End pair? */ if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) { if (save->prim_count > 0) { GLint i = save->prim_count - 1; ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; save->prim[i].end = 0; save->prim[i].count = (save->vert_count - save->prim[i].start); } /* Make sure this vertex list gets replayed by the "loopback" * mechanism: */ save->dangling_attr_ref = 1; vbo_save_SaveFlushVertices( ctx ); /* Swap out this vertex format while outside begin/end. Any color, * etc. received between here and the next begin will be compiled * as opcodes. */ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); } unmap_vertex_store( ctx, save->vertex_store ); assert(save->vertex_size == 0);} void vbo_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ){ struct vbo_save_context *save = &vbo_context(ctx)->save; save->replay_flags |= dlist->flags;}void vbo_save_EndCallList( GLcontext *ctx ){ struct vbo_save_context *save = &vbo_context(ctx)->save; if (ctx->ListState.CallDepth == 1) { /* This is correct: want to keep only the VBO_SAVE_FALLBACK * flag, if it is set: */ save->replay_flags &= VBO_SAVE_FALLBACK; }}static void vbo_destroy_vertex_list( GLcontext *ctx, void *data ){ struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data; (void) ctx; if ( --node->vertex_store->refcount == 0 ) free_vertex_store( ctx, node->vertex_store ); if ( --node->prim_store->refcount == 0 ) FREE( node->prim_store );}static void vbo_print_vertex_list( GLcontext *ctx, void *data ){ struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data; GLuint i; (void) ctx; _mesa_debug(NULL, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", node->count, node->prim_count, node->vertex_size); for (i = 0 ; i < node->prim_count ; i++) { struct _mesa_prim *prim = &node->prim[i]; _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", i, _mesa_lookup_enum_by_nr(prim->mode), prim->weak ? " (weak)" : "", prim->start, prim->start + prim->count, (prim->begin) ? "BEGIN" : "(wrap)", (prim->end) ? "END" : "(wrap)"); }}static void _save_current_init( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; GLint i; for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) { const GLuint j = i - VBO_ATTRIB_POS; ASSERT(j < VERT_ATTRIB_MAX); save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j]; save->current[i] = ctx->ListState.CurrentAttrib[j]; } for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) { const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL; ASSERT(j < MAT_ATTRIB_MAX); save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; save->current[i] = ctx->ListState.CurrentMaterial[j]; }}/** * Initialize the display list compiler */void vbo_save_api_init( struct vbo_save_context *save ){ GLcontext *ctx = save->ctx; GLuint i; save->opcode_vertex_list = _mesa_alloc_opcode( ctx, sizeof(struct vbo_save_vertex_list), vbo_save_playback_vertex_list, vbo_destroy_vertex_list, vbo_print_vertex_list ); ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin; _save_vtxfmt_init( ctx ); _save_current_init( ctx ); /* These will actually get set again when binding/drawing */ for (i = 0; i < VBO_ATTRIB_MAX; i++) save->inputs[i] = &save->arrays[i]; /* Hook our array functions into the outside-begin-end vtxfmt in * ctx->ListState. */ ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -