1.紋理
在gles2中,紋理在glsl中定義的順序,并不是按先后順序來排列的。
例如以下代碼:
1
uniform sampler2D Samp0;
2
uniform sampler2D Samp1;
3
uniform sampler2D Samp2; 假如我們以為Samp0是第0個紋理,Samp1是第1個紋理……這樣就錯了。
這里我們要顯式的指定每個Sampler的索引。
下面是取得紋理索引的代碼:
1
for (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前,要開啟紋理索引
1
for (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++如下定義:
1
typedef 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的時候崩。具體原因未明。