2016-06-27 4 views
1

iPhoneのOpenGL Es 1.1でピクセルベースのアート(レトロタイルとアートと考える)に問題があります。OpenGL ESピクセルアート - スケーリング

タイルは、各ビットが設定されているかどうかを示す8バイト(各行に1バイト)を使用して表されます。例えば

番号8のタイル:

0 0 0 0 0 0 0 0  -> 
0 0 1 1 1 0 0 0  ->  xxx 
0 1 0 0 0 1 0 0  ->  x x 
0 1 0 0 0 1 0 0  ->  x x 
0 0 1 1 1 0 0 0  ->  xxx 
0 1 0 0 0 1 0 0  ->  x x 
0 1 0 0 0 1 0 0  ->  x x 
0 0 1 1 1 0 0 0  ->  xxx 

iPhone上のOpenGLにこれを変換

glDrawArrays(GL_POINTS, 0, 64); 

Simulator output at 100%

ロジックが正しいが、問題は、それがdoesnのある使用レトロな効果を与えません。私は塊状の/レトロなスタイルのより多くを探していた。私は()私はそれがGL_Disable(POINT_SMOOTHだったと思うが、この効果のESは何も変わっていないので、かどうかわからない。)。私は、ピクセルが正方形として表示される原因となるピクセルのスムージングをオフにすることができますことを読んで私が見つけ

可能な解決策を

  1. フレームバッファを使用して、より小さい解像度にレンダリングし、レンダリングバッファに拡大します。私はこれがどのように行われているのか、それがうまくいくのか分かりません。
  2. ピクセルからイメージを作成し、そのイメージからテクスチャを作成し、最後にそのテクスチャをレンダリングします。各画素について

    1. を、水平方向と垂直方向の両方の代わりに二つの画素を描画する:iがオフ考え

    可能な解決策。

  3. 三角形を使用して各ピクセルを正方形として描画します。
  4. GLPointSizeを使用する - 2に設定すると正しい効果が得られますが、座標が崩れます。整列が難しくなります。

最終的に私はタイルを提示することを希望:

Retro pixels - Number 8

これはどのようにOpenGLとピクセルの仕事を理解し、私のより多くのであり、私はこれを動作するようにゲームボーイエミュレータを使用しています。もし誰かが、グラフィックスを手動で作成し、それらをテクスチャとしてロードするという正しい方法を考えているのであれば、実行可能な答えではありません。

答えて

0

私の質問が明確ではないが、画面にピクセルを描画するには、テクスチャを作成してピクセルデータを渡してから、そのテクスチャを画面にレンダリングする必要があります。これは、glDrawPixelsに相当します。

コードは次のようになります。

どこかのセットアップで
#define W 255,255,255 

#define G 192,192,192 

//8 x 8 tile with 3 bytes for each pixel RGB format 
GLubyte pixels[8 * 8 * 3] = { 
W,W,W,W,W,W,W,W, 
W,W,G,G,G,W,W,W, 
W,G,W,W,W,G,W,W, 
W,G,W,W,W,G,W,W, 
W,W,G,G,G,W,W,W, 
W,G,W,W,W,G,W,W, 
W,G,W,W,W,G,W,W, 
W,W,G,G,G,W,W,W 
}; 

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glGenTextures(1, &tex); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, tex); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

そして、いつものようにテクスチャを描く:

glActiveTexture(GL_TEXTURE0); 
glUniform1i([program uniformLocation:@"s_texture"], 0); 
glBindTexture(GL_TEXTURE_2D, tex); 

glEnableVertexAttribArray(positionAttrib); 
glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0, v); 
glEnableVertexAttribArray(texAttrib); 
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, t); 
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, i); 
+0

右。 'GL_POINTS'を描画すると、個々のジオメトリの部分を描画します。バッファの中で最も小さなものが描画されます。 'GL_TRIANGLES'を描画すると、ディスプレイの連続部分に描画され、そこに含まれるすべてのピクセルが何らかの価値を得るようにします。あなたが望むのは、低解像度のグラフィックスがポイントサンプリングで高解像度にスケールされていると仮定すれば、それらを元の解像度でアップロードし、GL_NEARESTを使って出力を表現したい領域に描画するだけです。そのすべてはあなたがすでに把握しているように見えます! – Tommy

1

これを行うにはかなりの方法があります。最初に見つけたものをお勧めします。小さなバッファにシーンを描画し、それをキャンバスに再描画します。

あなたが探しているのは、FBO(フレームバッファオブジェクト)です。 FBOを作成してテクスチャを貼り付ける方法の例を見てください。これにより、入力する任意の寸法のバッファが作成されます。いくつかの一般的な問題は、POTテクスチャ(2の累乗:2,4,8,16 ...など64x128バッファ)を必要とする可能性が最も高いため、異なるサイズを制御するためにはビューポートを使用する必要があります必要なバッファの一部だけを使用してください。

これにより、キャンバス(ビュー)に描画するために使用できる低解像度のテクスチャが作成されます。あなたが試してみるべきものを描く方法。ポイントは最良の解決策ではないかもしれません。バッファの場合でも、私があなたの例で定義したポイント間の線を使用します。この時点で、アンチエイリアスの有無に関わらず描画を選択する必要があります。これを有効にするには、iOS上でマルチサンプリングを探します。

シェイプが描画されるテクスチャを作成したら、それをビューに再描画する必要があります。これは、フルスクリーンのテクスチャをかなり描くことです。繰り返しますが、複数の描画方法があります。最も強力なツールは、テクスチャパラメータです。最も近いものを使用すると、すべての色補間が破棄され、四角形が表示されます。線形(または三線形)を使用すると補間が行われ、結果はおそらく達成したいものに近いものになります。次に、マルチサンプリングでアンチエイリアスを作成し、より良い結果を得るために、もう一度試してみてください。

だからここ累乗である:FBOについては

をキャンバスに再描画すると

  • 異なるFBOバッファはFBO
  • テクスチャパラメータ
  • アンチエイリアスにアンチエイリアス
  • のサイズこれは最も簡単な操作の1つです:

    • 生成するフレームバッファは、(glGenFramebuffers
    • はバインドフレームバッファ(glBindFramebuffer
    • テクスチャ(glGenTextures)を作成し、それをバインドするには、(glBindTexture
    • セットテクスチャデータglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    • はにテクスチャをアタッチフレームバッファglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.textureID, 0);
    • テクスチャに描画するときに、FBOフレームバッファをバインドする必要があり、メインバッファに描画するときにそのフレームバッファをバインドするだけです。

    これは非常に広範な回答です(質問のとおりです)。これを実装しており、さらに質問や問題がある場合は、個別の質問を作成し、おそらくコメント。

    幸運。

+0

FBOsがある、ES 1.1でサポートされていません。 OPが使用したいもの。 ES 1.1の使用は良いアイデアだと言っているわけではありませんが、これは実際に質問されたように答えません。 –

+0

@RetoKoradi - 私は感謝の言葉に基づいてes2に切り替えました。 –

+0

IveはFBOに関するより具体的な質問を作成しました - http:// stackoverflow。com/questions/38071480/opengl-es-fbo-scaling –