OpenGL在哪里将glVertexAttribPointer放在面向对象的模型中?

时间:2014-01-18 14:26:50

标签: java oop opengl lwjgl object-oriented-analysis

我正在使用Java / LWJGL,并且在学习OpenGL的过程中正在围绕LWJGL创建我自己的轻型面向对象框架,但是我对如何处理glVertexAttribPointer感到很困惑。 / p>

请使用以下代码:

public class GameController extends Controller {
    //<editor-fold defaultstate="collapsed" desc="keep-imports">    
    static {
        int KEEP_LWJGL_IMPORTS = GL_2_BYTES | GL_ALIASED_LINE_WIDTH_RANGE | GL_ACTIVE_TEXTURE | GL_BLEND_COLOR | GL_ARRAY_BUFFER | GL_ACTIVE_ATTRIBUTE_MAX_LENGTH | GL_COMPRESSED_SLUMINANCE | GL_ALPHA_INTEGER | GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | GL_ALREADY_SIGNALED | GL_ANY_SAMPLES_PASSED | GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH | GL_ACTIVE_PROGRAM | GL_ACTIVE_ATOMIC_COUNTER_BUFFERS | GL_ACTIVE_RESOURCES | GL_BUFFER_IMMUTABLE_STORAGE;
        int KEEP_OWN_IMPORTS = PROJECTION_MATRIX.getLocation();
    }
//</editor-fold>

    private Program testProgram;
    private VertexArray vertexArray;
    private ArrayBuffer arrayBuffer;

    private final Matrix4f modelviewMatrix = new Matrix4f();
    private final FloatBuffer modelViewMatrixBuffer = BufferUtils.createFloatBuffer(16);

    private float aspect;
    private Matrix4f projectionMatrix;

    final float[] vertexPositions = new float[] {
        -0.25f,  0.25f, -0.25f,
        -0.25f, -0.25f, -0.25f,
         0.25f, -0.25f, -0.25f,

         0.25f, -0.25f, -0.25f,
         0.25f,  0.25f, -0.25f,
        -0.25f,  0.25f, -0.25f,

         0.25f, -0.25f, -0.25f,
         0.25f, -0.25f,  0.25f,
         0.25f,  0.25f, -0.25f,

         0.25f, -0.25f,  0.25f,
         0.25f,  0.25f,  0.25f,
         0.25f,  0.25f, -0.25f,

         0.25f, -0.25f,  0.25f,
        -0.25f, -0.25f,  0.25f,
         0.25f,  0.25f,  0.25f,

        -0.25f, -0.25f,  0.25f,
        -0.25f,  0.25f,  0.25f,
         0.25f,  0.25f,  0.25f,

        -0.25f, -0.25f,  0.25f,
        -0.25f, -0.25f, -0.25f,
        -0.25f,  0.25f,  0.25f,

        -0.25f, -0.25f, -0.25f,
        -0.25f,  0.25f, -0.25f,
        -0.25f,  0.25f,  0.25f,

        -0.25f, -0.25f,  0.25f,
         0.25f, -0.25f,  0.25f,
         0.25f, -0.25f, -0.25f,

         0.25f, -0.25f, -0.25f,
        -0.25f, -0.25f, -0.25f,
        -0.25f, -0.25f,  0.25f,

        -0.25f,  0.25f, -0.25f,
         0.25f,  0.25f, -0.25f,
         0.25f,  0.25f,  0.25f,

         0.25f,  0.25f,  0.25f,
        -0.25f,  0.25f,  0.25f,
        -0.25f,  0.25f, -0.25f
    };

    public GameController(final boolean debug) {
        super(debug);
    }

    @Override
    protected void init() {
        glViewport(0, 0, 800, 600);
        testProgram = new Program(
                new VertexShader("shaders/test.vert.glsl").compile(),
                new FragmentShader("shaders/test.frag.glsl").compile()
                ).compile();
        testProgram.use();

        vertexArray = new VertexArray().create().bind();
        arrayBuffer = new StaticDrawArrayBuffer().create().fillData(vertexPositions);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        glEnableVertexAttribArray(0);

        aspect = 800f / 600f;
        projectionMatrix = new Matrix4f().identity().perspective(50.0f, aspect, 0.1f, 1000.0f);
        Uniforms.setUniformMatrix4(PROJECTION_MATRIX, false, projectionMatrix);

        glEnable(GL_CULL_FACE);
        glFrontFace(GL_CW);

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    }

    @Override
    protected void render(final double msDelta) {
        glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
        glClearDepthf(1f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        testProgram.use();

        for (int i = 0; i < 24000; i++) {
            float fVar = i + currentTime / 1000f * 0.3f;
            modelviewMatrix.identity()
                    .translate(0.0f, 0.0f, -8.0f)   //translate
                    .rotate(currentTime / 1000f * 45.0f, 0.0f, 1.0f, 0.0f)  //rotate around Y
                    .rotate(currentTime / 1000f * 21.0f, 1.0f, 0.0f, 0.0f)  //rotate around X
                    .translate(
                        (float)Math.sin(2.1f * fVar) * 2.0f,
                        (float)Math.cos(1.7f * fVar) * 2.0f,
                        (float)Math.sin(1.3f * fVar) * (float)Math.cos(1.5f * fVar) * 2.0f
                    );  //translate
            Uniforms.setUniformMatrix4(MODELVIEW_MATRIX, false, modelviewMatrix.writeToFloatBuffer(modelViewMatrixBuffer));
            testProgram.drawArrays(GL_TRIANGLES, 0, 36);
        }
    }

    @Override
    protected void shutdown() {
        testProgram.delete();
        vertexArray.delete();
        arrayBuffer.delete();
    }

    @Override
    protected void windowResized(final int width, final int height) {
        aspect = width * 1.0f / height;
        projectionMatrix = new Matrix4f().identity().perspective(50.0f, aspect, 0.1f, 1000.0f);
        Uniforms.setUniformMatrix4(PROJECTION_MATRIX, false, projectionMatrix);
    }

    public static void main(String[] args) {
        Controller controller = new GameController(false);
        controller.start();
    }
}

我希望有人能够准确地向我解释我应该在glVertexAttribPointerglEnableVertexAttribArray放置在面向对象的模型中,例如VertexArrayArrayBuffer({ {1}}是超类)或者甚至可能在Buffer中? 我认为我对框架的所有底层调用都是非常自我解释的,否则随便问一下。

2 个答案:

答案 0 :(得分:2)

很难说没有看到这个陈述是如何实现的:

   arrayBuffer = new StaticDrawArrayBuffer().create().fillData(vertexPositions);

假设为了使用arrayBuffer创建并填充vertexPositions,该函数的副作用为glBindBuffer (GL_ARRAY_BUFFER, ...),那么您可以有意义地调用glVertexAttribPointer (...)

然而,我会说清楚fillData (...)已经说出了副作用。正如你的代码现在所代表的那样,没有人会从它的角度知道那行代码实际上绑定了一个缓冲区对象。为了保持一致性,您甚至可以考虑在bind (...)课程中添加StaticDrawArrayBuffer方法,并在glVertexAttribPointer (...)之前立即调用该方法。

至于哪个类应该包含你讨论的函数,那些都存储在每个顶点数组对象中。所以将它们添加到VertexArray。您甚至可能希望修改VertexAttribPointer包装器接口,以便它引用缓冲区对象,而不是像GL API那样使用选择器/锁存器机制。

答案 1 :(得分:0)

您应该在绘制之前启用它们,并在绘制完成后禁用它们。