3

私はOpenGLでGUIに取り組んでいます。この画像を使用してボタンのテクスチャを作成しています。 ここに画像の説明を入力してください

よく見えませんが、周囲に明るい境界線(幅2ピクセル)があります。

私が達成したいのは、境界線をそのままにしておく、サイズ変更可能なボタンを用意することです。ここで私に与えられたヒントによると、StackOverflowで9セルパターンを使用することにしたので、クワッドを次のように9つの部分に分割しました。

ここに画像の説明を入力してください

私はそれが境界線について行った場合に達成した効果が本当に好きですが、問題は中央(9番目)にあるクワッドにあります:

ここに画像の説明を入力してください

境界線を無視して、同じようにテクスチャを繰り返したりラップしたりしたいと思います。

だから私の質問は-私が今使っている1つのテクスチャだけでこれを行う方法はありますか?または、境界線の幅だけ減少する2番目のテクスチャを作成し、このクワッドをこのテクスチャの中央にレンダリングする必要がありますか?

また、それが必要かどうかはわかりませんが、ここに私のコードの断片を入れています:

これは、テクスチャのタイリング/ラッピングに使用しているコードです。

switch(m_bTiling)
{
case true:
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                     GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                     GL_REPEAT );
    break;
case false:
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                     GL_CLAMP );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                     GL_CLAMP );
    break;
}

そして、これがクワッドを描画するためのコードです:

// Top left quad [1]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0f, 1.0-maxTexCoordBorderY);                     
    glVertex2i(pos.x, pos.y + m_borderWidth);

    // Top left
    glTexCoord2f(0.0f, 1.0);    
    glVertex2i(pos.x, pos.y);

    // Top right
    glTexCoord2f(maxTexCoordBorderX, 1.0);  
    glVertex2i(pos.x + m_borderWidth, pos.y);

    // Bottom right
    glTexCoord2f(maxTexCoordBorderX, 1.0-maxTexCoordBorderY);
    glVertex2i(pos.x + m_borderWidth, pos.y + m_borderWidth);
glEnd();

// Top middle quad [2]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(maxTexCoordBorderX, 1.0 - maxTexCoordBorderY);             
    glVertex2i(pos.x + m_borderWidth, pos.y + m_borderWidth);

    // Top left
    glTexCoord2f(maxTexCoordBorderX, 1.0);
    glVertex2i(pos.x + m_borderWidth, pos.y);

    // Top right
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, 1.0);   
    glVertex2i(pos.x + width - m_borderWidth, pos.y);

    // Bottom right
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, 1.0 - maxTexCoordBorderY);
    glVertex2i(pos.x + width - m_borderWidth, pos.y + m_borderWidth);
glEnd();

// Top right quad [3]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(1.0 - maxTexCoordBorderX, 1.0 - maxTexCoordBorderY);                   
    glVertex2i(pos.x + width - m_borderWidth, pos.y + m_borderWidth);

    // Top left
    glTexCoord2f(1.0 - maxTexCoordBorderX, 1.0);
    glVertex2i(pos.x + width - m_borderWidth, pos.y);

    // Top right
    glTexCoord2f(1.0, 1.0); 
    glVertex2i(pos.x + width, pos.y);

    // Bottom right
    glTexCoord2f(1.0, 1.0 - maxTexCoordBorderY);    
    glVertex2i(pos.x + width, pos.y + m_borderWidth);
glEnd();

// Middle left quad [4]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0, maxTexCoordBorderY);              
    glVertex2i(pos.x, pos.y + height - m_borderWidth);

    // Top left
    glTexCoord2f(0.0, maxTexCoordHeight - maxTexCoordBorderY);
    glVertex2i(pos.x, pos.y + m_borderWidth);

    // Top right
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordHeight - maxTexCoordBorderY);           
    glVertex2i(pos.x + m_borderWidth, pos.y + m_borderWidth);

    // Bottom right
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordBorderY);
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);
glEnd();

// Middle right quad [5] 
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(1.0 - maxTexCoordBorderX, maxTexCoordBorderY);                     
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height - m_borderWidth);

    // Top left
    glTexCoord2f(1.0 - maxTexCoordBorderX, maxTexCoordHeight - maxTexCoordBorderY);
    glVertex2i(pos.x + width - m_borderWidth, pos.y + m_borderWidth);

    // Top right
    glTexCoord2f(1.0, maxTexCoordHeight - maxTexCoordBorderY);  
    glVertex2i(pos.x + width, pos.y + m_borderWidth);

    // Bottom right 
    glTexCoord2f(1.0, maxTexCoordBorderY);  
    glVertex2i(pos.x + width, pos.y + height - m_borderWidth);
