Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Triangle - Shade

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4

    Triangle - Shade

    Hello to everyone,

    Iím fighting with OpenGLES, with shaders and matrix. I need to display triangles and shade them according to a directional light.

    My code is the following.



    Code :
    public void OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl)
    {
    	gl.GlClear((int)GL10.GlColorBufferBit | GL10.GlDepthBufferBit);
     
    	// Draw the heightmap.
    	// Translate the heightmap into the screen.
    	Matrix.SetIdentityM(mModelMatrix, 0);
    	Matrix.TranslateM(mModelMatrix, 0, 0.0f, 0.0f, iZoomLevel);
     
    	// scaling
    	Matrix.SetIdentityM(mScaleMatrix, 0);
    	Matrix.ScaleM(mScaleMatrix, 0, scaleX, scaleY, scaleZ);
     
    	// Set a matrix that contains the current rotation.
    	Matrix.SetIdentityM(mCurrentRotation, 0);
    	Matrix.RotateM(mCurrentRotation, 0, mAngleX, 0.0f, 1.0f, 0.0f);
    	Matrix.RotateM(mCurrentRotation, 0, mAngleY, 1.0f, 0.0f, 0.0f);
    	mAngleX = 0.0f;
    	mAngleY = 0.0f;
     
    	// Multiply the current rotation by the accumulated rotation, and then
    	// set the accumulated rotation to the result.
    	Matrix.MultiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0);
    	System.Array.Copy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16);
     
    	Matrix.MultiplyMM(mTemporaryMatrix, 0, mScaleMatrix, 0, mAccumulatedRotation, 0);
    	System.Array.Copy(mTemporaryMatrix, 0, mScaleMatrix, 0, 16);
     
    	// Rotate the cube taking the overall rotation into account.
    	Matrix.MultiplyMM(mTemporaryMatrix, 0, mModelMatrix, 0, mScaleMatrix, 0); //mAccumulatedRotation, 0);
    	System.Array.Copy(mTemporaryMatrix, 0, mModelMatrix, 0, 16);
     
    	// This multiplies the view matrix by the model matrix, and stores
    	// the result in the MVP matrix
    	// (which currently contains model * view).
    	Matrix.MultiplyMM(mMVPMatrix, 0, mVMatrix, 0, mModelMatrix, 0);
     
    	Matrix.MultiplyMV(lightDirInEyeSpace, 0, mTemporaryMatrix, 0, lightDirInModelSpace, 0);
     
    	// This multiplies the modelview matrix by the projection matrix,
    	// and stores the result in the MVP matrix
    	// (which now contains model * view * projection).
    	Matrix.MultiplyMM(mTemporaryMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
    	System.Array.Copy(mTemporaryMatrix, 0, mMVPMatrix, 0, 16);
     
    	mTriangle1.Draw (mMVPMatrix, mVMatrix, lightDirInEyeSpace);
    	mTriangle2.Draw (mMVPMatrix, mVMatrix, lightDirInEyeSpace);
    }
     
    public void OnSurfaceCreated (Javax.Microedition.Khronos.Opengles.IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
    {
    	// Set the background clear color to black.
    	GLES20.GlClearColor(1.0f, 1.0f, 1.0f, 0.0f);
     
    	// Enable depth testing
    	GLES20.GlEnable(GLES20.GlDepthTest);
     
    	// Position the eye in front of the origin.
    	float eyeX = 0.0f;
    	float eyeY = 0.0f;
    	float eyeZ = -0.5f;
     
    	// We are looking toward the distance
    	float lookX = 0.0f;
    	float lookY = 0.0f;
    	float lookZ = -5.0f;
     
    	// Set our up vector. This is where our head would be pointing were we
    	// holding the camera.
    	float upX = 0.0f;
    	float upY = 1.0f;
    	float upZ = 0.0f;
     
    	// Set the view matrix. This matrix can be said to represent the camera
    	// position.
    	// NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination
    	// of a model and view matrix. In OpenGL 2, we can keep track of these
    	// matrices separately if we choose.
    	Matrix.SetLookAtM(mVMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
     
    	// Initialize the accumulated rotation matrix
    	Matrix.SetIdentityM(mAccumulatedRotation, 0);
     
    	mTriangle1 = new Triangle ();
    	mTriangle1.SetVerts(0f,0f,0, 0.5f,0.0f,0, 0.0f,0.5f,0);
    	mTriangle2 = new Triangle ();
    	mTriangle2.SetVerts(0f,0f,0, 0.0f, 0.5f,0.0f, 0f,0.0f,0.5f);
    }

    My triangle class:


    Code :
    class Triangle
    {
    	private FloatBuffer vertexBuffer;
    	private int mProgram;
    	private int mPositionHandle;
    	private int mColorHandle;
    	private int mMVPMatrixHandle;
    	private int mMVMatrixHandle;
    	private int mLightDirHandle;
    	private int mNormalHandle;
     
    	// number of coordinates per vertex in this array
    	static int COORDS_PER_VERTEX = 3;
    	float[] triangleCoords = new float [] { // in counterclockwise order:
    		-0.5f,  -0.5f, 0.0f,   // top
    		0.5f, -0.5f, 0.0f,   // bottom left
    		0.0f, 0.5f, 0.0f    // bottom right
    	};
    	private int vertexCount = 3; //triangleCoords.Length / COORDS_PER_VERTEX;
    	private int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
     
    	// Set color with red, green, blue and alpha (opacity) values
    	float[] color = new float[] { 
    		0.63671875f, 
    		0.76953125f, 
    		0.22265625f, 
    		1.0f };
     
    	public Triangle ()
    	{
    		// initialize vertex byte buffer for shape coordinates
    		// (number of coordinate values * 4 bytes per float)
    		ByteBuffer bb = ByteBuffer.AllocateDirect (	triangleCoords.Length * 4);
    		// use the device hardware's native byte order
    		bb.Order (ByteOrder.NativeOrder ());
     
    		// create a floating point buffer from the ByteBuffer
    		vertexBuffer = bb.AsFloatBuffer ();
    		// add the coordinates to the FloatBuffer
    		vertexBuffer.Put (triangleCoords);
    		// set the buffer to read the first coordinate
    		vertexBuffer.Position (0);
     
    		// prepare shaders and OpenGL program
    		int vertexShader = MyGLRenderer.LoadShader (GLES20.GlVertexShader,
    			vertexShaderCode);
    		int fragmentShader = MyGLRenderer.LoadShader (GLES20.GlFragmentShader,
    			fragmentShaderCode);
     
    		mProgram = GLES20.GlCreateProgram ();             // create empty OpenGL Program
    		GLES20.GlAttachShader (mProgram, vertexShader);   // add the vertex shader to program
    		GLES20.GlAttachShader (mProgram, fragmentShader); // add the fragment shader to program
    		GLES20.GlLinkProgram (mProgram);                  // create OpenGL program executables
    	}
     
    	public void SetVerts(float v0, float v1, float v2, float v3, float v4, float v5,
    		float v6, float v7, float v8)
    	{
    		triangleCoords[0] = v0;
    		triangleCoords[1] = v1;
    		triangleCoords[2] = v2;
    		triangleCoords[3] = v3;
    		triangleCoords[4] = v4;
    		triangleCoords[5] = v5;
    		triangleCoords[6] = v6;
    		triangleCoords[7] = v7;
    		triangleCoords[8] = v8;
     
    		vertexBuffer.Put(triangleCoords);
    		// set the buffer to read the first coordinate
    		vertexBuffer.Position(0);
    	}
     
    	public void Draw (float[] mvpMatrix, float[] mvMatrix, float[] lightDirInEyeSpace)
    	{
    		// Add program to OpenGL environment
    		GLES20.GlUseProgram (mProgram);
     
    		// get handle to vertex shader's vPosition member
    		mPositionHandle = GLES20.GlGetAttribLocation (mProgram, "vPosition");
     
    		// Enable a handle to the triangle vertices
    		GLES20.GlEnableVertexAttribArray (mPositionHandle);
    		// Prepare the triangle coordinate data
    		GLES20.GlVertexAttribPointer (mPositionHandle, COORDS_PER_VERTEX,
    			GLES20.GlFloat, false,
    			vertexStride, vertexBuffer);
     
    		// get handle to shape's transformation matrix
    		mMVPMatrixHandle = GLES20.GlGetUniformLocation (mProgram, "uMVPMatrix");
    		MyGLRenderer.CheckGlError ("glGetUniformLocation");
    		// Apply the projection and view transformation
    		GLES20.GlUniformMatrix4fv (mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    		MyGLRenderer.CheckGlError ("glUniformMatrix4fv");
     
    		//-
     
    		mMVMatrixHandle = GLES20.GlGetUniformLocation (mProgram, "u_MVMatrix");
    		MyGLRenderer.CheckGlError ("glGetUniformLocation");
    		// Apply the projection and view transformation
    		GLES20.GlUniformMatrix4fv(mMVMatrixHandle, 1, false, mvMatrix, 0);
    		MyGLRenderer.CheckGlError ("glUniformMatrix4fv");
     
    		// get handle to shape's transformation matrix
    		mLightDirHandle = GLES20.GlGetUniformLocation (mProgram, "u_LightDir");
    		MyGLRenderer.CheckGlError ("glGetUniformLocation");
     
    		// Apply the projection and view transformation
    		GLES20.GlUniform3f(mLightDirHandle, lightDirInEyeSpace[0], lightDirInEyeSpace[1], lightDirInEyeSpace[2] );
    		MyGLRenderer.CheckGlError ("GlUniform4f");
     
    		// get handle to normal
    		mNormalHandle = GLES20.GlGetUniformLocation (mProgram, "a_Normal");
    		MyGLRenderer.CheckGlError ("glGetUniformLocation");
     
    		// calc normal
    		float x = (triangleCoords[4] - triangleCoords[1]) * (triangleCoords[8] - triangleCoords[2]) - (triangleCoords[5] - triangleCoords[2]) * (triangleCoords[7] - triangleCoords[1]);
    		float y = (triangleCoords[5] - triangleCoords[2]) * (triangleCoords[6] - triangleCoords[0]) - (triangleCoords[3] - triangleCoords[0]) * (triangleCoords[8] - triangleCoords[2]);
    		float z = (triangleCoords[3] - triangleCoords[0]) * (triangleCoords[7] - triangleCoords[1]) - (triangleCoords[4] - triangleCoords[1]) * (triangleCoords[6] - triangleCoords[0]);
     
    		// Apply the projection and view transformation
    		GLES20.GlUniform3f(mNormalHandle, x, y, z );
    		MyGLRenderer.CheckGlError ("GlUniform3f");
     
    		//-
     
    		// Draw the triangle
    		GLES20.GlDrawArrays(GLES20.GlTriangles, 0, vertexCount);
    		//GLES20.GlDrawElements (GLES20.GlTriangles, drawOrder.Length,
    		//	GLES20.GlUnsignedShort, drawListBuffer);
     
    		// Disable vertex array
    		GLES20.GlDisableVertexAttribArray (mPositionHandle);
    	}

    My shaders are:

    Code :
    uniform mat4 uMVPMatrix;
    uniform mat4 u_MVMatrix;
    uniform vec3 u_LightDir;
     
    attribute vec4 vPosition;
    uniform vec4 a_Color; 
    uniform vec3 a_Normal;
     
    varying vec3 v_Color;
    vec3 materialColor; 
     
    void main()                    
    {                              
        materialColor = vec3(1,0,0);
        vec4 newNormal = u_MVMatrix * vec4(a_Normal, 0.0); 
        float lightIntensity = max(0.0, dot(newNormal.xyz, u_LightDir));
        v_Color = materialColor * lightIntensity; 
     
        gl_Position = uMVPMatrix * vPosition;
    }
     
     
    precision mediump float; 
     
    varying vec3 v_Color;          
     
    void main()                    
    {                              
       gl_FragColor = vec4(v_Color, 1.0); 
       gl_FragColor = v_Color; 
    };

    Triangles are not displayed with the right shading.

    Could you help me ? Thank you in advance.

    Keven Corazza

  2. #2
    Intern Newbie
    Join Date
    Jan 2014
    Posts
    40
    What output did you expect and what you've got instead?

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    I need a simple thing: I've some triangles that could represent a surface. I need to have a shading in order to understand the shape of the surface otherwise everything seems flat.

    In the example there are two triangles one on the plane formed by axis x-y and one on the plane formed by axis y-z.

    One triangle is everytime black, the other assume red gradation according to the rotation of the view but the result is not exactly the expected.

    I don't know if the problem is in vertex shader or if it caused by something else.

    I would like to attach an image but it seems no possible inthis forum.

    Thank you in advance.

    Keven Corazza



    Quote Originally Posted by nenad* View Post
    What output did you expect and what you've got instead?

  4. #4
    Intern Newbie
    Join Date
    Jan 2014
    Posts
    40
    Are your normals normalized?

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    I've just modified the shader in this way:

    Code :
    			+ " vec4 newNormal = u_MVMatrix * vec4(normalize(a_Normal), 0.0); \n"
    			+ " float lightIntensity = max(0.0, dot(newNormal.xyz, u_VectorToLight)); \n"
    			+ " v_Color = materialColor * lightIntensity; \n"

    Normals are now normalized. But the result doesn't change.

    Other ideas ? Matrixes are right ?

    Keven Corazza

  6. #6
    Intern Newbie
    Join Date
    Jan 2014
    Posts
    40
    Using a debugger might be a good idea.
    Otherwise, hard to tell at a glance without seeing the output.

  7. #7
    Intern Newbie
    Join Date
    Jan 2014
    Posts
    40
    Also, make sure that the light direction vector is normalized and that its w component is set to zero prior to multiplying it with matrices.

  8. #8
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    Do you know where I can find a simple example that do what I need ?

    I don't need textures or other complex things. Just view triangle surfaces.

    Thank you in advance.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •