2

私の問題は、OpenGL を使用したテキストのレンダリングに関するものです。テキストはテクスチャにレンダリングされてから、クワッドに描画されます。問題は、テクスチャの端にあるピクセルが部分的に透明に描画されることです。質感の内部は細かいです。

NEAREST (非) 補間を使用し、テクスチャ ラッピングを CLAMP_TO_EDGE に設定し、ビューポート ピクセルの中心に頂点を配置するように投影行列を設定して、テクセルの中心に到達するテクスチャ座標を計算しています。まだ問題が発生しています。

テクスチャ ユーティリティを使用して VTK に取り組んでいます。これらは、テクスチャをロードするために使用される GL 呼び出しであり、デバッガーでステップスルーすることによって決定されます。

glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Create and bind pixel buffer object here (not shown, lots of indirection in VTK)...
glTexImage2D( GL_TEXTURE_2D, 0 , GL_RGBA, xsize, ysize, 0, format, GL_UNSIGNED_BYTE, 0);
// Unbind PBO -- also omitted
glBindTexture(GL_TEXTURE_2D, id);
glAlphaFunc (GL_GREATER, static_cast<GLclampf>(0));
glEnable (GL_ALPHA_TEST);
// I've also tried doing this here for premultiplied alpha, but it made no difference:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();

レンダリング コード:

  float p[2] = ...; // point to render text at

  int imgDims[2] = ...; // Actual dimensions of image
  float width = ...; // Width of texture in image
  float height = ...; // Height of texture in image

  // Prepare the quad
  float xmin = p[0];
  float xmax = xmin + width - 1;
  float ymin = p[1];
  float ymax = ymin + height - 1;
  float quad[] = { xmin, ymin,
                   xmax, ymin,
                   xmax, ymax,
                   xmin, ymax };

  // Calculate the texture coordinates.
  float smin = 1.0f / (2.0f * (imgDims[0]));
  float smax = (2.0 * width - 1.0f) / (2.0f * imgDims[0]);
  float tmin = 1.0f / (2.0f * imgDims[1]);
  float tmax = (2.0f * height - 1.0f) / (2.0f * imgDims[1]);

  float texCoord[] = { smin, tmin,
                       smax, tmin,
                       smax, tmax,
                       smin, tmax };

  // Set projection matrix to map object coords to pixel centers
  // (modelview is identity)
  GLint vp[4];
  glGetIntegerv(GL_VIEWPORT, vp);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  float offset = 0.5;
  glOrtho(offset, vp[2] + offset,
          offset, vp[3] + offset,
          -1, 1);

  // Disable polygon smoothing. Why not, I've tried everything else?
  glDisable(GL_POLYGON_SMOOTH);

  // Draw the quad
  glColor4ub(255, 255, 255, 255);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glVertexPointer(2, GL_FLOAT, 0, points);
  glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
  glDrawArrays(GL_QUADS, 0, 4);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);

  // Restore projection matrix
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

デバッグの目的で、最も外側のテクセルを赤で上書きし、次の内側のテクセル レイヤーを緑で上書きしました (そうしないと、ほとんどが白のテキスト イメージで何が起こっているのかわかりにくくなります)。

gDEBugger を使用してメモリ内のテクスチャを調べたところ、期待どおりに見えます。テクスチャ領域の周りに明るい赤と緑の境界線があります (サイズが 2 の累乗になるように、余分な空きスペースがパディングされています)。参考のため:

良いピクセル!

最終的にレンダリングされたイメージは次のようになります (20 倍に拡大 -- 黒いピクセルは、デバッグ境界の下にレンダリングされたテキストの残りです)。淡い赤の境界線ですが、まだ太字の緑の境界線:

ピクセルが悪い!

したがって、影響を受けるのはピクセルの外縁だけです。色のブレンドなのかアルファブレンディングなのかよくわかりません。途方に暮れています。コーナー ピクセルがエッジ ピクセルの 2 倍薄いことに気付きました。おそらくそれは重要なことです...ここで誰かがエラーを見つけることができるでしょうか?

4

2 に答える 2

0

「ピクセルパーフェクト」の問題である可能性があります。OpenGL は、ラインの中心をピクセルにラスタライズされるスポットと定義します。中間は、1 つの整数と次の整数のちょうど中間です...ピクセル (x,y) を取得して「ピクセル パーフェクト」を表示するには...座標を次のように修正します。

x=(int)x+0.5f; // x is a float.. makes 0.0 into 0.5, 16.343 into 16.5, etc. 
y=(int)y+0.5f;

これがおそらくブレンドを台無しにしているものです。テクスチャの変調でも同じ問題がありました...下端と右端にある単一のやや暗い線または一連のピクセル。

于 2013-09-22T05:19:16.810 に答える