glEnd();

// Bottom left quad [6]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0, 0.0);                     
    glVertex2i(pos.x, pos.y + height);

    // Top left
    glTexCoord2f(0.0, maxTexCoordBorderY);  
    glVertex2i(pos.x, pos.y + height - m_borderWidth);

    // Top right
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordBorderY);   
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);

    // Bottom right
    glTexCoord2f(maxTexCoordBorderX, 0.0);  
    glVertex2i(pos.x + m_borderWidth, pos.y + height);
glEnd();

// Bottom middle quad [7]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(maxTexCoordBorderX, 0.0);                          
    glVertex2i(pos.x + m_borderWidth, pos.y + height);

    // Top left
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordBorderY);
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);

    // Top right
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, maxTexCoordBorderY);    
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height - m_borderWidth);

    // Bottom right
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, 0.0);   
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height);
glEnd();

// Bottom right quad [8]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(1.0 - maxTexCoordBorderX, 0.0);                        
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height);

    // Top left
    glTexCoord2f(1.0 - maxTexCoordBorderX, maxTexCoordBorderY);
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height - m_borderWidth);

    // Top right
    glTexCoord2f(1.0, maxTexCoordBorderY);  
    glVertex2i(pos.x + width, pos.y + height - m_borderWidth);

    // Bottom right 
    glTexCoord2f(1.0, 0.0);
    glVertex2i(pos.x + width, pos.y + height);
glEnd();

// Middle middle quad [9]
glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordBorderY);                   
    glVertex2i(pos.x + m_borderWidth, pos.y + height - m_borderWidth);

    // Top left
    glTexCoord2f(maxTexCoordBorderX, maxTexCoordHeight - maxTexCoordBorderY);   
    glVertex2i(pos.x + m_borderWidth, pos.y + m_borderWidth);

    // Top right
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, maxTexCoordHeight - maxTexCoordBorderY);        
    glVertex2i(pos.x + width - m_borderWidth, pos.y + m_borderWidth);

    // Bottom right 
    glTexCoord2f(maxTexCoordWidth - maxTexCoordBorderX, maxTexCoordBorderY);
    glVertex2i(pos.x + width - m_borderWidth, pos.y + height - m_borderWidth);
glEnd();
4

2 に答える 2

1

えーと、あなたの問題がわかります。「ミドルミドル」クワッドには、一定値のmaxTexCoordBorderX(およびY)を使用しています。サイズの変更に応じて中央の四角形のUV座標を再計算する必要があります(例:width /(currWidth-2 * borderWidth))。その後、テクスチャを常に繰り返すように設定できますが、テクスチャ座標をui要素として変更するためです。サイズを変更すると、中央部分が繰り返されることはありません。

もちろん、将来のある時点でVBOまたはよりパフォーマンスの高いものを使用する場合は、それぞれに2つのフラグメントシェーダー(それぞれが独自のsampler2Dオブジェクトを持ち、1つは繰り返し、もう1つはストレッチ)を定義するだけです。タイリングモードで、「リピート」シェーダーを使用してすべてのコーナークワッドとミドルミドルクワッドをレンダリングし、ストレッチシェーダーを使用してすべてのエッジクワッドをレンダリングします。これは再計算を必要とせず、非常に高速である必要があります。

注:ここでは複数の四角形を描画していますが、これはお勧めできません。共有頂点を持つインデックス付きメッシュを使用することをお勧めします。これにより、大腿四頭筋の境界での「裂け目」の可能性が最小限に抑えられます。

于 2012-12-13T15:24:09.530 に答える
0

エッジ/中央をストレッチしている場合は問題ありませんが、タイリングしているため、中央部分だけで2番目のテクスチャを作成する必要があります。

境界線のサイズがある場合、これはプログラムで実行できることに注意してください。センターのコンテンツを新しい2D配列にコピーしてから、それを別のテクスチャにアップロードします。

別の解決策(コメントで述べたように)は、中央の中央の四角形のテクスチャ座標をコーナーの内側の頂点と同じものに設定することです。このようにして、中央のクワッドのテクスチャが引き伸ばされます。これにより、右上隅のクワッドにすべてが含まれていない限り、右上隅の輝きに奇妙なストレッチが作成されることに注意してください。リピートソリューションを使用したい場合は、これに関してまだ問題があります。

それでも中央部分を繰り返したい場合で、レンダリングパイプライン全体を非推奨ではないOpenGLに移動してもかまわない場合は、ananthonlineの答えの方が適しています。レンダリングコードを最新のOpenGLに移動したくない、または移動できない場合は、テクスチャコピーがほとんど唯一の解決策です。

于 2012-12-13T14:34:08.163 に答える