3

VBO、VAO、IBO、およびシェーダーを使用して、基本的な Quad-renderer を作成しようとしています。主にVBO、VAO、IBOを1つだけ使用して、要素が追加/削除されたときにデータを再バッファリングしようとしています。カラーグレーディングの代わりにテクスチャを実装することを決定するまで、ほとんどすべてがうまくいきました.

ClientStates のような廃止された関数の使用を避け、シェーダー内のテクスチャを使用する可能性があるため、何を試しても何も描画されません。

何も描画されていないという問題に加えて、テクスチャが BRectangle クラス内に保存されているという問題があり、DrawElements の使用中にそれらにアクセスする方法がわかりません。

また、追加のインデックスを追加する必要がないように、IBO を再利用できますか?

私の現在のアプローチ:

Renderer に Rectangle atm を追加すると、必要なデータがバッファリングされます。

    public class ShaderRenderer {

    public static final int POSITION_INDEX = 0; // index of vertex attribute "in_Position"
    public static final int TEXTURE_INDEX = 1; // index of vertex attribute "in_Texture"

    public static final int FLOAT_NUM_BYTES; // sizeof(float) in bytes
    public static final int INT_NUM_BYTES; // sizeof(int) in bytes
    public static final int VEC4_BYTES; // sizeof(vec4) in bytes

    static {
        FLOAT_NUM_BYTES = Float.SIZE / Byte.SIZE;
        INT_NUM_BYTES = Integer.SIZE / Byte.SIZE;
        VEC4_BYTES = 4 * FLOAT_NUM_BYTES;
    }

    private VAO vao = new VAO();
    private VBO vbo = new VBO();
    private IBO ibo = new IBO();

    private int elements = 0;

    public ShaderRenderer() {
        try {
            ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", POSITION_INDEX, TEXTURE_INDEX);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void add( BRectangle rect ) {

        // Bind the VAO
        // This OpenGL-object groups the "in_Position" and "in_Color"
        // vertex attributes.
        vao.bind();

        // Bind the VBO and add the FloatBuffer from the Rect
        vbo.bind();
        vbo.addBuffer(rect.vertexData);

        ibo.bind();
        ibo.addIndices(generateIndices());
        ibo.buffer();

        //==============================================================       
        // Now we tell OpenGL that we will use POSITION_INDEX and COLOR_INDEX
        // to communicate respectively the vertex positions and vertex colors
        // to our shaders.
        {
            // First we enable the indices. This will affect the vertex
            // array object from above.
            glEnableVertexAttribArray(POSITION_INDEX);
            Util.checkGLError();


            // Then we tell OpenGL how it should read the GL_ARRAY_BUFFER
            // (to which we have bound our vertex data, see above).

            // The position data starts at the beginning of the vertex data
            glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false,
                    2 * VEC4_BYTES, 0);
            Util.checkGLError();

            // The color data starts after the first 4 floats of position data
            glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false,
                    0, VEC4_BYTES);
            Util.checkGLError();
        }

        vbo.bufferData();

        // Just to be VERY clean, we will unbind the vertex attribute object
        // and only bind it when we render. This way we cannot accidentally modify
        // it anymore.
        vao.unbind();

        // Only after the vertex array is disabled, we unbind the buffers
        // to the GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER targets, because
        // otherwise the vertex array object would become invalid again.
        vbo.unbind();

        ibo.unbind();
    }

    void DestroyVBO() {

        glDisableVertexAttribArray(POSITION_INDEX);
        Util.checkGLError();

        glDisableVertexAttribArray(TEXTURE_INDEX);
        Util.checkGLError();

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        Util.checkGLError();

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        Util.checkGLError();

        glDeleteBuffers(ibo.id);
        Util.checkGLError();

        glDeleteBuffers(vbo.id);
        Util.checkGLError();

        glBindVertexArray(0);
        Util.checkGLError();

        glDeleteVertexArrays(vao.id);
        Util.checkGLError();
    }


    private int[] generateIndices() {
        int c = elements * 3;
        int v[] = { c, c+1, c+2,
                    c, c+3, c+2};
        elements++;
        return v;
    }

    public void render () {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        Util.checkGLError();


        vao.bind();
        glDrawElements(
                GL_TRIANGLES,
                ibo.size,
                GL_UNSIGNED_INT,
                0);
        Util.checkGLError();

        vao.unbind();
    }

}

私の基本的な Rectangle クラス

public class BRectangle  {
    final int amountOfVertices = 8;
    final int vertexSize = 3;
    final int textureSize = 2;

