📄 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 void
update_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_program
void 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_program
void 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 + -