tags:

views:

30

answers:

1

Hello, Can anyone help me with a simple problem? I’ve put a square built it from many triangles like 20*20 triangles, I’ve added to this square a texture, also I’ve set the normal to this square and since its positioned is in zero Z coordinate plane the normal is very easy to find (0,0,1). The problem is that I can’t see my textured square illuminated by a spot at all. I also tried to remove the ambient light and to reduce it but no chance. Also i increased the number of small triangles from the square for better resolution but no luck. I've search basic example but no luck. Also did some one found a solution to a spot over a texture, or can someone give me a small example ? So:

  1. In surfacecreated i've put:
   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. In onDrawFrame i've added: 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. The Square class is pretty straightforward:

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);

}

}

A: 

Have you verified that your light illuminates the square when you don’t set GL_SPOT_CUTOFF and GL_SPOT_EXPONENT?

From the way you’ve positioned your light and the camera, I imagine that you’re trying to shine a spotlight from the position of the viewer. One thing that you need to watch out for is that positional/directional lighting parameters (i.e. GL_POSITION and GL_SPOT_DIRECTION) are stored in eye space, which means that they are transformed by the value of the modelview matrix at the time you call glLightfv, and that transformed value is stored, not the one you specified. It looks like you don’t set up the modelview matrix until you draw, so the light may not be where you think it is.

Still, if you’re trying to shine a spotlight, you’re probably better off trying to apply the spotlight shape using another texture, rather than by using fixed-function lighting calculations, which rely on the tessellation of your geometry and don’t give you as much flexibility to define the shape of your highlight. The cutoff you’ve chosen is pretty small, which can potentially cause the spotlight to miss your vertices entirely.

Pivot
Thx for your tips. I simplified the problem and this time i tried to spotlight a square without texture only colorized. I think here i have the problem. I don't have a spotlight at all. I disable the GL_SPOT_CUTOFF and exponent and still the same situation. Can you clarify me please what did you want to say by "... are stored in eye space, which means that they are transformed by the value of the modelview matrix at the time you call glLightfv..." . ? Anyway many thx for your reply !
EddieS
OpenGL ES lights a vertex after transforming it by the modelview matrix (but before applying the projection matrix). Light positions/directions need to be in the same coordinate space, but multiplying by the modelview matrix is done once when you call glLightfv, rather than every time the light is used. Have you tried setting up the modelview matrix the same way as you do for drawing before you call glLightfv?You may find sections 8, 9, and 18 of the OpenGL FAQ (http://www.opengl.org/resources/faq/technical/) useful for understanding how all these transformations work.
Pivot
Thanks Pivot !!
EddieS