私は OpenGL の完全な初心者であり、現在のプラットフォームは iOS です。5 つの異なるテクスチャ フィルタ (コントラスト、明るさなど) を実装するアップルのサンプル GLImageProcessing を使用しています。この例では、一度に 1 つの効果を固定テクスチャに適用します。
アーカイブしたいのは、一度にすべてのフィルターをテクスチャに適用することです。
私が理解している限り、それを行う主な方法は2つあります。
- フレームバッファにレンダリング
- シェーダーを使用する
フィルターの例から既にいくつかの作業コードがあるので、当面はシェーダーを避けたいと思います。
私が正しく理解していれば、次のことを行う必要があります。
- フィルタリング プロセスの結果としてテクスチャを生成するオフスクリーン バッファの結果を定義します。
- 次のフィルターには、以前に作成されたフィルターが供給されます。(N 回繰り返す)
- 最終テクスチャをメイン バッファに配置する
残念ながら、「resultTexture」は常に空です:(
より適切だと思われる場合は、シェーダーを自由に使用してください...助けてください:)
// A simple vertex format
typedef struct {
GLfloat x, y, s, t;
} V2fT2f;
// Geometry flipping texcoords upside down
V2fT2f flipquad[4] = {
{ 0, 0, 0, 1 },
{ 1, 0, 1, 1 },
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
};
void drawGL(int wide, int high, float brightness, float contr )
{
GLuint resultTexture;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, wide, 0, high, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(wide, high, 1);
// Remember the FBO being used for the display framebuffer
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO);
//Create offscreen buffer and an empty texture
glGenTextures(1, &resultTexture);
glBindTexture(GL_TEXTURE_2D, resultTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffersOES(1, &ResultFBO);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_TEXTURE_2D,
ResultTexture,
0);
//Brightness filter
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glBindTexture(GL_TEXTURE_2D, sourceTexture); //Bind the original texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
float t = brightness;
if (t > 1.0f)
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glColor4f(t-1, t-1, t-1, t-1);
}
else
{
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
glColor4f(1-t, 1-t, 1-t, 1-t);
}
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
//Repeat for every other filter
glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
glBindTexture(GL_TEXTURE_2D, resultTexture); //Bind the result texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
// ... filter code
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
//Dispaly result step
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
glViewport(0, 0, wide, high);
glBindTexture(GL_TEXTURE_2D, resultTexture); //Bind the last result texture
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}