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
This commit is contained in:
daniel@transgaming.com 2010-04-22 13:35:27 +00:00
Родитель d99bd45f94
Коммит 85423183fb
5 изменённых файлов: 166 добавлений и 35 удалений

Просмотреть файл

@ -141,7 +141,7 @@ GLuint Program::getAttributeLocation(const char *name)
{
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
if (mLinkedAttribute[index] == std::string(name))
if (mLinkedAttribute[index].name == std::string(name))
{
return index;
}
@ -1039,55 +1039,55 @@ bool Program::linkAttributes()
// Link attributes that have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
int location = getAttributeBinding(attribute.name);
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
}
mLinkedAttribute[location] = name;
mLinkedAttribute[location] = attribute;
}
}
// Link attributes that don't have a binding location
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS + 1; attributeIndex++)
{
const char *name = mVertexShader->getAttributeName(attributeIndex);
int location = getAttributeBinding(name);
const Attribute &attribute = mVertexShader->getAttribute(attributeIndex);
int location = getAttributeBinding(attribute.name);
if (location == -1) // Not set by glBindAttribLocation
{
int availableIndex = 0;
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].empty())
while (availableIndex < MAX_VERTEX_ATTRIBS && !mLinkedAttribute[availableIndex].name.empty())
{
availableIndex++;
}
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
}
mLinkedAttribute[availableIndex] = name;
mLinkedAttribute[availableIndex] = attribute;
}
}
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;
}
int Program::getAttributeBinding(const char *name)
int Program::getAttributeBinding(const std::string &name)
{
for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
{
@ -1749,6 +1749,41 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
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, ...)
{
if (!format)
@ -1826,7 +1861,8 @@ void Program::unlink(bool destroy)
for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
mLinkedAttribute[index].clear();
mLinkedAttribute[index].name.clear();
mLinkedAttribute[index].type.clear();
mSemanticIndex[index] = -1;
}
@ -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()
{
mDeleteStatus = true;

Просмотреть файл

@ -15,6 +15,7 @@
#include <vector>
#include <set>
#include "libGLESv2/Shader.h"
#include "libGLESv2/Context.h"
namespace gl
@ -80,6 +81,10 @@ class Program
void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
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();
bool isFlaggedForDeletion() const;
@ -107,7 +112,7 @@ class Program
bool linkVaryings();
bool linkAttributes();
int getAttributeBinding(const char *name);
int getAttributeBinding(const std::string &name);
bool linkUniforms(ID3DXConstantTable *constantTable);
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
@ -130,6 +135,7 @@ class Program
bool applyUniform3iv(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, ...);
FragmentShader *mFragmentShader;
@ -144,7 +150,7 @@ class Program
ID3DXConstantTable *mConstantTableVS;
std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
std::string mLinkedAttribute[MAX_VERTEX_ATTRIBS];
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
struct Sampler

Просмотреть файл

@ -278,14 +278,11 @@ void VertexShader::compile()
parseAttributes();
}
const char *VertexShader::getAttributeName(unsigned int semanticIndex)
const Attribute &VertexShader::getAttribute(unsigned int semanticIndex)
{
if (semanticIndex < MAX_VERTEX_ATTRIBS + 1)
{
return mAttributeName[semanticIndex].c_str();
}
ASSERT(semanticIndex < MAX_VERTEX_ATTRIBS + 1);
return 0;
return mAttribute[semanticIndex];
}
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++)
{
if (mAttributeName[semanticIndex] == attributeName)
if (mAttribute[semanticIndex].name == attributeName)
{
return semanticIndex;
}
@ -312,16 +309,18 @@ void VertexShader::parseAttributes()
for (int attributeIndex = 0; *input != '}'; input++)
{
char attributeType[100];
char attributeName[100];
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)
{
mAttributeName[semanticIndex] = attributeName;
mAttribute[semanticIndex].type = attributeType;
mAttribute[semanticIndex].name = attributeName;
}
else
{

Просмотреть файл

@ -67,6 +67,12 @@ class Shader
static void *mVertexCompiler;
};
struct Attribute
{
std::string type;
std::string name;
};
class VertexShader : public Shader
{
public:
@ -76,7 +82,7 @@ class VertexShader : public Shader
GLenum getType();
void compile();
const char *getAttributeName(unsigned int attributeIndex);
const Attribute &getAttribute(unsigned int attributeIndex);
int getSemanticIndex(const std::string &attributeName);
private:
@ -84,7 +90,7 @@ class VertexShader : public Shader
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

Просмотреть файл

@ -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, "
"GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %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)",
program, index, bufsize, length, size, type, name);
try
@ -1881,7 +1881,31 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
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&)
{
@ -2300,12 +2324,10 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
*params = programObject->getAttachedShadersCount();
return;
case GL_ACTIVE_ATTRIBUTES:
UNIMPLEMENTED(); // FIXME
*params = 0;
*params = programObject->getActiveAttributeCount();
return;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
UNIMPLEMENTED(); // FIXME
*params = 0;
*params = programObject->getActiveAttributeMaxLength();
return;
case GL_ACTIVE_UNIFORMS:
UNIMPLEMENTED(); // FIXME