聚光灯照亮纹理的基本问题

时间:2010-07-04 12:13:45

标签: opengl-es

任何人都可以帮我解决一个简单的问题吗?我已经从许多三角形(如20 * 20三角形)构建了一个正方形,我已将此正方形添加到纹理中,我也将法线设置为此正方形,因为它的位置在零Z坐标平面中,法线是很容易找到(0,0,1)。问题是我看不到我的纹理广场被一个点照亮了。我也试图去除环境光并减少它,但没有机会。此外,我增加了从正方形的小三角形的数量,以获得更好的分辨率,但没有运气。我搜索基本的例子,但没有运气。也有人找到了解决纹理上的斑点的问题,或者有人能给我一个小例子吗? 所以:

  1. 在表面创建中我已经把:
  2.    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
       gl.glClearColor(.5f, .5f, .5f, 1);
       gl.glShadeModel(GL10.GL_SMOOTH);
       gl.glEnable(GL10.GL_DEPTH_TEST);
       gl.glEnable(GL10.GL_TEXTURE_2D);
    
       float lightAmbient[] = new float[] { 0.3f, 0.3f, 0.3f, 1 };
       float lightDiffuse[] = new float[] { 0.7f, 0.7f, 0.7f, 1 };
       float lightSpecular[] = new float[] { 0.7f, 0.7f, 0.7f, 1 };
       lightDirection = new float[] {0.0f, 0.0f, -1.0f};
       lightPos = new float[] { 0, 0, 10f, 1 };
    
       gl.glEnable(GL10.GL_LIGHTING);
       gl.glEnable(GL10.GL_LIGHT0);
    
    
       gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);    
       gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);    
       gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightSpecular, 0);
       gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);   
       gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPOT_DIRECTION, lightDirection, 0);
       gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 3f);  
       gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_EXPONENT, 100f);
       gl.glEnable(GL10.GL_DEPTH_TEST);   
       gl.glDepthFunc(GL10.GL_LESS);
       gl.glDisable(GL10.GL_DITHER);
       gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
    
        int[] textures = new int[1];
        gl.glGenTextures(1, textures, 0);
        mTextureID = textures[0];
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
    
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                GL10.GL_LINEAR);
    
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                GL10.GL_CLAMP_TO_EDGE);
    
        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                GL10.GL_REPLACE);
    
        InputStream is = mContext.getResources()
                .openRawResource(R.raw.wood);
        Bitmap bitmap;
        try {
            bitmap = BitmapFactory.decodeStream(is);
        } finally {
            try {
                is.close();
            } catch(IOException e) {
                // Ignore.
            }
        }
    
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
        bitmap.recycle();
    
    1. 在onDrawFrame中,我添加了:     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

      gl.glMatrixMode(GL10.GL_MODELVIEW);
      gl.glLoadIdentity();
      
      GLU.gluLookAt(gl, 0, 0, 10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
      
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
      
      gl.glActiveTexture(GL10.GL_TEXTURE0);
      gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
      gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
              GL10.GL_REPEAT);
      gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
              GL10.GL_REPEAT);
      
      mSquare.draw(gl);
      
    2. Square类很简单:

    3. class Square {     int point = 1;

      int x1 = -2;
      int x2 = 2;
      int y1 = -2;
      int y2 = 2;
      int W = x2 - x1;
      int H = y2 - y1;
      int dx  = 30;
      int dy  = 30;
      
      
      private float vertices2[] = new float[3*4*dx * dy];
      private float normals[] = new float[3*4*dx * dy];
      
      float one = 1.0f;
      float texCoords[] = new float[3*4*dx * dy];
      
      private FloatBuffer vertexbuffer1 = null;
      private FloatBuffer mTextureBuffer = null;
      private FloatBuffer mNormalBuffer = null;
      
      private void initVertexes() {
          float incW = W/(float)dx;
          float incH = H/(float)dy;
          int i = 0;
          int j = 0;
          int k = 0;
      
          for(float y = y2; y >= (y1 + incH) ; y -= incH) 
              for(float x = x1; x<= (x2 - incW); x += incW) {
      
                  vertices2[i++] = x ;
                  vertices2[i++] = y - incH;
                  vertices2[i++] = -point;
      
                  texCoords[j++] = (x2 + x)/(4f*W);
                  texCoords[j++] = (y2 + y -incH)/(4f*H);
      
                  normals[k++] = 0;
                  normals[k++] = 0;
                  normals[k++] = 1;
      
                  vertices2[i++] = x ;
                  vertices2[i++] = y ;
                  vertices2[i++] = -point;
      
                  texCoords[j++] = (x2 + x)/(4f*W);
                  texCoords[j++] = (y2 + y)/(4f*H);
      
                  normals[k++] = 0;
                  normals[k++] = 0;
                  normals[k++] = 1;
      
                  vertices2[i++] = x + incW;
                  vertices2[i++] = y - incH ;
                  vertices2[i++] = -point;
      
                  texCoords[j++] = (x2 + x + incW)/(4f*W);
                  texCoords[j++] = (y2 + y - incH)/(4f*H);
      
                  normals[k++] = 0;
                  normals[k++] = 0;
                  normals[k++] = 1;
      
                  vertices2[i++] = x + incW;
                  vertices2[i++] = y ;
                  vertices2[i++] = -point;
      
                  texCoords[j++] = (x2 + x + incW)/(4f*W);
                  texCoords[j++] = (y2 + y)/(4f*H);
      
                  normals[k++] = 0;
                  normals[k++] = 0;
                  normals[k++] = 1;
              }
      
      }
      
      
      public Square() {
      
          initVertexes();
      
          ByteBuffer vbb1 = ByteBuffer.allocateDirect(vertices2.length * 4);
          vbb1.order(ByteOrder.nativeOrder());
          vertexbuffer1 = vbb1.asFloatBuffer();
          vertexbuffer1.put(vertices2);
          vertexbuffer1.position(0);
      
          ByteBuffer txtb1 = ByteBuffer.allocateDirect(texCoords.length * 4);
          txtb1.order(ByteOrder.nativeOrder());
          mTextureBuffer = txtb1.asFloatBuffer();
          mTextureBuffer.put(texCoords);
          mTextureBuffer.position(0);
      
          ByteBuffer nor = ByteBuffer.allocateDirect(normals.length * 4);
          nor.order(ByteOrder.nativeOrder());
          mNormalBuffer = nor.asFloatBuffer();
          mNormalBuffer.put(normals);
          mNormalBuffer.position(0);
      

      }

      public void draw(GL10 gl) {
      
          gl.glEnable(GL10.GL_TEXTURE_2D);
          gl.glNormalPointer(3, 0, mNormalBuffer);
          gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
          gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexbuffer1);
          gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 2*2*dx*dy);
      
      }
      

      }

1 个答案:

答案 0 :(得分:0)

如果您未设置GL_SPOT_CUTOFFGL_SPOT_EXPONENT,是否确认您的灯光照亮了广场?

从你定位光线和相机的方式来看,我想你正试图从观众的位置发出聚光灯。您需要注意的一件事是位置/方向照明参数(即GL_POSITIONGL_SPOT_DIRECTION)存储在眼睛空间中,这意味着它们由模型视图矩阵的值在您调用glLightfv的时间,并且存储了转换后的值,而不是您指定的值。在您绘制之前,您似乎没有设置模型视图矩阵,因此光可能不在您认为的位置。

尽管如此,如果你试图照亮聚光灯,你可能最好不要尝试使用其他纹理来应用聚光灯形状,而不是使用固定功能照明计算,这依赖于几何体的细分和不要给你足够的灵活性来定义你的高光的形状。您选择的截止值非常小,这可能会导致聚光灯完全错过顶点。