mState.vertexAttribute[attribNum].mArrayEnabled = enabled;\r
}\r
\r
+void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)\r
+{\r
+ mState.vertexAttribute[attribNum].mDivisor = divisor;\r
+}\r
+\r
const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)\r
{\r
return mState.vertexAttribute[attribNum];\r
{\r
ASSERT(index < MAX_VERTEX_ATTRIBS);\r
\r
- mState.vertexAttribute[index].mCurrentValue[0] = values[0];\r
- mState.vertexAttribute[index].mCurrentValue[1] = values[1];\r
- mState.vertexAttribute[index].mCurrentValue[2] = values[2];\r
- mState.vertexAttribute[index].mCurrentValue[3] = values[3];\r
+ mState.vertexAttribute[index].setCurrentValue(values);\r
\r
mVertexDataManager->dirtyCurrentValue(index);\r
}\r
\r
+void Context::setVertexAttrib(GLuint index, const GLint *values)\r
+{\r
+ ASSERT(index < MAX_VERTEX_ATTRIBS);\r
+\r
+ mState.vertexAttribute[index].setCurrentValue(values);\r
+\r
+ mVertexDataManager->dirtyCurrentValue(index);\r
+}\r
+\r
+void Context::setVertexAttrib(GLuint index, const GLuint *values)\r
+{\r
+ ASSERT(index < MAX_VERTEX_ATTRIBS);\r
+\r
+ mState.vertexAttribute[index].setCurrentValue(values);\r
+\r
+ mVertexDataManager->dirtyCurrentValue(index);\r
+}\r
+\r
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, \r
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,\r
GLbitfield mask)\r
class VertexAttribute\r
{\r
public:\r
- VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)\r
+ VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(NULL), mArrayEnabled(false)\r
{\r
- mCurrentValue[0] = 0.0f;\r
- mCurrentValue[1] = 0.0f;\r
- mCurrentValue[2] = 0.0f;\r
- mCurrentValue[3] = 1.0f;\r
+ mCurrentValue[0].f = 0.0f;\r
+ mCurrentValue[1].f = 0.0f;\r
+ mCurrentValue[2].f = 0.0f;\r
+ mCurrentValue[3].f = 1.0f;\r
+ mCurrentValueType = ValueUnion::FloatType;\r
}\r
\r
int typeSize() const\r
return mStride ? mStride : typeSize();\r
}\r
\r
+ inline float getCurrentValue(int i) const\r
+ {\r
+ switch(mCurrentValueType)\r
+ {\r
+ case ValueUnion::FloatType: return mCurrentValue[i].f;\r
+ case ValueUnion::IntType: return static_cast<float>(mCurrentValue[i].i);\r
+ case ValueUnion::UIntType: return static_cast<float>(mCurrentValue[i].ui);\r
+ default: UNREACHABLE(); return mCurrentValue[i].f;\r
+ }\r
+ }\r
+\r
+ inline GLint getCurrentValueI(int i) const\r
+ {\r
+ switch(mCurrentValueType)\r
+ {\r
+ case ValueUnion::FloatType: return static_cast<GLint>(mCurrentValue[i].f);\r
+ case ValueUnion::IntType: return mCurrentValue[i].i;\r
+ case ValueUnion::UIntType: return static_cast<GLint>(mCurrentValue[i].ui);\r
+ default: UNREACHABLE(); return mCurrentValue[i].i;\r
+ }\r
+ }\r
+\r
+ inline GLuint getCurrentValueUI(int i) const\r
+ {\r
+ switch(mCurrentValueType)\r
+ {\r
+ case ValueUnion::FloatType: return static_cast<GLuint>(mCurrentValue[i].f);\r
+ case ValueUnion::IntType: return static_cast<GLuint>(mCurrentValue[i].i);\r
+ case ValueUnion::UIntType: return mCurrentValue[i].ui;\r
+ default: UNREACHABLE(); return mCurrentValue[i].ui;\r
+ }\r
+ }\r
+\r
+ inline void setCurrentValue(const GLfloat *values)\r
+ {\r
+ mCurrentValue[0].f = values[0];\r
+ mCurrentValue[1].f = values[1];\r
+ mCurrentValue[2].f = values[2];\r
+ mCurrentValue[3].f = values[3];\r
+ mCurrentValueType = ValueUnion::FloatType;\r
+ }\r
+\r
+ inline void setCurrentValue(const GLint *values)\r
+ {\r
+ mCurrentValue[0].i = values[0];\r
+ mCurrentValue[1].i = values[1];\r
+ mCurrentValue[2].i = values[2];\r
+ mCurrentValue[3].i = values[3];\r
+ mCurrentValueType = ValueUnion::IntType;\r
+ }\r
+\r
+ inline void setCurrentValue(const GLuint *values)\r
+ {\r
+ mCurrentValue[0].ui = values[0];\r
+ mCurrentValue[1].ui = values[1];\r
+ mCurrentValue[2].ui = values[2];\r
+ mCurrentValue[3].ui = values[3];\r
+ mCurrentValueType = ValueUnion::UIntType;\r
+ }\r
+\r
// From glVertexAttribPointer\r
GLenum mType;\r
GLint mSize;\r
bool mNormalized;\r
GLsizei mStride; // 0 means natural stride\r
+ GLuint mDivisor; // From glVertexAttribDivisor\r
\r
union\r
{\r
gl::BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.\r
\r
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray\r
- float mCurrentValue[4]; // From glVertexAttrib\r
+private:\r
+ union ValueUnion\r
+ {\r
+ enum Type { FloatType, IntType, UIntType };\r
+\r
+ float f;\r
+ GLint i;\r
+ GLuint ui;\r
+ };\r
+ ValueUnion mCurrentValue[4]; // From glVertexAttrib\r
+ ValueUnion::Type mCurrentValueType;\r
};\r
\r
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];\r
GLuint getArrayBufferName() const;\r
\r
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);\r
+ void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor);\r
const VertexAttribute &getVertexAttribState(unsigned int attribNum);\r
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,\r
bool normalized, GLsizei stride, const void *pointer);\r
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);\r
\r
void setVertexAttrib(GLuint index, const GLfloat *values);\r
+ void setVertexAttrib(GLuint index, const GLint *values);\r
+ void setVertexAttrib(GLuint index, const GLuint *values);\r
\r
Buffer *getBuffer(GLuint handle);\r
Fence *getFence(GLuint handle);\r
if(mDirtyCurrentValue[i])\r
{\r
delete mCurrentValueBuffer[i];\r
- mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);\r
+ mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].getCurrentValue(0), attribs[i].getCurrentValue(1), attribs[i].getCurrentValue(2), attribs[i].getCurrentValue(3));\r
mDirtyCurrentValue[i] = false;\r
}\r
\r
case GL_CURRENT_VERTEX_ATTRIB:\r
for(int i = 0; i < 4; ++i)\r
{\r
- params[i] = attribState.mCurrentValue[i];\r
+ params[i] = attribState.getCurrentValue(i);\r
}\r
break;\r
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:\r
case GL_CURRENT_VERTEX_ATTRIB:\r
for(int i = 0; i < 4; ++i)\r
{\r
- float currentValue = attribState.mCurrentValue[i];\r
+ float currentValue = attribState.getCurrentValue(i);\r
params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));\r
}\r
break;\r
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
*params = attribState.mBoundBuffer.name();\r
break;\r
+ case GL_CURRENT_VERTEX_ATTRIB:\r
+ for(int i = 0; i < 4; ++i)\r
+ {\r
+ params[i] = attribState.getCurrentValueI(i);\r
+ }\r
+ break;\r
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:\r
switch(attribState.mType)\r
{\r
break;\r
}\r
break;\r
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:\r
+ *params = attribState.mDivisor;\r
+ break;\r
default: return error(GL_INVALID_ENUM);\r
}\r
}\r
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
*params = attribState.mBoundBuffer.name();\r
break;\r
+ case GL_CURRENT_VERTEX_ATTRIB:\r
+ for(int i = 0; i < 4; ++i)\r
+ {\r
+ params[i] = attribState.getCurrentValueUI(i);\r
+ }\r
+ break;\r
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:\r
switch(attribState.mType)\r
{\r
break;\r
}\r
break;\r
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:\r
+ *params = attribState.mDivisor;\r
+ break;\r
default: return error(GL_INVALID_ENUM);\r
}\r
}\r
{\r
TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",\r
index, x, y, z, w);\r
- UNIMPLEMENTED();\r
+\r
+ if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ es2::Context *context = es2::getContext();\r
+\r
+ if(context)\r
+ {\r
+ GLint vals[4] = { x, y, z, w };\r
+ context->setVertexAttrib(index, vals);\r
+ }\r
}\r
\r
void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)\r
{\r
TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",\r
index, x, y, z, w);\r
- UNIMPLEMENTED();\r
+\r
+ if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ es2::Context *context = es2::getContext();\r
+\r
+ if(context)\r
+ {\r
+ GLuint vals[4] = { x, y, z, w };\r
+ context->setVertexAttrib(index, vals);\r
+ }\r
}\r
\r
void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)\r
{\r
TRACE("(GLuint index = %d, GLint *v = 0x%0.8p)", index, v);\r
- UNIMPLEMENTED();\r
+\r
+ if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ es2::Context *context = es2::getContext();\r
+\r
+ if(context)\r
+ {\r
+ context->setVertexAttrib(index, v);\r
+ }\r
}\r
\r
void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)\r
{\r
TRACE("(GLuint index = %d, GLint *v = 0x%0.8p)", index, v);\r
- UNIMPLEMENTED();\r
+\r
+ if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ es2::Context *context = es2::getContext();\r
+\r
+ if(context)\r
+ {\r
+ context->setVertexAttrib(index, v);\r
+ }\r
}\r
\r
void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)\r
void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)\r
{\r
TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);\r
- UNIMPLEMENTED();\r
+\r
+ es2::Context *context = es2::getContext();\r
+\r
+ if(context)\r
+ {\r
+ if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ context->setVertexAttribDivisor(index, divisor);\r
+ }\r
}\r
\r
void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)\r