2017-08-17 20 views
1

私はLWJGLを使って "タイル"を描画しています。あるいは、スクリーン上にテクスチャ化された2Dの四角形を描画しています。ただし、テクスチャ座標は常に(0、0)であるため、テクスチャ付きの四角形は最初のピクセルカラーを使用して塗りつぶします。フラグメントシェーダのテクスチャ座標が常に(0、0)ですか?

これは私の頂点シェーダです:

#version 330 core 

in vec4 in_Position; 
in vec4 in_Color; 
in vec2 in_TextureCoord; 

out vec4 pass_Color; 
out vec2 pass_TextureCoord; 

void main(void) { 
    gl_Position = in_Position; 

    pass_Color = in_Color; 
    pass_TextureCoord = in_TextureCoord; 
} 

そして、これは私のフラグメントシェーダです:

#version 330 core 

uniform sampler2D texture_diffuse; 

in vec4 pass_Color; 
in vec2 pass_TextureCoord; 

out vec4 out_Color; 

void main(void) { 
    out_Color = pass_Color; 
    // Override out_Color with our texture pixel 
    out_Color = texture(texture_diffuse, pass_TextureCoord); 
} 

そして、これは基本的に私は四角形を描画するために使用しているコードです:

ARBShaderObjects.glUseProgramObjectARB(shaderProgram); 

glBindTexture(GL_TEXTURE_2D, sprite.getId()); 

glBegin(GL11.GL_QUADS); 
glVertex2d(screenMinX, screenMinY); 
glTexCoord2d(0.0, 0.0); 
glVertex2d(screenMaxX, screenMinY); 
glTexCoord2d(1.0, 0.0); 
glVertex2d(screenMaxX, screenMaxY); 
glTexCoord2d(1.0, 1.0); 
glVertex2d(screenMinX, screenMaxY); 
glTexCoord2d(0.0, 1.0); 
glEnd(); 

// release the shader 
ARBShaderObjects.glUseProgramObjectARB(0); 

上記のコードが最初にどのように機能するかわからないため、修正できません。 in_Positionin_Colorまたはin_TextureCoordが最初の2つだけであることをシェーダに伝えていませんが、うまく動作するようです。最終的にフラグメントシェーダに渡されるin_TextureCoordですが、これは(0、0)という一定の値を持つようです - フラグメントシェーダの出力カラーをXの値に等しいチャンネルに設定することでテクスチャ座標の座標。それは四角い全体にわたって単色のままであり、テクスチャ座標に変化がないことを示している。

上記のコードで生成された四角形はテクスチャである必要がありますが、その代わりに、与えられたテクスチャの最初のピクセルである無地の色が塗られています。テクスチャ座標をそれに応じて変更するには、コードをどのように変更できますか?もし私がこの全てがどのようにぴったり合っているのか誤解しているようであれば、私を修正してください。

Thisは私が上記を達成するために使ったチュートリアルです。

p.s.私は、Javaスニペットがdeprecatedイミディエイトモードを使用していることを認識していますが、glDrawArraysの使用方法や他の一般的に提案されている方法を理解することはできません。これを変える手助けをしてもらえますか?

+0

"これは本質的に私が四角形を描画するために使用するコードです:テクスチャ座標を決して設定しないでください。どうしてそれらが0、0以外のものになると思いますか? – tkausl

+0

@tkausl個々のピクセルごとにテクスチャ座標を設定するにはどうすればよいですか? OpenGLはピクセルを内部的に扱うように見えるので、私は混乱します。 – curz46

答えて

1

私は、Javaスニペットが廃止予定の即時モードを使用していることに気付いていますが、glDrawArraysの使用方法やその他の一般的な方法についてはわかりません。これを変える手助けをしてもらえますか?

あなたはもう属性in_Colorを必要としないので、あなたは(そしてもちろんのもpass_Color頂点シェーダとフラグメントシェーダからの)頂点シェーダから属性を削除する必要があります。
それ以外の場合は、color属性で論理的にソリューションを展開する必要があります。

