I follow the OpenGL ES 2.0 tutorial and combine it with the GLSL lighting tutorial I found using Utah's handy tea pot from developer.apple.com.
After many exercises and experiments, I have a kettle drawn moderately correctly on the screen, rotating around all three axes with “tone shading” from the working light. As a result, because of me, several failures in the geometry simply draw the entire list of vertices in the form of triangular stripes (if you look in the teapot.h file, there is "-1" where I should start new triangular stripes, but this is only test data and not related to my problem).
I'm a little confused about how to position the light in the scene. In my Objective-C code, I have a float 3 vector that contains {0,1,0} and passes this to the shader to then calculate the light intensity.
Why does light also appear on stage? I mean, the light acts as if it is attached to the teapot with an invisible stick, always pointing to the same side, regardless of the direction the teapot is in.
This is the vertex shader.
attribute vec4 Position; attribute vec4 SourceColor; attribute vec3 Normal; uniform mat4 Projection; uniform mat4 Modelview; varying vec3 normal; void main(void) { normal = Normal; gl_Position = Projection * Modelview * Position; }
The "position" is set by the Obj-C code and is the vertex for the object, "Normal" is a list of normals from both the vertex array (VBO), "Projection", and "Modelview", calculated as follows:
(A CC3GLMatrix from the Cocos3D library mentioned in the GLES tutorial above)
CC3GLMatrix *projection = [CC3GLMatrix matrix]; float h = 4.0f * self.frame.size.height / self.frame.size.width; [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:1 andFar:100]; glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); CC3GLMatrix *modelView = [CC3GLMatrix matrix]; [modelView populateFromTranslation:CC3VectorMake(0, 0, -7)]; [modelView scaleBy:CC3VectorMake(30, 30, 30)]; _currentRotation += displayLink.duration * 90; [modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, _currentRotation)]; glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
And I set the light in the scene by doing
float lightDir[] = {1,0,1}; glUniform3fv(_lightDirUniform, 1, lightDir);
The fragment shader is as follows
varying lowp vec4 DestinationColor; // 1 varying highp vec3 normal; uniform highp vec3 LightDir; void main(void) { highp float intensity; highp vec4 color; intensity = dot(LightDir,normal); if (intensity > 0.95) color = vec4(1.0,0.5,0.5,1.0); else if (intensity > 0.5) color = vec4(0.6,0.3,0.3,1.0); else if (intensity > 0.25) color = vec4(0.4,0.2,0.2,1.0); else color = vec4(0.2,0.1,0.1,1.0); gl_FragColor = color; }
When trying to deal with this, I come across code that refers to (not existing in GLES) gl_LightSource and gl_NormalMatrix, but I don’t know what to put in equivalents. I need to transfer shaders from my code, Links to "space for space", "outer space", etc. Confused, I know that I probably should convert things between them, but I don’t understand why and how (and where - in the code or in the shader?)
In each frame, do I need to change the light source? The code I have for customization seems too simplistic. I really don’t touch the kettle, I, instead, am I moving the whole scene - the light and everything around?