首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CG着色器语义与OpenGL 3.x?

CG着色器语义与OpenGL 3.x?
EN

Stack Overflow用户
提问于 2011-09-03 09:40:27
回答 1查看 3.1K关注 0票数 2

我曾经在OpenGL 2.x中使用CG着色器处理顶点数组,但我在OpenGL 3.x中更新了VBO和VAO,现在除了位置之外,语义似乎不起作用了。CG不会抛出任何编译错误,但如果我在片段着色器中将输出颜色设置为输入正常值,我只会得到纯黑。还有另一个链接到一个页面的答案,上面写着使用cgGLEnableClientState (它自己什么都不做)和cgGLSetParameterPointer (这看起来很疯狂,因为我已经把数据发送到OpenGL了,为什么还要通过CG发送另一个副本)。那么我错过了什么呢?

顶点着色器:

代码语言:javascript
复制
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;
}

片段着色器:

代码语言:javascript
复制
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::POSITIONShader::NORMAL等):

代码语言:javascript
复制
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设置功能如下:

代码语言:javascript
复制
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);
    }
}

着色器绑定函数如下:

代码语言:javascript
复制
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;
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-04 05:05:18

更改了顶点输入结构中的语义,以使用ATTR*匹配我在GenericVertexInputIndices中的内容,瞧,它起作用了。我之前尝试过在顶点和片段着色器中将所有语义都更改为ATTR*,但没有注意到它没有抱怨顶点输入结构中的错误。显然,它们只用于顶点输入。另一个小细节把一切都搞砸了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7290637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档