永远也不完美的程序

不断学习,不断实践,不断的重构……

常用链接

统计

积分与排名

好友链接

最新评论

gles2开发中遇到的问题及解决方法

1.纹理
在gles2中,纹理在glsl中定义的顺序,并不是按先后顺序来排列的。
例如以下代码:
1uniform sampler2D Samp0;
2uniform sampler2D Samp1;     
3uniform sampler2D Samp2;     
假如我们以为Samp0是第0个纹理,Samp1是第1个纹理……这样就错了。
这里我们要显式的指定每个Sampler的索引。
下面是取得纹理索引的代码:
 1for (GLint i = 0; i < nConstantNum; ++i)
 2{
 3    glGetActiveUniform(m_uiProgramObject, i, 256&constant.nLength, &constant.nSize, &constant.glType, constant.szConstantName);
 4    constant.nLocation = glGetUniformLocation(m_uiProgramObject, constant.szConstantName);
 5    constant.nUseType = GPUParameters::GetAutoConstantTypeByName((const char*)constant.szConstantName);
 6
 7        if (constant.glType == GL_SAMPLER_2D || constant.glType == GL_SAMPLER_CUBE)
 8        {
 9            //如果是纹理
10            s32 nUnitIndex = pPixelShader->GetSamplerIndex(constant.szConstantName);   //获得配置好的纹理的索引
11            if (nUnitIndex >= 0)
12            {
13                m_mapSamplers.insert(std::make_pair(constant.nLocation, nUnitIndex));
14            }

15            else
16            {
17                m_mapSamplers.insert(std::make_pair(constant.nLocation, 0));
18            }

19        }

20        else
21        {
22                //这里处理其他constant变量
23        }

24        
25}


然后在调用该shader前,要开启纹理索引
1for (AIRMap<s32, s32>::iterator it = m_mapSamplers.begin(); it != m_mapSamplers.end(); ++it)
2{
3 s32 nIndex = it->second;
4 glUniform1i(it->first, nIndex);
5}
这样才能使设置的纹理生效。

2.顶点定义
在DX下,顶点声明假如用了position,normal,uv,color,即使shade中其中一项没用到,只要在C++下把正确的长度传进去,这样渲染就会正常。
但glsl下,假如其中一项attribute没用到,会被过滤掉的,的以C++上传递的vertexbuffer的排列方式,必须要严格按照glsl里真正用到的attribute。
举个例子:
attribute mediump vec3 position;
attribute mediump vec3 normal;
attribute mediump vec4 inColor;
attribute mediump vec2 uvCoords;
C++如下定义:

 

1typedef struct tagVertexNormal 
2{
3
4    Vector3Df vPos;
5    Vector3Df normal;
6    CColorValue  color;
7    f32   tu, tv;
8}
VERTEX_NORMAL, *LPVERTEX_NORMAL;

假如glsl代码里的inColor没用到,那么按上面的传递将会发和错误。
要使正常运行,必须把CColorValue color这行去掉。

3.纹理采样要区分纹理是否含有mipmap
假如纹理没有mipmap,GL_NEAREST_MIPMAP_NEAREST这类的统一不能用作采样。

4.顶点属性的绑定必须在VB的更改后。
如下代码:
    LPRHWVERTEX pVertex = (LPRHWVERTEX)m_pScreenQuad->m_pVB->Lock();

    //左上角
    pVertex[0].color = color;
    pVertex[0].rhw = 1.0f;
    pVertex[0].tu = 0.0f;
    pVertex[0].tv = 0.0f;
    pVertex[0].x = rectScreen.left - fOffset;
    pVertex[0].y = rectScreen.top - fOffset;
    pVertex[0].z = 1.0f;

    //右上角
    pVertex[1].color = color;
    pVertex[1].rhw = 1.0f;
    pVertex[1].tu = fUVScale;
    pVertex[1].tv = 0.0f;
    pVertex[1].x = rectScreen.right - fOffset;
    pVertex[1].y = rectScreen.top - fOffset;
    pVertex[1].z = 1.0f;

    //右下角
    pVertex[2].color = color;
    pVertex[2].rhw = 1.0f;
    pVertex[2].tu = fUVScale;
    pVertex[2].tv = fUVScale;
    pVertex[2].x = rectScreen.right - fOffset;
    pVertex[2].y = rectScreen.bottom - fOffset;
    pVertex[2].z = 1.0f;

    //左下角
    pVertex[3].color = color;
    pVertex[3].rhw = 1.0f;
    pVertex[3].tu = 0.0f;
    pVertex[3].tv = fUVScale;
    pVertex[3].x = rectScreen.left - fOffset;
    pVertex[3].y = rectScreen.bottom - fOffset;
    pVertex[3].z = 1.0f;
    m_pScreenQuad->m_pVB->Unlock();

    while (!elemLst.IsEnd())
    {
        if (i >= m_vtGPUAttributes.size())
        {
            break;
        }
        GLAttributeInfo& attribInfo = m_vtGPUAttributes[i];
        GLint location = attribInfo.nLocation;
        const VERTEX_ELEMENT& elem = elemLst.GetNext();
        size_t typeSize = CVertexDeclaration::GetTypeSize(elem.m_eType);
        pBufferData = (char*)NULL + elem.m_nOffset;
        GLenum glType = OpenGLES2Mapping::GetGLType(elem.m_eType);
        int subUnitCount = typeSize / 4;

        glEnableVertexAttribArray(location);
        //GL_Check_Error( "OpenGLES2ShaderObject::Apply - glEnableVertexAttribArray" );
        glVertexAttribPointer(location, subUnitCount, glType, GL_FALSE, pVertexDeclaration->GetStride(), pBufferData);
        //GL_Check_Error( "OpenGLES2ShaderObject::Apply - glVertexAttribPointer" );
        glBindAttribLocation( m_uiProgramObject, location, attribInfo.szAttribName );
        //GL_Check_Error( "OpenGLES2ShaderObject::Apply - glBindAttribLocation" );
        pGLES2Renderer->AddVertexAttribValue(location);

        //PrintDebugString( "Enable and bind vertext attrib [%s] at [%d]\n", attribInfo.szAttribName, location );
        ++i;
    }
这里是先写顶点,再绑定顶点声明,如果顺序不对,就会在DrawXXX的时候崩。具体原因未明。

posted on 2014-02-20 19:33 狂烂球 阅读(1492) 评论(1)  编辑 收藏 引用 所属分类: 图形编程

评论

# re: gles2开发中遇到的问题及解决方法[未登录] 2014-04-25 23:38 zy

去看看最新的4U tech1.8  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理