我正在我的游戏中间执行以下 C++ 代码(除此之外一切都运行良好),并且在渲染时我没有运行它:
MetaBalls::MetaBalls() : largeTexture(NULL), metaballsShader(NULL), smallTexture(NULL), smallFBO(0), largeFBO(0) {
// 1. Compile shader that will render small texture onto larger texture using blur threshold
CRender::Instance()->CreateShader("Shaders/metaballs.fs", "Shaders/metaballs.vs", &metaballsShader);
metaballsShader->_locations["projview"] = glGetUniformLocation(metaballsShader->_program, "projview");
// 4. Load the sprite that will be rendered as particles on the small texture
// TODO: batch render this
m_metaballSprite.InitSprite("Embellishments/particle.png", OFFSCREEN);
// 2. Create new texture and 2 frame buffers
// First frame buffer to render small texture, second frame buffer to scale small texture up into big one
glGenTextures(1, &smallTexture);
glBindTexture(GL_TEXTURE_2D, smallTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_OES, SMALL_TEX_W, SMALL_TEX_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// 3. Create second larger texture to contain final water textured (rendered in game as sprite)
glGenTextures(1, &largeTexture);
glBindTexture(GL_TEXTURE_2D, largeTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_OES, LARGE_TEX_W, LARGE_TEX_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// 5. Attach small texture to frame buffer
glGenFramebuffers(1, &smallFBO);
glBindFramebuffer(GL_FRAMEBUFFER, smallFBO);
glBindTexture(GL_TEXTURE_2D, smallTexture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
s3eDebugErrorShow(S3E_MESSAGE_CONTINUE_STOP, "Metaballs small framebuffer incomplete");
}
// 6. Attach large texture to other frame buffer
glGenFramebuffers(1, &largeFBO);
glBindFramebuffer(GL_FRAMEBUFFER, largeFBO);
glBindTexture(GL_TEXTURE_2D, largeTexture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
s3eDebugErrorShow(S3E_MESSAGE_CONTINUE_STOP, "Metaballs small framebuffer incomplete");
}
// 7. Build geometry for small frame buffer
float w = PTM_DOWNSCALE(SMALL_TEX_W);
float h = PTM_DOWNSCALE(SMALL_TEX_H);
CRender::Instance()->BuildQuad(
tVertex( b2Vec3(0,0,0), b2Vec2(0,1) ),
tVertex( b2Vec3(w,0,0), b2Vec2(1,1) ),
tVertex( b2Vec3(w,h,0), b2Vec2(1,0) ),
tVertex( b2Vec3(0,h,0), b2Vec2(0,0) ),
smallBuffer);
// 8. Build geometry for large frame buffer
w = PTM_DOWNSCALE(SMALL_TEX_W);
h = PTM_DOWNSCALE(SMALL_TEX_H);
CRender::Instance()->BuildQuad(
tVertex( b2Vec3(0,0,0), b2Vec2(0,1) ),
tVertex( b2Vec3(w,0,0), b2Vec2(1,1) ),
tVertex( b2Vec3(w,h,0), b2Vec2(1,0) ),
tVertex( b2Vec3(0,h,0), b2Vec2(0,0) ),
largeBuffer);
// return to default state
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
我的问题是我收到了从 OpenGL ES 2.0 报告的这个错误:
GL Error GL_INVALID_OPERATION on entry to function glGenFramebuffers(1, 0xd8450e8)
如果我在函数开始附近切换上述 opengl 调用的顺序,我可以在 glGenTextures 行、glBindFramebuffer 或什至在第一个 CreateShader 函数内执行的 glCreateProgram() 上出现 GL_INVALID_OPERATION。尽管使用当前调用顺序,着色器正在加载和编译正常。
我得到的错误破坏了 opengl.org 上这些调用的记录结果,例如,如果您传递 glGenFrameBuffers 未返回的非零值,glGenFramebuffers 应该只返回 GL_INVALID_OPERATION。但是,我检查了从 glGenFrameBuffers 返回的整数......它们是 2 和 3。这些没有错,因为我已经有了第三个帧缓冲区 elseware。我还尝试同时生成纹理和帧缓冲区,但它们会产生相同的 GLuint 并且会发生相同的错误。
知道这个错误是如何引起的吗?过去我在这个类中运行过类似的代码没有问题。