    public FloatBuffer vertexData;

    Texture texture;

    public BRectangle(float x, float y ) {
        float[] VerticesArray = new float[]{
                -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
                -0.1f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
                -0.1f, 0.4f, 0.0f, 1.0f, 1.0f, 1.0f,
                -0.5f, 0.4f, 0.0f, 1.0f, 0.0f, 1.0f
            };
        vertexData = BufferUtils.createFloatBuffer(24);
        vertexData.put(VerticesArray);



        try {
            texture = Textures.loadTexture("data/floor.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
        glBindTexture(GL_TEXTURE_2D, texture.getTextureID());

    }

}

main[] を使用したテスト

public class ShaderTest {

    ShaderRenderer sr;

    FpsCounter c;

    public ShaderTest() {
    }

    public void create() throws LWJGLException, Exception {

        new SimpleDisplay(800, 600, "test", false, false);
        glOrtho(0, 800, 0, 600, 1, -1);
        //Keyboard
        Keyboard.create();

        c = new FpsCounter();

        Textures.setUpTextureLoader();

        //Mouse
        Mouse.setGrabbed(false);
        Mouse.create();

        sr = new ShaderRenderer();
        //OpenGL
        initGL();


    }


    public void destroy() {
        Mouse.destroy();
        Keyboard.destroy();
        Display.destroy();
    }

    public void initGL() throws IOException {



        ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", ShaderRenderer.POSITION_INDEX, ShaderRenderer.TEXTURE_INDEX);
        sr.add(new BRectangle(0f, 0f));
    }

    public void processKeyboard() {
    }

    public void processMouse() {
    }

    public void render() throws LWJGLException {
        sr.render();
    }


    public void run() throws LWJGLException {
        while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
            if (Display.isVisible()) {
                processKeyboard();
                processMouse();
                update();
                render();
            } else {
                if (Display.isDirty()) {
                    render();
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
            }

            Display.update();
            //Display.sync(60);
        }
    }

    public void update() {
        c.updateFPS();
    }

    public static void main(String[] args) {
        ShaderTest main = null;
        try {
            main = new ShaderTest();
            main.create();
            main.run();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (main != null) {
                main.destroy();
            }
        }
    }
}

そしてopenglinit

public static void initGLSlim() {
    glClearColor(0, 0, 0, 0);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);

    glEnable(GL11.GL_TEXTURE_2D);  

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 800, 600, 0, 1, -1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}

頂点シェーダー

#version 140

in vec4 in_Position;
in vec2 in_Texture;
out vec2 out_Texture;

void main(void)
{
   gl_Position = vec4(in_Position.x *0.75 ,in_Position.y, in_Position.z, in_Position.w);
   out_Texture = in_Texture;
}

フラグメントシェーダー

#version 140

in vec2 out_Texture;
uniform sampler2D mytexture;
out vec4 fragColor;

void main(void)
{
   fragColor = texture2D(mytexture, out_Texture);
}
4

1 に答える 1

2

ストライド パラメータが正しくありません。

ここにあなたが持っているものがあります:

glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false, 2 * VEC4_BYTES, 0); 
glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false, 0, VEC4_BYTES);

ポジション インデックスにフロート ストライドが 8 であることを伝えていますが、これは正しくありません。私が知る限り、4 つの頂点をアップロードしており、頂点ごとに 6 つの float (4x 位置 + 2x テクスチャ) を使用しています。つまり、あなたの POSITION ストライドは6 * FLOAT_NUM_BYTES.

同じ配列にパックされているため、テクスチャストライドは同じである必要があります。ここでは、texcoords が密集していることを伝えていますが、実際には 6 float ごとに 1 組の texcoords しかありません。繰り返しますが、ここが必要6 * FLOAT_NUM_BYTESです。


また、追加のインデックスを追加する必要がないように、IBO を再利用できますか?

はい、IBO を使用して、必要な数のオブジェクトを描画できます。ただし、すべてのオブジェクトが同じインデックスを必要とする場合に限ります。


その他のあまり深刻でないコメント:

  • 初期化で clearColor をゼロにする必要はありません。デフォルトではゼロです。
  • 初期化で depth_test/lighting を無効にする必要はありません。デフォルトではオフになっています。
  • シェーダーを使用しているときは glEnable(GL_TEXTURE_2D) を呼び出さないでください。このスイッチは、固定パイプラインのテクスチャリングのみを有効にし、シェーダー プログラムには影響しません。コアプロファイルに移動するとエラーが発生するため、削除してください。
于 2012-08-29T15:47:36.297 に答える