Opengl:使用VBO时改变视图矩阵的优化?

时间:2016-07-20 09:19:53

标签: opengl camera shader

我正在进行一些重构,尝试使用VBO和我自己的着色器来显示一些图形对象(让我们说1000个球体)而不是显示列表。

目前,我的对象在大约100毫秒内渲染得很好,但是当我尝试移动相机时(更改" viewmatrix"这是我的着色器的统一变量),我必须重新绘制所有我的对象,持续另外100毫秒......有没有办法通过只改变统一变量" viewmatrix"来减少这个时间。 ?

注意:在原始代码(使用显示列表的代码)中,移动相机后,通过使用" glCallList" ...功能,在不到10毫秒内重绘场景。我希望与VBO有类似的结果,但事实并非如此......我一定错过了一些......

以下是我的代码的一些示例:

抽屉(方法" drawMethod"执行1000次,每个球体一个):

    public void draw() {

        shaderProgram.start();

        transformationMatrix = TransformationMatrix.createTransformationMatrix(new Vector3f(0,0,0), 0, 0, 0, 1);
        shaderProgram.loadTransformationMatrix(transformationMatrix);
        shaderProgram.loadViewMatrix(renderer.camera);

        Light light = new Light(new Vector3f(50,50,100),new Vector3f(1,1,1));
        shaderProgram.loadLight(light);

        for (DrawingEntity entity : listOfEntities) {
            drawMethod(entity);
        }

        shaderProgram.stop();

        mapEntities.clear();

    }
    private void genericDrawMethod(DrawingEntity entity) {
            shaderProgram.enableNormal();
            float shineDamper = (float) entity.getMaterial().getShineDamper();
            float reflectivity = (float) entity.getMaterial().getReflectivity();
            shaderProgram.loadShineVariables(shineDamper,reflectivity);
            shaderProgram.loadAmbientLight(new Vector3f(
                        (float) renderer.data.getAmbientLightColor().getRed() / 255f,
                        (float) renderer.data.getAmbientLightColor().getGreen() / 255f,
                        (float) renderer.data.getAmbientLightColor().getBlue() / 255f));

            float[] vertices = entity.getVertices();
            float[] colors = entity.getColors();
            float[] idxBuffer = entity.getIndices();
            float[] normals = entity.getNormals();


            // VERTICES POSITIONS BUFFER
            storeDataInAttributeList(ShaderProgram.POSITION_ATTRIBUTE_IDX,VERTICES_IDX,vertices);

            // COLORS BUFFER
            shaderProgram.disableTexture();
            storeDataInAttributeList(ShaderProgram.COLOR_ATTRIBUTE_IDX,COLOR_IDX,colors);

            // NORMAL BUFFER
            storeDataInAttributeList(ShaderProgram.NORMAL_ATTRIBUTE_IDX,NORMAL_IDX,normals);

            // INDEX BUFFER
            int[] intIdxBuff = new int[idxBuffer.length];
            for (int i = 0; i < idxBuffer.length ; i++) {
                intIdxBuff[i] = (int) idxBuffer[i];
            }
            IntBuffer ibIdxBuff = Buffers.newDirectIntBuffer(intIdxBuff);
            // Select the VBO, GPU memory data, to use for colors
            gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, vboHandles[IDX_BUFF_IDX]);
            int numBytes = idxBuffer.length * 4;
            gl.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, numBytes, ibIdxBuff, GL2.GL_STATIC_DRAW);
            ibIdxBuff.rewind();

            // draw triangles
            gl.glDrawElements(GL2.GL_TRIANGLES, idxBuffer.length, GL2.GL_UNSIGNED_INT, 0);

            releaseVAOMemory();
        }

        private void storeDataInAttributeList(int shaderAttributeNumber, int bufferAttributeNumber, float[] data) {
            int coordinateSize = 0;
            switch (shaderAttributeNumber) {
            // recognize the type of VAO to determine the size of the coordinates
                case ShaderProgram.COLOR_ATTRIBUTE_IDX : coordinateSize = 4; break; // r, g, b, a
                case ShaderProgram.POSITION_ATTRIBUTE_IDX : coordinateSize = 3; break; // x, y, z
                case ShaderProgram.NORMAL_ATTRIBUTE_IDX : coordinateSize = 3; break; // x, y, z
                case ShaderProgram.UVMAPPING_ATTRIBUTE_IDX : coordinateSize = 2; break; // u, v
            }
            FloatBuffer fbData = Buffers.newDirectFloatBuffer(data);
            // Select the VBO, GPU memory data, to use for data
            gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vboHandles[bufferAttributeNumber]);
            int numBytes = data.length * 4;
            gl.glBufferData(GL2.GL_ARRAY_BUFFER, numBytes, fbData, GL2.GL_STATIC_DRAW);
            fbData.rewind(); // It is OK to release CPU after transfer to GPU
            // Associate Vertex attribute 1 with the last bound VBO
            gl.glVertexAttribPointer(shaderAttributeNumber, coordinateSize,
                                GL2.GL_FLOAT, false /* normalized? */, 0 /* stride */,
                                0 /* The bound VBO data offset */);
            gl.glEnableVertexAttribArray(shaderAttributeNumber);
            listOfVAOUsed.add(shaderAttributeNumber);
        }

        private void releaseVAOMemory() {
            for (Integer vao : listOfVAOUsed) {
                gl.glDisableVertexAttribArray(vao);
            }
            listOfVAOUsed.clear();
        }

我的顶点着色器:

#if __VERSION__ >= 130
    #define attribute in
    #define varying out
#endif

#ifdef GL_ES
    precision mediump float;
    precision mediump int;
#endif

uniform mat4    transformationMatrix;
uniform mat4    projectionMatrix;
uniform mat4    viewMatrix;
uniform vec3    lightPosition;
uniform float   useNormals; // 0 for no, 1 for yes

attribute vec3  attribute_Position;
attribute vec4  attribute_Color;
attribute vec3  attribute_Normal;
attribute vec3  attribute_TextureCoords;

varying vec4    varying_Color;
varying vec3    surfaceNormal;
varying vec3    toLightVector;
varying vec3    toCameraVector;
varying vec2    pass_textureCoords;
varying float   varying_useNormals;

void main(void)
{
    vec4 worldPosition = transformationMatrix * vec4(attribute_Position,1.0);

    varying_Color = attribute_Color;
    gl_Position = projectionMatrix * viewMatrix * worldPosition;

    varying_useNormals = useNormals;

    if (useNormals > 0.5)
    {
        surfaceNormal = (transformationMatrix * vec4(attribute_Normal,0.0)).xyz;
        toLightVector = lightPosition - worldPosition.xyz;
        toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;

        pass_textureCoords = attribute_TextureCoords;
    }
}

我的片段着色器:

#if __VERSION__ >= 130
    #define varying in
    out vec4 mgl_FragColor;
    #define texture2D texture
    #define gl_FragColor mgl_FragColor
#endif

#ifdef GL_ES
    precision mediump float;
    precision mediump int;
#endif

varying   vec4    varying_Color;
varying   vec3    surfaceNormal;
varying   vec3    toLightVector;
varying   vec3    toCameraVector;
varying   vec2    pass_textureCoords;
varying   float   varying_useNormals;

uniform   vec3    ambientLight;
uniform   vec3    lightColor;
uniform   float   shineDamper;
uniform   float   reflectivity;
uniform   sampler2D textureSampler;
uniform   float   useTexture; // 0 for no, 1 for yes

void main (void)
{
    vec4 inputColor = varying_Color;

    if (varying_useNormals > 0.5)
    {
        if (useTexture > 0.5)
        {
            inputColor = texture(textureSampler,pass_textureCoords);
        }

        vec3 unitNormal = normalize(surfaceNormal);
        if (!gl_FrontFacing)
        {
            unitNormal = -normalize(surfaceNormal);
        }

        vec3 unitLightVector = normalize(toLightVector);

        float nDot1 = dot(unitNormal,unitLightVector);

        float brightnessR = max(nDot1,ambientLight.x);
        float brightnessG = max(nDot1,ambientLight.y);
        float brightnessB = max(nDot1,ambientLight.z);
        //float brightness = max(nDot1,0.0);
        vec3 diffuse = vec3(brightnessR*lightColor.x,brightnessG*lightColor.y,brightnessB*lightColor.z);

        vec3 unitVectorToCamera = normalize(toCameraVector);
        vec3 lightDirection = -unitLightVector;
        vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);

        float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
        specularFactor = max(specularFactor,0.0);
        float damperFactor = pow(specularFactor,shineDamper);
        vec3 finalSpecular = damperFactor * reflectivity * lightColor;

        gl_FragColor = vec4(diffuse,1.0) * inputColor + vec4(finalSpecular,1.0);
    }
    else
    {
        gl_FragColor = inputColor;
    }
}

0 个答案:

没有答案