Implemented glGetActiveAttrib

TRAC #11929 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@180 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent d99bd45f
...@@ -141,7 +141,7 @@ GLuint Program::getAttributeLocation(const char *name) ...@@ -141,7 +141,7 @@ GLuint Program::getAttributeLocation(const char *name)
{ {
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{ {
if (mLinkedAttribute[index] == std::string(name)) if (mLinkedAttribute[index].name == std::string(name))
{ {
return index; return index;
} }
...@@ -1039,55 +1039,55 @@ bool Program::linkAttributes() ...@@ -1039,55 +1039,55 @@ bool Program::linkAttributes()
// Link attributes that have a binding location // Link attributes that have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
const char *name = mVertexShader->getAttributeName(attributeIndex); const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
int location = getAttributeBinding(name); int location = getAttributeBinding(attribute.name);
if (location != -1) // Set by glBindAttribLocation if (location != -1) // Set by glBindAttribLocation
{ {
if (!mLinkedAttribute[location].empty()) if (!mLinkedAttribute[location].name.empty())
{ {
// Multiple active attributes bound to the same location; not an error // Multiple active attributes bound to the same location; not an error
} }
mLinkedAttribute[location] = name; mLinkedAttribute[location] = attribute;
} }
} }
// Link attributes that don't have a binding location // Link attributes that don't have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS + 1; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS + 1; attributeIndex++)
{ {
const char *name = mVertexShader->getAttributeName(attributeIndex); const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
int location = getAttributeBinding(name); int location = getAttributeBinding(attribute.name);
if (location == -1) // Not set by glBindAttribLocation if (location == -1) // Not set by glBindAttribLocation
{ {
int availableIndex = 0; int availableIndex = 0;
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].empty()) while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].name.empty())
{ {
availableIndex++; availableIndex++;
} }
if (availableIndex == MAX_VERTEX_ATTRIBS) if (availableIndex == MAX_VERTEX_ATTRIBS)
{ {
appendToInfoLog("Too many active attributes (%s)", name); appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str());
return false; // Fail to link return false; // Fail to link
} }
mLinkedAttribute[availableIndex] = name; mLinkedAttribute[availableIndex] = attribute;
} }
} }
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{ {
mSemanticIndex[attributeIndex] = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].c_str()); mSemanticIndex[attributeIndex] = mVertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name.c_str());
} }
return true; return true;
} }
int Program::getAttributeBinding(const char *name) int Program::getAttributeBinding(const std::string &name)
{ {
for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++) for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
{ {
...@@ -1749,6 +1749,41 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v) ...@@ -1749,6 +1749,41 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
return true; return true;
} }
GLenum Program::parseAttributeType(const std::string &type)
{
if (type == "float")
{
return GL_FLOAT;
}
else if (type == "float2")
{
return GL_FLOAT_VEC2;
}
else if (type == "float3")
{
return GL_FLOAT_VEC3;
}
else if (type == "float4")
{
return GL_FLOAT_VEC4;
}
else if (type == "float2x2")
{
return GL_FLOAT_MAT2;
}
else if (type == "float3x3")
{
return GL_FLOAT_MAT3;
}
else if (type == "float4x4")
{
return GL_FLOAT_MAT4;
}
else UNREACHABLE();
return GL_NONE;
}
void Program::appendToInfoLog(const char *format, ...) void Program::appendToInfoLog(const char *format, ...)
{ {
if (!format) if (!format)
...@@ -1826,7 +1861,8 @@ void Program::unlink(bool destroy) ...@@ -1826,7 +1861,8 @@ void Program::unlink(bool destroy)
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{ {
mLinkedAttribute[index].clear(); mLinkedAttribute[index].name.clear();
mLinkedAttribute[index].type.clear();
mSemanticIndex[index] = -1; mSemanticIndex[index] = -1;
} }
...@@ -1924,6 +1960,68 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade ...@@ -1924,6 +1960,68 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade
} }
} }
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
int attribute = 0;
for (unsigned int i = 0; i < index; i++)
{
do
{
attribute++;
ASSERT(attribute < MAX_VERTEX_ATTRIBS); // index must be smaller than getActiveAttributeCount()
}
while (mLinkedAttribute[attribute].name.empty());
}
if (bufsize > 0)
{
const char *string = mLinkedAttribute[attribute].name.c_str();
strncpy(name, string, bufsize);
name[bufsize - 1] = '\0';
if (length)
{
*length = strlen(name);
}
}
*size = 1;
*type = parseAttributeType(mLinkedAttribute[attribute].type);
}
GLint Program::getActiveAttributeCount()
{
int count = 0;
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
if (!mLinkedAttribute[attributeIndex].name.empty())
{
count++;
}
}
return count;
}
GLint Program::getActiveAttributeMaxLength()
{
int maxLength = 0;
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
if (!mLinkedAttribute[attributeIndex].name.empty())
{
maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
}
}
return maxLength;
}
void Program::flagForDeletion() void Program::flagForDeletion()
{ {
mDeleteStatus = true; mDeleteStatus = true;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include "libGLESv2/Shader.h"
#include "libGLESv2/Context.h" #include "libGLESv2/Context.h"
namespace gl namespace gl
...@@ -80,6 +81,10 @@ class Program ...@@ -80,6 +81,10 @@ class Program
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLint getActiveAttributeCount();
GLint getActiveAttributeMaxLength();
void flagForDeletion(); void flagForDeletion();
bool isFlaggedForDeletion() const; bool isFlaggedForDeletion() const;
...@@ -107,7 +112,7 @@ class Program ...@@ -107,7 +112,7 @@ class Program
bool linkVaryings(); bool linkVaryings();
bool linkAttributes(); bool linkAttributes();
int getAttributeBinding(const char *name); int getAttributeBinding(const std::string &name);
bool linkUniforms(ID3DXConstantTable *constantTable); bool linkUniforms(ID3DXConstantTable *constantTable);
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
...@@ -130,6 +135,7 @@ class Program ...@@ -130,6 +135,7 @@ class Program
bool applyUniform3iv(GLint location, GLsizei count, const GLint *v); bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
GLenum parseAttributeType(const std::string &type);
void appendToInfoLog(const char *info, ...); void appendToInfoLog(const char *info, ...);
FragmentShader *mFragmentShader; FragmentShader *mFragmentShader;
...@@ -144,7 +150,7 @@ class Program ...@@ -144,7 +150,7 @@ class Program
ID3DXConstantTable *mConstantTableVS; ID3DXConstantTable *mConstantTableVS;
std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS]; std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
std::string mLinkedAttribute[MAX_VERTEX_ATTRIBS]; Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler struct Sampler
......
...@@ -278,14 +278,11 @@ void VertexShader::compile() ...@@ -278,14 +278,11 @@ void VertexShader::compile()
parseAttributes(); parseAttributes();
} }
const char *VertexShader::getAttributeName(unsigned int semanticIndex) const Attribute &VertexShader::getAttribute(unsigned int semanticIndex)
{ {
if (semanticIndex < MAX_VERTEX_ATTRIBS + 1) ASSERT(semanticIndex < MAX_VERTEX_ATTRIBS + 1);
{
return mAttributeName[semanticIndex].c_str();
}
return 0; return mAttribute[semanticIndex];
} }
int VertexShader::getSemanticIndex(const std::string &attributeName) int VertexShader::getSemanticIndex(const std::string &attributeName)
...@@ -294,7 +291,7 @@ int VertexShader::getSemanticIndex(const std::string &attributeName) ...@@ -294,7 +291,7 @@ int VertexShader::getSemanticIndex(const std::string &attributeName)
{ {
for (int semanticIndex = 0; semanticIndex < MAX_VERTEX_ATTRIBS; semanticIndex++) for (int semanticIndex = 0; semanticIndex < MAX_VERTEX_ATTRIBS; semanticIndex++)
{ {
if (mAttributeName[semanticIndex] == attributeName) if (mAttribute[semanticIndex].name == attributeName)
{ {
return semanticIndex; return semanticIndex;
} }
...@@ -312,16 +309,18 @@ void VertexShader::parseAttributes() ...@@ -312,16 +309,18 @@ void VertexShader::parseAttributes()
for (int attributeIndex = 0; *input != '}'; input++) for (int attributeIndex = 0; *input != '}'; input++)
{ {
char attributeType[100];
char attributeName[100]; char attributeName[100];
int semanticIndex; int semanticIndex;
int matches = sscanf(input, "_%s : TEXCOORD%d;", attributeName, &semanticIndex); int matches = sscanf(input, "%s _%s : TEXCOORD%d;", attributeType, attributeName, &semanticIndex);
if (matches == 2) if (matches == 3)
{ {
if (semanticIndex < MAX_VERTEX_ATTRIBS + 1) if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
{ {
mAttributeName[semanticIndex] = attributeName; mAttribute[semanticIndex].type = attributeType;
mAttribute[semanticIndex].name = attributeName;
} }
else else
{ {
......
...@@ -67,6 +67,12 @@ class Shader ...@@ -67,6 +67,12 @@ class Shader
static void *mVertexCompiler; static void *mVertexCompiler;
}; };
struct Attribute
{
std::string type;
std::string name;
};
class VertexShader : public Shader class VertexShader : public Shader
{ {
public: public:
...@@ -76,7 +82,7 @@ class VertexShader : public Shader ...@@ -76,7 +82,7 @@ class VertexShader : public Shader
GLenum getType(); GLenum getType();
void compile(); void compile();
const char *getAttributeName(unsigned int attributeIndex); const Attribute &getAttribute(unsigned int attributeIndex);
int getSemanticIndex(const std::string &attributeName); int getSemanticIndex(const std::string &attributeName);
private: private:
...@@ -84,7 +90,7 @@ class VertexShader : public Shader ...@@ -84,7 +90,7 @@ class VertexShader : public Shader
void parseAttributes(); void parseAttributes();
std::string mAttributeName[MAX_VERTEX_ATTRIBS + 1]; // One extra to report link error Attribute mAttribute[MAX_VERTEX_ATTRIBS + 1]; // One extra to report link error
}; };
class FragmentShader : public Shader class FragmentShader : public Shader
......
...@@ -1868,10 +1868,10 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) ...@@ -1868,10 +1868,10 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures)
} }
} }
void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{ {
TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
"GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)", "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
program, index, bufsize, length, size, type, name); program, index, bufsize, length, size, type, name);
try try
...@@ -1881,7 +1881,31 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, ...@@ -1881,7 +1881,31 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
UNIMPLEMENTED(); // FIXME gl::Context *context = gl::getContext();
if (context)
{
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
if (context->getShader(program))
{
return error(GL_INVALID_OPERATION);
}
else
{
return error(GL_INVALID_VALUE);
}
}
if (index >= programObject->getActiveAttributeCount())
{
return error(GL_INVALID_VALUE);
}
programObject->getActiveAttribute(index, bufsize, length, size, type, name);
}
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
{ {
...@@ -2300,12 +2324,10 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) ...@@ -2300,12 +2324,10 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
*params = programObject->getAttachedShadersCount(); *params = programObject->getAttachedShadersCount();
return; return;
case GL_ACTIVE_ATTRIBUTES: case GL_ACTIVE_ATTRIBUTES:
UNIMPLEMENTED(); // FIXME *params = programObject->getActiveAttributeCount();
*params = 0;
return; return;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
UNIMPLEMENTED(); // FIXME *params = programObject->getActiveAttributeMaxLength();
*params = 0;
return; return;
case GL_ACTIVE_UNIFORMS: case GL_ACTIVE_UNIFORMS:
UNIMPLEMENTED(); // FIXME UNIMPLEMENTED(); // FIXME
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment