0

そのため、OpenGL でよりモダンなシェーダーベースのレンダリング システムに移行しようとしています。私が理解しているように、その一部は、代わりに古い OpenGL の組み込みマトリックス スタックで達成されていた投影を実行しています。私自身の行列をシェーダーに。これが私のシェーダーです (申し訳ありませんが、何らかの理由で、コードの書式設定に空白を表示できません)。

//Vertex

attribute vec3 coord3d;
attribute vec3 v_color;
varying vec3 f_color;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;

void main(void) 
{
        gl_Position = projection * view * model * vec4(coord3d, 1.0);
        f_color = v_color;
}

//Fragment

varying vec3 f_color;

void main(void) 
{
    gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);
}

ただし、射影および/またはビュー行列による乗算によってテストオブジェクトが消えるという問題がありました。シェーダーを次のように変更すると:

gl_Position = model * vec4(coord3d, 1.0);

オブジェクトは、画面の [-1, 1] スペースに対してフラットで配置され、画面上で期待どおりに表示されます。これを段階的に見ていきましょう。

関連する 3 つのクラスがあります。シーン、オブジェクト、カメラと呼びましょう。Scene のコンストラクターでは、これらの Gluints が設定されます。

//Model - must be changed for each model
Object::ModelUniform = glGetUniformLocation(ObjectShader, "model");

//View - must be changed once per frame
m_ViewUniform = glGetUniformLocation(ObjectShader, "view");

//Projection - must only be set once    
m_ProjectionUniform = glGetUniformLocation(ObjectShader, "projection");
glm::mat4 projection = glm::perspective(60.0f, 1.33f, 0.1f, 512.f);
glUniformMatrix4fv(m_ProjectionUniform, 1, GL_FALSE, glm::value_ptr(projection));

次に、フレームごとに 1 回 (まだシーンにあります。古いシェーダー + glMultMatrixf() コードでバックグラウンドで実行されている他のオブジェクトがありますが、2 つの間に相互作用があるとは思いません)。

glm::vec3 Eye = glm::vec3(CameraPos.x, CameraPos.y, CameraPosz);

glm::vec3 Center = glm::vec3(ObjectPos.x, ObjectPos.y, ObjectPosz);

glm::vec3 Up = glm::vec3(0.0, 1.0, 0.0);

glm::mat4 view = glm::lookAt(Eye, Center, Up);
glUniformMatrix4fv(m_ViewUniform, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(ObjectShader);
Object->Cycle();

次に、Object::Cycle() で:

glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(Position.x, Position.y, Position.z));
glUniformMatrix4fv(Object::ModelUniform, 1, GL_FALSE, glm::value_ptr(model));
glEnableVertexAttribArray(CoordinateAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(CoordinateAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);

glEnableVertexAttribArray(ColorAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(ColorAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));

glDrawArrays(GL_TRIANGLES, 0, 6);

glDisableVertexAttribArray(ColorAttribute);
glDisableVertexAttribArray(CoordinateAttribute);

glDisable(GL_BLEND);

glBindBuffer(GL_ARRAY_BUFFER, 0);

私が使用するすべての行列は、glMultMatrixf() のような非推奨の関数を使用して、古い OpenGL で正常に動作します。

前述のように、モデル マトリックスのみを使用しても問題なく動作します。カメラを回転させても、見つからないオブジェクトが見つかりません。

ここで何が問題になる可能性がありますか?

4

2 に答える 2

4

ここ:

glUniformMatrix4fv(m_ProjectionUniform, 1, GL_FALSE, glm::value_ptr(projection));

そしてここ

glm::mat4 view = glm::lookAt(Eye, Center, Up);
glUniformMatrix4fv(m_ViewUniform, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(ObjectShader);
Object->Cycle();

ビューを設定していますが、その後シェーダーをアクティブにします。射影行列に同じ問題があるかもしれませんが、コードからはわかりません。ユニフォームを設定するには、シェーダーをアクティブにする必要があります。それらを設定している間、シェーダーがバインドされていない可能性があります。一方、投稿したビットから、シェーダーは常にアクティブになる可能性があるため、これは最初のフレームの後に機能します。それを伝えることは不可能です。

于 2013-03-06T16:39:27.870 に答える
1

これを試して:

uniform mat4 ModelView;
uniform mat4 ProjectionView;

in vec4 position;

void main()
{
    gl_Position = ProjectionView * ModelView * position ;
}

行列の乗算は、OpenGL では右から左に進みます。

于 2013-03-02T14:29:28.163 に答える