我正在尝试将一个小场景渲染到一个立方体贴图中,以用于 WebGL 中的反射——使用 Emscripten(C++ 到 JavaScript)。我的代码只是通过 6 个面,并将所有对象渲染到立方体纹理的当前绑定侧。该代码适用于桌面版本,没有错误。但是 WebGL 说:
渲染警告:没有纹理绑定到单元 0。
在检查 glGetError(); 后,我也收到错误 1282;当我调用“glDrawElements”时。两条消息出现 30 次(将 5 个网格渲染为 6 个面 - 6*5=30)
Fbo & 纹理创建
glGenFramebuffers(1, &m_FboId);
glBindFramebuffer(GL_FRAMEBUFFER, m_FboId);
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
for (unsigned int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, CUBEMAP_SIZE, CUBEMAP_SIZE, 0, GL_RGB, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#if !WEB
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Wrap_R is invalid in WebGL
#endif
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glGenRenderbuffers(1, &m_DepthId);
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, CUBEMAP_SIZE, CUBEMAP_SIZE);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthId);
m_DrawBuffers[0] = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, m_DrawBuffers);
int fbo_Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fbo_Status != GL_FRAMEBUFFER_COMPLETE) printf(" ::ENGINE:: FBO Creation Failed! glError: %i\n", fbo_Status);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
渲染:
glBindFramebuffer(GL_FRAMEBUFFER, m_FboId);
glViewport(0, 0, CUBEMAP_SIZE, CUBEMAP_SIZE);
Object* objectPtr;
shader.bind();
shader.loadProjectionMtx(math::perspective(90.0f, 1.0f, 0.001f, 300.0f)[0][0]);
shader.loadCameraPosition(m_Position.x, m_Position.y, m_Position.z);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
math::mat4 viewMtx(1.0f);
for (unsigned int f = 0; f < 6; f++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, m_glId, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (f == 2)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3( 0.0f, -1.0f, 0.0f), math::vec3(0.0f, 0.0f, 1.0f));
else if (f == 1)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3( 1.0f, 0.0f, 0.0f), math::vec3(0.0f, -1.0f, 0.0f));
else if (f == 4)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3( 0.0f, 0.0f, -1.0f), math::vec3(0.0f, -1.0f, 0.0f));
else if (f == 3)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3( 0.0f, 1.0f, 0.0f), math::vec3(0.0f, 0.0f, -1.0f));
else if (f == 0)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3(-1.0f, 0.0f, 0.0f), math::vec3(0.0f, -1.0f, 0.0f));
else if (f == 5)
viewMtx = math::lookAt(m_Position, m_Position - math::vec3( 0.0f, 0.0f, 1.0f), math::vec3(0.0f, -1.0f, 0.0f));
shader.loadViewMtx(viewMtx[0][0]);
for (unsigned int i = 0; i < m_Entities.size(); i++)
{
shader.loadModelMtx(m_Entities[i]->getMtx()[0][0]);
objectPtr = static_cast<Object*>(m_Entities[i]);
for (int t = 0; t < 3; t++)
{
glActiveTexture(GL_TEXTURE0 + t);
glBindTexture(GL_TEXTURE_2D, objectPtr->getTextureId(t));
glUniform1i(objectPtr->getUniformLoc(t), t);
}
glBindVertexArray(objectPtr->getMesh()->getVao());
int error = glGetError();
glDrawElements(GL_TRIANGLES, objectPtr->getMesh()->getNumberOfIndices(), GL_UNSIGNED_SHORT, 0);
error = glGetError(); if (error != 0) printf("GL ERROR: %i\n", error);
glBindVertexArray(0);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
我在这里做了什么 WebGL 不喜欢的事情?当我将场景渲染到 2D 纹理到另一个 FBO 时,这正是我渲染场景的方式。唯一不同的是,这一次,我渲染成立方体纹理。