我曾经在OpenGL 2.x中使用CG着色器处理顶点数组,但我在OpenGL 3.x中更新了VBO和VAO,现在除了位置之外,语义似乎不起作用了。CG不会抛出任何编译错误,但如果我在片段着色器中将输出颜色设置为输入正常值,我只会得到纯黑。还有另一个链接到一个页面的答案,上面写着使用cgGLEnableClientState (它自己什么都不做)和cgGLSetParameterPointer (这看起来很疯狂,因为我已经把数据发送到OpenGL了,为什么还要通过CG发送另一个副本)。那么我错过了什么呢?
顶点着色器:
struct input
{
in uniform float4x4 worldViewProjMatrix;
in uniform float4x4 invTransWorldMatrix;
in uniform float4x4 worldMatrix;
in uniform float3 lightDir;
in uniform float3 eyePosition;
in varying float4 position : POSITION;
in varying float4 normal : NORMAL;
in varying float2 texCoord : TEXCOORD;
};
struct output
{
out varying float4 position : POSITION;
out varying float2 texCoord : TEXCOORD0;
out varying float3 light : TEXCOORD1;
out varying float3 normal : TEXCOORD2;
out varying float3 view : TEXCOORD3;
};
output main(input IN)
{
output OUT = output(0);
OUT.position = mul(IN.worldViewProjMatrix, IN.position);
OUT.texCoord = IN.texCoord;
OUT.light = IN.lightDir;
float3 worldPosition = normalize(mul(IN.worldMatrix, IN.position)).xyz;
OUT.view = IN.eyePosition - worldPosition;
OUT.normal = normalize(mul(IN.invTransWorldMatrix, IN.normal)).xyz;
return OUT;
}片段着色器:
struct input {
in varying float2 texCoord : TEXCOORD0;
in varying float3 light : TEXCOORD1;
in varying float3 normal : TEXCOORD2;
in varying float3 view : TEXCOORD3;
in uniform float3 diffuse;
in uniform float3 ambient;
in uniform float3 specular;
in uniform float shininess;
in uniform sampler2D colorMapSampler;
};
float4 main(input IN) : COLOR
{
float4 color = tex2D(IN.colorMapSampler, IN.texCoord);
float3 normal = normalize(IN.normal);
float3 lightDir = normalize(IN.light);
float3 viewDir = normalize(IN.view);
float3 diff = saturate(dot(normal, lightDir));
float3 reflect = normalize(2 * diff * normal - lightDir);
float3 specular = pow(saturate(dot(reflect, viewDir)), IN.shininess);
float4 result;
//result = float4(color.rgb * (IN.ambient + IN.diffuse * diff) + IN.specular * specular, 1.0f);
result = float4(IN.normal, 1.0f);
return result;
}我发现有些地方列出了这些作为glVertexAttribPointer的索引,但它们很容易出错(这些是VBO设置函数中的Shader::POSITION、Shader::NORMAL等):
enum GenericVertexInputIndices
{
POSITION = 0,
BLENDWEIGHT = 1,
NORMAL = 2,
DIFFUSE = 3, COLOR0 = 3,
SPECULAR = 4, COLOR1 = 4,
TESSFACTOR = 5, FOGCOORD = 5,
PSIZE = 6,
BLENDINDICES = 7,
TEXCOORD0 = 8,
TEXCOORD1 = 9,
TEXCOORD2 = 10,
TEXCOORD3 = 11,
TEXCOORD4 = 12,
TEXCOORD5 = 13,
TEXCOORD6 = 14, TANGENT = 14,
TEXCOORD7 = 15, BINORMAL = 15,
};VBO设置功能如下:
void MeshObject::initVBO(const unsigned int&_indexVBO, unsigned int& _indexOffset)
{
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
//sub in this section of the index data
m_indexOffset = _indexOffset;
_indexOffset = _indexOffset + m_indices.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexVBO);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_indexOffset * sizeof(unsigned short), m_indices.size() * sizeof(unsigned short), &(m_indices[0]));
//init vertex data
glGenBuffers(1, &m_vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexVBO);
{
glBufferData(GL_ARRAY_BUFFER, m_data.size() * sizeof(VertexData), &(m_data[0]), GL_STATIC_DRAW);
glEnableVertexAttribArray(Shader::POSITION);
glVertexAttribPointer(Shader::POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)0);
glEnableVertexAttribArray(Shader::NORMAL);
glVertexAttribPointer(Shader::NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)12);
glEnableVertexAttribArray(Shader::TEXCOORD0);
glVertexAttribPointer(Shader::TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)24);
}
}着色器绑定函数如下:
void Shader::bind(const matrix4 &_worldTransform, const Material::MaterialInfo &_info)
{
CGerror error;
//bind to the shader
CGprofile profile = renderGlobals.shaderMgr.getProfile(static_cast<Shader::ShaderType>(m_shaderType));
cgGLEnableProfile(profile);
error = cgGetError();
cgGLBindProgram(m_program);
error = cgGetError();
switch (m_shaderType)
{
case VERTEX:
{
//get vertex parameters
CGparameter worldMatrix = cgGetNamedParameter(m_program, "IN.worldMatrix");
CGparameter worldViewProjMatrix = cgGetNamedParameter(m_program, "IN.worldViewProjMatrix");
CGparameter invTransWorldMatrix = cgGetNamedParameter(m_program, "IN.invTransWorldMatrix");
CGparameter light = cgGetNamedParameter(m_program, "IN.lightDir");
CGparameter eyePosition = cgGetNamedParameter(m_program, "IN.eyePosition");
error = cgGetError();
//set vertex parameters
matrix4 worldViewProj = *(renderGlobals.debugCamera.getViewProjectionMatrix()) * _worldTransform;
cgGLSetMatrixParameterfc(worldViewProjMatrix, worldViewProj.m16);
matrix4 invTransWorld = _worldTransform.getInverse().getTranspose();
if (invTransWorldMatrix != NULL)
{
cgGLSetMatrixParameterfc(invTransWorldMatrix, invTransWorld.m16);
}
if (worldMatrix != NULL)
{
cgGLSetMatrixParameterfc(worldMatrix, _worldTransform.m16);
}
vector3 lightPos = *renderGlobals.debugCamera.getPosition();
//vector3 lightPos = vector3(0.0f, 0.0f, 0.0f);
vector3 lightDir = lightPos - _worldTransform.wAxis;
if (light != NULL)
{
cgGLSetParameter3fv(light, lightDir.v);
}
if (eyePosition != NULL)
{
cgGLSetParameter3fv(eyePosition, renderGlobals.debugCamera.getPosition()->v);
}
error = cgGetError();
break;
}
case FRAGMENT:
{
//set up material info
CGparameter diffuse = cgGetNamedParameter(m_program, "IN.diffuse");
CGparameter ambient = cgGetNamedParameter(m_program, "IN.ambient");
CGparameter specular = cgGetNamedParameter(m_program, "IN.specular");
CGparameter shininess = cgGetNamedParameter(m_program, "IN.shininess");
if (diffuse != NULL)
{
cgGLSetParameter3fv(diffuse, _info.diffuse.rgb);
}
if (ambient != NULL)
{
cgGLSetParameter3fv(ambient, _info.ambient.rgb);
}
if (specular != NULL)
{
cgGLSetParameter3fv(specular, _info.specular.rgb);
}
if (shininess != NULL)
{
cgGLSetParameter1f(shininess, _info.shininess);
}
//set up textures
CGparameter colorMapSampler = cgGetNamedParameter(m_program, "IN.colorMapSampler");
if (colorMapSampler != NULL)
{
if (_info.textureInfo[0].size() > 0)
{
Index<Texture> texture = _info.textureInfo[0][0].texture;
cgGLSetTextureParameter(colorMapSampler, texture->getID());
cgGLEnableTextureParameter(colorMapSampler);
} else {
cgGLDisableTextureParameter(colorMapSampler);
}
}
break;
}
default:
{
//ERROR: tryin to bind a shader with an unknown type
assert(0);
unbind();
return;
}
}
}发布于 2011-09-04 05:05:18
更改了顶点输入结构中的语义,以使用ATTR*匹配我在GenericVertexInputIndices中的内容,瞧,它起作用了。我之前尝试过在顶点和片段着色器中将所有语义都更改为ATTR*,但没有注意到它没有抱怨顶点输入结构中的错误。显然,它们只用于顶点输入。另一个小细节把一切都搞砸了。
https://stackoverflow.com/questions/7290637
复制相似问题