【问题标题】:OpenGL: two spheres in single vertex bufferOpenGL:单个顶点缓冲区中的两个球体
【发布时间】:2013-08-26 17:01:06
【问题描述】:

(问题在底部)我正在学习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();

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

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

这是它们的绘制方式:

         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 多个球体。

【问题讨论】:

  • 是你贴在GLU方法上面的代码还是你自己的代码?我没有看到对Sphere() 的呼叫。
  • 我从 GLU.Sphere() 复制了代码并更改了内容以适合我的缓冲区生成方法,因此创建单个球体没有任何问题。

标签: java opengl lwjgl vbo


【解决方案1】:

似乎有很多选择:

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

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

【讨论】:

  • 好的,我现在正在阅读原始重启。设备是HD7870。
  • 因为我没有使用元素数组(还不知道如何使用)我正在寻找 glMultiDrawArrays 但找不到。为此需要哪个版本的 opengl?
  • 可能缺少实例渲染;)
  • 将四边形更改为四边形需要额外的坐标,会变慢吗?
  • @huseyintugrulbuyukisik 它“更慢”,因为当没有共享顶点时,您无法从 T&L 后缓存中受益。换句话说,顶点着色器必须单独计算每个顶点,并且不能重用先前相同顶点的结果。这就是索引渲染和/或条形/扇形图元有助于提高性能的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多