2

GLSLバージョン4.10を使用してテクスチャマッピングを行う方法を理解しようとしています。私はGLSLにかなり慣れていないので、シェーダーを使用してsin(time)に基づいて色がフェードする三角形のレンダリングを今日取得できてうれしかったです。今、私は単一のテクスチャでシェーダーを使用することに興味があります。

多くのチュートリアルやStackOverflowの回答でさえ、gl_MultiTexCoord0の使用を提案しています。ただし、これはGLSL 1.30以降非推奨になり、最新バージョンは4.20になりました。私のグラフィックカードは4.20をサポートしていません。そのため、4.10を使用しようとしています。

テクスチャを適切に生成してバインドしていることはわかっています。固定関数パイプラインを使用しているときにハイトマップが完全にレンダリングされ、テクスチャではなく色でうまくレンダリングされるため、適切な頂点座標とテクスチャ座標があります。

これが私のGLSLシェーダーと私のC++描画コードの一部です:

---heightmap.vert (GLSL)---

in vec3 position;
in vec2 texcoord;

out vec2 p_texcoord;

uniform mat4 projection;
uniform mat4 modelview;

void main(void)
{
    gl_Position = projection * modelview * vec4(position, 1.0);
    p_texcoord = texcoord;
}


---heightmap.frag (GLSL)---

in vec2 p_texcoord;

out vec4 color;

uniform sampler2D texture;

void main(void)
{
    color = texture2D(texture, p_texcoord);
}


---Heightmap::Draw() (C++)---

// Bind Shader
// Bind VBO + IBO
// Enable Vertex and Texcoord client state

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);

// glVertexPointer(...)
// glTexCoordPointer(...)

glUniform4fv(projLoc, projection);
glUniform4fv(modelviewLoc, modelview);
glUniform1i(textureId, 0);

// glDrawElements(...)

// glDisable/unbind everything

私も疑わしいのは、頂点シェーダーではタッチしていないので、テクスチャコーディネイトをフラグメントシェーダーに変化として渡す必要があるかどうかです。また、そこから補間されたtexcoordsをどのように取得するのかわかりません。補間された座標ではなく、0.fまたは1.fを取得するようです。シェーダーについては、それがどのように機能するかを理解するのに十分な知識がありません。誰かが私を啓発することができれば、私はわくわくするでしょう!

編集1:

@Bahbar:申し訳ありませんが、それはタイプミスでした。あるマシンでコードを入力し、別のマシンでコードを読み取っています。私が言ったように、それはすべて固定機能パイプラインで機能しました。glEnableClientStateとgl[Vertex| TexCoord] Pointerは非推奨ですが、シェーダーで動作するはずですよね?glVertexAttribPointerではなくglVertexPointerは、テクスチャではなく色で機能しました。また、glBindAttribLocation(0の位置と1のtexcoord)を使用しています。

私がまだglVertexPointerを使用している理由は、一度に1つのことを非推奨にしようとしているからです。

4

1 に答える 1

3

glBindTextureテクスチャ オブジェクトを 2 番目のパラメータとして受け取ります。

// Enable Vertex and Texcoord client state

一般的な頂点属性を意味していると思いますか? あなたpositiontexcoord属性はどこに設定されていますか? これを行うには、glEnableClientState と glVertex/TexCoordPointer の代わりに、glEnableVertexAttrib と glVertexAttribPointer を呼び出す必要があります (これらはすべて、gl_MultiTexCoord が glsl にあるのと同じ方法で廃止されます)。

そしてもちろん、属性がバインドされている場所を把握するには、glGetAttribLocation を呼び出して GL が属性を配置するために選択した場所を把握するか、glBindAttribLocation を使用して自分で定義する必要があります (プログラムをリンクする前に)。

追加した後、編集して追加します。

まあ、0 は glVertexPointer からデータを引き出すことになるかもしれません (依存すべきではないという理由からです。attrib 0 は特別であり、ほとんどの IHV は Vertex と同じように機能します) が、1 は glTexCoord からデータを引き出すことはありません。

理論的には、一般的な属性 (texcoord など、glVertexAttribPointer(1,XXX) からデータを取得します。1 は選択した場所です) と組み込み属性 (取得する gl_MultiTexCoord[0] など) の間に重複はありません。 glTexCoordPointer からのデータ)。

現在、nvidia は仕様に準拠していないことが知られており、実際に属性をエイリアスし (これは、私の知る限り、Cg モデルに由来します)、glTexCoord に特定の属性の場所を使用するようにとまで述べています ( Cg仕様では、 TexCoord0 には位置 8 を使用し、位置 1 は属性の blendweight です (表 39、p242 を参照)。

于 2011-11-29T20:40:09.097 に答える