2011-09-03 36 views
2

我曾經在OpenGL 2.x中使用過頂點數組的CG着色器,但我已經更新爲在OpenGL 3.x中使用VBO和VAO,現在除了POSITION以外,語義看起來並不起作用。 CG不會引發任何編譯錯誤,但是如果我將我的片段着色器中的輸出顏色設置爲我的輸入正常值,則只會變黑。還有另一個答案,鏈接到一個頁面說使用cgGLEnableClientState(它本身沒有做什麼)和cgGLSetParameterPointer(這似乎是瘋了,因爲我已經發送數據到OpenGL,爲什麼通過CG發送另一個副本)。那麼我錯過了什麼?CG Shader語義與OpenGL 3.x?

頂點着色器:

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某個地方,但他們很容易被錯誤的(這些是Shader::POSITIONShader::NORMAL, VBO設置功能等):

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; 
     } 
    } 
} 

回答

0

改變了頂點輸入結構語義使用ATTR *匹配什麼我在GenericVertexInputIndices,瞧,它的工作原理。我曾嘗試在頂點和片段着色器中將所有語義更改爲ATTR *,並得到一堆域衝突錯誤,但沒有注意到它沒有抱怨頂點輸入結構中的錯誤。顯然它們只是用於頂點輸入。另一個小細節完全把一切都搞砸了。