OpenGL:单个顶点缓冲区中的两个球体

时间:2013-08-26 17:01:06

标签: java opengl lwjgl vbo

(问题在底部)我正在学习opengl(使用lwjgl)并通过发送缓冲区完成一些扁平形状的绘制。现在我需要在单个缓冲区中绘制许多球体。在我的上一个问题中,我被建议使用几何实例,但我不知道如何在java中使用任何着色器语言,所以我试图在单个缓冲区中创建多个对象,就像在示例中一样。

我试图通过QUAD_STRIP样式生成两个球体(使用lwjgl自己的GLU.Sphere()函数来填充缓冲区):

n=c1*(c2+1);
        float rr=(float) Math.random();
        float gg=(float) Math.random();
        float bb=(float) Math.random();
        float aa=(float) Math.random();

        positions = new float[c1 * (c2+1) * 3*2 *2];
        normals = new float[c1 * (c2+1) * 3*2 *2];
        colors = new float[c1 * (c2+1) * 4*2 *2];
        int counter=0;
        float drho = 3.141593F / 32.0f;
        float dtheta = 6.283186F / 32.0f;
        float ds = 1.0F / 32.0f;
        float dt = 1.0F / 32.0f;
        float t = 1.0F;

        /*first sphere*/
        for (int i = 0; i < 32; i++) {
            float rho = i * drho;

            float s = 0.0F;
            for (int j = 0; j <= 32; j++) {
              float theta = j == 32 ? 0.0F : j * dtheta;
              float x = (float) (-Math.sin(theta) * Math.sin(rho));
              float y = (float) (Math.cos(theta) * Math.sin(rho));
              float z = (float) (1.0f * Math.cos(rho));           

              normals[counter*3+0]=x*1.0f;normals[counter*3+1]=y*1.0f;normalscounter*3+2]=z*1.0f;

              colors[counter*4+0]=rr;colors[counter*4+1]=gg;colors[counter*4+2]=bb;colors[counter*4+3]=1.0f/*aa*/;  

              positions[counter*3+0]=x*r;positions[counter*3+1]=y*r;positions[counter*3+2]=z*r;
              counter++;
              x = (float) (-Math.sin(theta) * Math.sin(rho + drho));
              y = (float) (Math.cos(theta) * Math.sin(rho + drho));
              z = (float) (1.0f * Math.cos(rho + drho));

              normals[counter*3+0]=x*1.0f;normals[counter*3+1]=y*1.0f;normals[counter*3+2]=z*1.0f;

              colors[counter*4+0]=rr;colors[counter*4+1]=gg;colors[counter*4+2]=bb;colors[counter*4+3]=1.0f/*aa*/;  

              positions[counter*3+0]=x*r;positions[counter*3+1]=y*r;positions[counter*3+2]=z*r;
              counter++;
              s += ds;
            }

            t -= dt;
          }
/* first sphere end */
/* second sphere generation */
        {
            drho = 3.141593F / 32.0f;
            dtheta = 6.283186F / 32.0f;
            ds = 1.0F / 32.0f;
            dt = 1.0F / 32.0f;
            t = 1.0F;
            for (int i = 0; i < 32; i++) {
                float rho = i * drho;

                float s = 0.0F;
                for (int j = 0; j <= 32; j++) {
                  float theta = j == 32 ? 0.0F : j * dtheta;
                  float x = (float) (-Math.sin(theta) * Math.sin(rho));
                  float y = (float) (Math.cos(theta) * Math.sin(rho));
                  float z = (float) (1.0f * Math.cos(rho));           
                 normals[counter*3+0]=x*1.0f;normals[counter*3+1]=y*1.0f;normals[counter*3+2]=z*1.0f;

                  colors[counter*4+0]=rr;colors[counter*4+1]=gg;colors[counter*4+2]=bb;colors[counter*4+3]=1.0f/*aa*/;  

                  positions[counter*3+0]=x*r+1.0f;positions[counter*3+1]=y*r+1.0f;positions[counter*3+2]=z*r+1.0f;
                  counter++;
                  x = (float) (-Math.sin(theta) * Math.sin(rho + drho));
                  y = (float) (Math.cos(theta) * Math.sin(rho + drho));
                  z = (float) (1.0f * Math.cos(rho + drho));

                  normals[counter*3+0]=x*1.0f;normals[counter*3+1]=y*1.0f;normals[counter*3+2]=z*1.0f;

                  colors[counter*4+0]=rr;colors[counter*4+1]=gg;colors[counter*4+2]=bb;colors[counter*4+3]=1.0f/*aa*/;  

                  positions[counter*3+0]=x*r+1.0f;positions[counter*3+1]=y*r+1.0f;positions[counter*3+2]=z*r+1.0f;
                  counter++;
                  s += ds;
                }

                t -= dt;
              }
        }
        /*second sphere end*/

        positionsBuf=BufferUtils.createFloatBuffer(c1 * (c2+1) * 3*2  *2);
        positionsBuf.put(positions);
        positionsBuf.rewind();
        colorsBuf=BufferUtils.createFloatBuffer(c1 * (c2+1) * 4*2  *2);
        colorsBuf.put(colors);
        colorsBuf.rewind();
        normalsBuf=BufferUtils.createFloatBuffer(c1 * (c2+1) * 3*2  *2);
        normalsBuf.put(normals);
        normalsBuf.rewind();

如您所见,下图显示了如何绘制两个球体。两者之间存在不必要的联系。

here

绳索很可能是由第一个球体的最后一个点和第二个球体的第一个点引起的。是否有某种分隔符/绘图提示在同一个缓冲区中分隔两个图形?

以下是它们的绘制方式:

         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,sphereBufferCol.get(0));
         GL11.glColorPointer(4, GL11.GL_FLOAT, 0, 0);
         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, sphereBufferPos.get(0));
         GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, sphereBufferNormal.get(0));
         GL11.glNormalPointer(GL11.GL_FLOAT, 0, 0);



         GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
         GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
         GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);

         //Each sphere is generated 32 by 32 quadstriparray and each having two sets of two points and there are two spheres 
         GL11.glDrawArrays(GL11.GL_QUAD_STRIP, 0, 32*33*2 *2);



         GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
         GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
         GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);

         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
         GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

问题:如何在不降低性能的情况下使绳状物消失?也许把零到最后和第一个点'的alpha值可以让它看不见但是不会因为屏幕上有很多行而导致每个球上有两个洞并降低性能?

所有顶点值都将被opencl互操作性改变,因此需要单个绘图调用来绘制整个10000+球。

1 个答案:

答案 0 :(得分:4)

似乎有很多选择:

如果您使用的是较新的硬件并想使用四条带,我更喜欢使用原始重启。

请注意,这只是快速评估和检查的结果(我个人不经常使用四条带甚至三条带)。)。