1//
2// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// Helper structure describing a single vertex attribute
7//
8
9#ifndef LIBGLESV2_VERTEXATTRIBUTE_H_
10#define LIBGLESV2_VERTEXATTRIBUTE_H_
11
12#include "libGLESv2/Buffer.h"
13
14namespace gl
15{
16
17class VertexAttribute
18{
19  public:
20    VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mPureInteger(false),
21                        mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
22    {
23    }
24
25    int typeSize() const
26    {
27        switch (mType)
28        {
29          case GL_BYTE:                        return mSize * sizeof(GLbyte);
30          case GL_UNSIGNED_BYTE:               return mSize * sizeof(GLubyte);
31          case GL_SHORT:                       return mSize * sizeof(GLshort);
32          case GL_UNSIGNED_SHORT:              return mSize * sizeof(GLushort);
33          case GL_INT:                         return mSize * sizeof(GLint);
34          case GL_UNSIGNED_INT:                return mSize * sizeof(GLuint);
35          case GL_INT_2_10_10_10_REV:          return 4;
36          case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
37          case GL_FIXED:                       return mSize * sizeof(GLfixed);
38          case GL_HALF_FLOAT:                  return mSize * sizeof(GLhalf);
39          case GL_FLOAT:                       return mSize * sizeof(GLfloat);
40          default: UNREACHABLE();              return mSize * sizeof(GLfloat);
41        }
42    }
43
44    GLsizei stride() const
45    {
46        return (mArrayEnabled ? (mStride ? mStride : typeSize()) : 16);
47    }
48
49    void setState(gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
50                  bool pureInteger, GLsizei stride, const void *pointer)
51    {
52        mBoundBuffer.set(boundBuffer);
53        mSize = size;
54        mType = type;
55        mNormalized = normalized;
56        mPureInteger = pureInteger;
57        mStride = stride;
58        mPointer = pointer;
59    }
60
61    template <typename T>
62    T querySingleParameter(GLenum pname) const
63    {
64        switch (pname)
65        {
66          case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
67            return static_cast<T>(mArrayEnabled ? GL_TRUE : GL_FALSE);
68          case GL_VERTEX_ATTRIB_ARRAY_SIZE:
69            return static_cast<T>(mSize);
70          case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
71            return static_cast<T>(mStride);
72          case GL_VERTEX_ATTRIB_ARRAY_TYPE:
73            return static_cast<T>(mType);
74          case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
75            return static_cast<T>(mNormalized ? GL_TRUE : GL_FALSE);
76          case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
77            return static_cast<T>(mBoundBuffer.id());
78          case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
79            return static_cast<T>(mDivisor);
80          case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
81            return static_cast<T>(mPureInteger ? GL_TRUE : GL_FALSE);
82          default:
83            UNREACHABLE();
84            return static_cast<T>(0);
85        }
86    }
87
88    // From glVertexAttribPointer
89    GLenum mType;
90    GLint mSize;
91    bool mNormalized;
92    bool mPureInteger;
93    GLsizei mStride;   // 0 means natural stride
94
95    union
96    {
97        const void *mPointer;
98        intptr_t mOffset;
99    };
100
101    BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
102    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
103    unsigned int mDivisor;
104};
105
106struct VertexAttribCurrentValueData
107{
108    union
109    {
110        GLfloat FloatValues[4];
111        GLint IntValues[4];
112        GLuint UnsignedIntValues[4];
113    };
114    GLenum Type;
115
116    void setFloatValues(const GLfloat floatValues[4])
117    {
118        for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
119        {
120            FloatValues[valueIndex] = floatValues[valueIndex];
121        }
122        Type = GL_FLOAT;
123    }
124
125    void setIntValues(const GLint intValues[4])
126    {
127        for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
128        {
129            IntValues[valueIndex] = intValues[valueIndex];
130        }
131        Type = GL_INT;
132    }
133
134    void setUnsignedIntValues(const GLuint unsignedIntValues[4])
135    {
136        for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
137        {
138            UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex];
139        }
140        Type = GL_UNSIGNED_INT;
141    }
142
143    bool operator==(const VertexAttribCurrentValueData &other)
144    {
145        return (Type == other.Type && memcmp(FloatValues, other.FloatValues, sizeof(float) * 4) == 0);
146    }
147
148    bool operator!=(const VertexAttribCurrentValueData &other)
149    {
150        return !(*this == other);
151    }
152};
153
154}
155
156#endif // LIBGLESV2_VERTEXATTRIBUTE_H_
157