用于 3D 头像效果的 Android OpenGL ES
最编程
2024-03-07 07:29:50
...
void AvatarSample::Draw(int screenW, int screenH)
{
LOGCATE("AvatarSample::Draw()");
if(m_ProgramObj == GL_NONE) return;
float dScaleLevel = m_FrameIndex % 200 * 1.0f / 1000 + 0.0001f;
float scaleLevel = 1.0;
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(m_ProgramObj);
glBindVertexArray(m_VaoId);
//1. 背景层的绘制
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_TextureIds[0]);
glUniform1i(m_SamplerLoc, 0);
scaleLevel = static_cast<float>(1.0f + dScaleLevel * pow(-1, m_FrameIndex / 200));
scaleLevel = scaleLevel < 1.0 ? scaleLevel + 0.2f : scaleLevel;
m_ScaleY = m_ScaleX = scaleLevel + 0.4f;
GLUtils::setVec2(m_ProgramObj, "u_texSize", glm::vec2(m_RenderImages[0].width, m_RenderImages[0].height));
GLUtils::setFloat(m_ProgramObj, "u_needRotate", 1.0f); // u_needRotate == 1 开启形变
GLUtils::setFloat(m_ProgramObj, "u_rotateAngle", m_TransX * 1.5f);
UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, m_TransX / 2, m_TransY / 2, (float)screenW / screenH);
glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0);
//2. 人像层的绘制
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_TextureIds[1]);
glUniform1i(m_SamplerLoc, 1);
scaleLevel = static_cast<float>(1.0f + dScaleLevel * pow(-1, m_FrameIndex / 200 + 1));
scaleLevel = scaleLevel < 1.0 ? scaleLevel + 0.2f : scaleLevel;
m_ScaleY = m_ScaleX = scaleLevel + 0.4f;
LOGCATE("AvatarSample::Draw() scaleLevel=%f", scaleLevel);
UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, m_TransX * 1.2f, m_TransY * 1.2f, (float)screenW / screenH);
GLUtils::setVec2(m_ProgramObj, "u_texSize", glm::vec2(m_RenderImages[0].width, m_RenderImages[0].height));
GLUtils::setFloat(m_ProgramObj, "u_needRotate", 0.0f);// u_needRotate == 0 关闭形变
GLUtils::setFloat(m_ProgramObj, "u_rotateAngle", m_TransX / 20);
glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0);
//3. 外层的绘制
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);
//切换另外一个着色器程序
glUseProgram(m_BlurProgramObj);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_TextureIds[2]);
GLUtils::setFloat(m_BlurProgramObj, "s_TextureMap", 0);
scaleLevel = static_cast<float>(1.0f + dScaleLevel * pow(-1, m_FrameIndex / 200));
scaleLevel = scaleLevel < 1.0 ? scaleLevel + 0.2f : scaleLevel;
m_ScaleY = m_ScaleX = scaleLevel + 0.8f;
UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, m_TransX * 2.5f, m_TransY * 2.5f, (float)screenW / screenH);
GLUtils::setMat4(m_BlurProgramObj, "u_MVPMatrix", m_MVPMatrix);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0);
glDisable(GL_BLEND);
m_FrameIndex ++;
}