📄 varray.c
字号:
/* * Mesa 3-D graphics library * Version: 6.1 * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "glheader.h"#include "imports.h"#include "bufferobj.h"#include "context.h"#include "enable.h"#include "enums.h"#include "dlist.h"#include "texstate.h"#include "mtypes.h"#include "varray.h"#include "dispatch.h"#ifndef GL_BOOLEAN#define GL_BOOLEAN 0x9999#endif/** * Update the fields of a vertex array structure. * We need to do a few special things for arrays that live in * vertex buffer objects. */static voidupdate_array(GLcontext *ctx, struct gl_client_array *array, GLuint dirtyFlag, GLsizei elementSize, GLint size, GLenum type, GLsizei stride, GLboolean normalized, const GLvoid *ptr){ array->Size = size; array->Type = type; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Ptr = (const GLubyte *) ptr;#if FEATURE_ARB_vertex_buffer_object array->BufferObj->RefCount--; if (array->BufferObj->RefCount <= 0) { ASSERT(array->BufferObj->Name); _mesa_remove_buffer_object( ctx, array->BufferObj ); (*ctx->Driver.DeleteBuffer)( ctx, array->BufferObj ); } array->BufferObj = ctx->Array.ArrayBufferObj; array->BufferObj->RefCount++; /* Compute the index of the last array element that's inside the buffer. * Later in glDrawArrays we'll check if start + count > _MaxElement to * be sure we won't go out of bounds. */ if (ctx->Array.ArrayBufferObj->Name) array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size - (GLsizeiptrARB) array->Ptr) / array->StrideB; else#endif array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= dirtyFlag;}void GLAPIENTRY_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (size < 2 || size > 4) { _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" ); return; } if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size, _mesa_lookup_enum_by_nr( type ), stride); /* always need to check that <type> is legal */ switch (type) { case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_INT: elementSize = size * sizeof(GLint); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" ); return; } update_array(ctx, &ctx->Array.Vertex, _NEW_ARRAY_VERTEX, elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.VertexPointer) ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );}void GLAPIENTRY_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n", _mesa_lookup_enum_by_nr( type ), stride); switch (type) { case GL_BYTE: elementSize = 3 * sizeof(GLbyte); break; case GL_SHORT: elementSize = 3 * sizeof(GLshort); break; case GL_INT: elementSize = 3 * sizeof(GLint); break; case GL_FLOAT: elementSize = 3 * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = 3 * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); return; } update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL, elementSize, 3, type, stride, GL_FALSE, ptr); if (ctx->Driver.NormalPointer) ctx->Driver.NormalPointer( ctx, type, stride, ptr );}void GLAPIENTRY_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (size < 3 || size > 4) { _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" ); return; } if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size, _mesa_lookup_enum_by_nr( type ), stride); switch (type) { case GL_BYTE: elementSize = size * sizeof(GLbyte); break; case GL_UNSIGNED_BYTE: elementSize = size * sizeof(GLubyte); break; case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_UNSIGNED_SHORT: elementSize = size * sizeof(GLushort); break; case GL_INT: elementSize = size * sizeof(GLint); break; case GL_UNSIGNED_INT: elementSize = size * sizeof(GLuint); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" ); return; } update_array(ctx, &ctx->Array.Color, _NEW_ARRAY_COLOR0, elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.ColorPointer) ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );}void GLAPIENTRY_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr){ GLint elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" ); return; } switch (type) { case GL_FLOAT: elementSize = sizeof(GLfloat); break; case GL_DOUBLE: elementSize = sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" ); return; } update_array(ctx, &ctx->Array.FogCoord, _NEW_ARRAY_FOGCOORD, elementSize, 1, type, stride, GL_FALSE, ptr); if (ctx->Driver.FogCoordPointer) ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );}void GLAPIENTRY_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" ); return; } switch (type) { case GL_UNSIGNED_BYTE: elementSize = sizeof(GLubyte); break; case GL_SHORT: elementSize = sizeof(GLshort); break; case GL_INT: elementSize = sizeof(GLint); break; case GL_FLOAT: elementSize = sizeof(GLfloat); break; case GL_DOUBLE: elementSize = sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" ); return; } update_array(ctx, &ctx->Array.Index, _NEW_ARRAY_INDEX, elementSize, 1, type, stride, GL_FALSE, ptr); if (ctx->Driver.IndexPointer) ctx->Driver.IndexPointer( ctx, type, stride, ptr );}void GLAPIENTRY_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (size != 3 && size != 4) { _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" ); return; } if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n", size, _mesa_lookup_enum_by_nr( type ), stride); switch (type) { case GL_BYTE: elementSize = size * sizeof(GLbyte); break; case GL_UNSIGNED_BYTE: elementSize = size * sizeof(GLubyte); break; case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_UNSIGNED_SHORT: elementSize = size * sizeof(GLushort); break; case GL_INT: elementSize = size * sizeof(GLint); break; case GL_UNSIGNED_INT: elementSize = size * sizeof(GLuint); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" ); return; } update_array(ctx, &ctx->Array.SecondaryColor, _NEW_ARRAY_COLOR1, elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.SecondaryColorPointer) ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );}void GLAPIENTRY_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr){ GLint elementSize; GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (size < 1 || size > 4) { _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); return; } if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n", unit, size, _mesa_lookup_enum_by_nr( type ), stride); /* always need to check that <type> is legal */ switch (type) { case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_INT: elementSize = size * sizeof(GLint); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); return; } update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit), elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.TexCoordPointer) ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );}void GLAPIENTRY_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" ); return; } update_array(ctx, &ctx->Array.EdgeFlag, _NEW_ARRAY_EDGEFLAG, sizeof(GLboolean), 1, GL_BOOLEAN, stride, GL_FALSE, ptr); if (ctx->Driver.EdgeFlagPointer) ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );}#if FEATURE_NV_vertex_programvoid GLAPIENTRY_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (index >= VERT_ATTRIB_MAX) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); return; } if (size < 1 || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)"); return; } if (stride < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)"); return; } if (type == GL_UNSIGNED_BYTE && size != 4) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); return; } /* check for valid 'type' and compute StrideB right away */ switch (type) { case GL_UNSIGNED_BYTE: elementSize = size * sizeof(GLubyte); break; case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" ); return; } update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index), elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.VertexAttribPointer) ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );}#endif#if FEATURE_ARB_vertex_programvoid GLAPIENTRY_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr){ GLsizei elementSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -