我正在进行一些重构,尝试使用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;
}
}