-1

Linux コンピューターで OpenGL 3.3 を使用できるようにするために Mesa 10.1.3 を使用しています。コア プロファイルのみが OpenGL 3.3 を備えているため、ウィンドウを作成するときにコア プロファイルを要求します。しかし、画面に三角形を表示する簡単なプログラムを作成しようとしても、何も得られませんでした。そのため、コードのどこかを台無しにしたと思っていましたが、再確認したところ、正しいものでした。これをテストするために、Windows でプログラムを実行してみましたが、正常に動作していました。そこで、コードをもう少し試してみました。頂点シェーダーで頂点の位置を 0.001 倍したところ、三角形が表示されましたが、それでも正常に機能していませんでした。私が見た三角形は直角三角形でしたが、正三角形を意図していました (Windows では正三角形が表示されます)。したがって、OpenGL Core プロファイルを使用すると、頂点の位置が多少異なると思いますが、これを修正する方法がよくわかりません。私は何を間違っていて、何をすべきですか?

ところで、これは私の頂点シェーダーが次のようになっています。

#version 330

in vec3 position;

void main()
{
  gl_Position = vec4(0.001*position, 1.0);
}

フラグメント シェーダー:

#version 330

out vec4 fragColor;

void main()
{
  fragColor = vec4(0.0, 1.0, 1.0, 1.0);
}

シェーダー クラス:

public Shader()
    {
    program = glCreateProgram();
    if(program == 0)
    {
        System.err.println("Shader creation failed: Could not find valid memory location");
        System.exit(1);
    }
    }

    public void bind()
    {
    glBindAttribLocation(program, 0, "position");
    glUseProgram(program);
    }

    public void addVertexShader(String text)
    {
    addProgram(text, GL_VERTEX_SHADER);
    }

    public void addFragmentShader(String text)
    {
    addProgram(text, GL_FRAGMENT_SHADER);
    }

    public void addGeometryShader(String text)
    {
    addProgram(text, GL_GEOMETRY_SHADER);
    }

    public void compile()
    {
    glLinkProgram(program);

    if(glGetProgrami(program, GL_LINK_STATUS) == 0)
    {
        System.err.println(glGetProgramInfoLog(program, 1024));
        System.exit(1);
    }

    glValidateProgram(program);

    if(glGetProgrami(program, GL_VALIDATE_STATUS) == 0)
    {
        System.err.println(glGetProgramInfoLog(program, 1024));
        System.exit(1);
    }
    }

    public void addProgram(String text, int type)
    {
    int shader = glCreateShader(type);

    if(shader == 0)
    {
        System.err.println("Shader creation failed");
        System.exit(1);
    }

    glShaderSource(shader, text);
    glCompileShader(shader);

    if(glGetShaderi(shader, GL_COMPILE_STATUS) == 0)
    {
        System.err.println(glGetShaderInfoLog(shader, 1024));
        System.exit(1);
    }

    glAttachShader(program, shader);

    }

そして、VBOを作成している頂点の配列:

Vertex[] data = new Vertex[] {            
new Vertex(new Vector3f(-0.1f, -0.1f, 0)),
new Vertex(new Vector3f(0,  1, 0)),
new Vertex(new Vector3f( 1,  -1, 0))};

私の描画方法:

public void draw()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//Vertex is a class which only holds a Vector3f for position, currently, so size is set to 3
glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
glDrawArrays(GL_TRIANGLES, 0, size);
glDisableVertexAttribArray(0);
}

そして、これは私が得ている結果です: ここに画像の説明を入力

4

1 に答える 1

1

あなたのglBindAttribLocation()電話は遅すぎます:

glBindAttribLocation(program, 0, "position");
glUseProgram(program);

glBindAttribLocation()効果を得るには、 のに呼び出す必要がありますglLinkProgram()。移動するか、glGetAttribLocation()リンク後に使用して、リンカーが属性に割り当てた場所を取得できます。またはさらに簡単に、GLSL 3.30 を使用しているため、シェーダー コードで場所を指定できます。

layout(location = 0) in vec3 position;

コア プロファイルを使用する場合は、Vertex Array Objects (VAO) も使用する必要があります。glGenVertexArrays()コードにやのような呼び出しがない場合はglBindVertexArray()、それらが必要になります。「OpenGL VAO」または「OpenGL Vertex Array Object」を検索すると、ここSOまたはインターネットの残りの部分に多くの例があるはずなので、あまり繰り返しません。大まかに言うと、頂点の状態の初期化を開始する前に、次のようになります。

GLuint vaoId = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// calls to glVertexAttribPointer, glEnableVertexAttribArray

次に、描画の準備ができたら:

glBindVertexArray(vao);

頂点データの定義も、問題の原因となる可能性があるようです。

Vertex[] data = new Vertex[] {            
new Vertex(new Vector3f(-0.1f, -0.1f, 0)),
new Vertex(new Vector3f(0,  1, 0)),
new Vertex(new Vector3f( 1,  -1, 0))};

これを VBO に入力するコードは示されていませんが、渡されるデータはglBufferData()フラットで連続したフロートの配列/バッファである必要がありますが、これはベクトル オブジェクト参照の配列です。

于 2014-09-11T06:10:15.460 に答える