Basic problem with a texture illuminated by a spotlight
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:
- 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();
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_R开发者_如何学JAVAEPEAT); gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); mSquare.draw(gl);
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);
}
}
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.
精彩评论