float[] posData = { 
    screenMinX, screenMinY, 0.0, 1.0, 
    screenMaxX, screenMinY, 0.0, 1.0, 
    screenMaxX, screenMaxY, 0.0, 1.0, 
    screenMinX, screenMaxY, 0.0, 1.0 }; 

float[] texData = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 }; 

は、頂点配列オブジェクトを生成します:

int vaoObj = glGenVertexArrays(); 
glBindVertexArray(vaoObj); 

有効、頂点及びテクスチャ座標の配列バッファを生成頂点postionsの配列のテクスチャ座標を設定

属性インデックスにそれらのバッファを関連付ける:

FloatBuffer posBuffer = MemoryUtil.memAllocFloat(posData.length); 
posBuffer.put(posData).flip(); 
FloatBuffer texBuffer = MemoryUtil.memAllocFloat(texData.length); 
texBuffer.put(texData).flip(); 

int vboPosObj = glGenBuffers(); 
glBindBuffer(GL_ARRAY_BUFFER, vboPosObj); 
glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW); 

// index 0 to associate with "in_Position"    
glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0); 
glEnableVertexAttribArray(0); // 0 = attribute index of "in_Position" 

int vboTexObj = glGenBuffers(); 
glBindBuffer(GL_ARRAY_BUFFER, vboTexObj); 
glBufferData(GL_ARRAY_BUFFER, texBuffer, GL_STATIC_DRAW); 

// index 0 to associate with "in_TextureCoord" 
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0); 
glEnableVertexAttribArray(1); // 1 = attribute index of "in_TextureCoord" 

頂点配列オブジェクトを解放:

glBindBuffer(GL_ARRAY_BUFFER, 0); 
glBindVertexArray(0); 


あなたは、属性in_Positionin_TextureCoordの属性インデックスを指定する必要があります。

あなたは頂点シェーダに明示的なレイアウト仕様を使用するか:

layout (location = 0) in vec4 in_Position; 
layout (location = 1) in vec2 in_TextureCoord; 

それともあなたはシェーダプログラム(glLinkProgram)をリンク右前に、シェーダプログラムに属性インデックスを指定します。

glBindAttribLocation(shaderProgramID, 0, "in_Position"); 
glBindAttribLocation(shaderProgramID, 1, "in_TextureCoord"); 


オブジェクトを描画する場合、vertexArrayObjectを結合するのに十分である:

glBindVertexArray(vaoObj); 
glDrawArrays(GL_QUADS, 0, 4); // 4 = number of vertices 
glBindVertexArray(0); 

注、バッファオブジェクトまたは頂点配列オブジェクトをさらに使用しないで、それが有する場合メモリリークを防ぐために削除する必要があります。 glDeleteBuffersによって削除されたバッファオブジェクトと頂点配列オブジェクトは、glDeleteVertexArraysによって削除されます。
バッファオブジェクトは頂点配列オブジェクトの下に作成されないため、頂点配列オブジェクトのみを削除するだけでは不十分です(OpenGL Vertex Array/Buffer Objects参照)

+0

返信いただきありがとうございます。私はこれを前に試しましたが、変化はありません。これも同様です。 – curz46

+0

@ curz46私は自分の答えを変えました。 – Rabbid76

+0

ありがとうございます。これは私の問題を解決しましたが、 'glDrawArrays'の' EXCEPTION_ACCESS_VIOLATION'を防ぐために大きなコードブロック( 'glDrawArrays'呼び出しの下を動かす)で' glBindVertexArray(0) 'の2つのインスタンスを削除しなければなりませんでした。また、GL_TRIANGLESをGL_QUADSに変更して元のように四角形を描画する必要がありました。私はこの答えが今後のレンダリングのための私の手がかりとなると思います。 – curz46

関連する問題