зеркало из https://github.com/AvaloniaUI/angle.git
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
This commit is contained in:
Родитель
d99bd45f94
Коммит
85423183fb
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче