Exemple #1
0
        public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            const float coord = 1.0f;

            // Cube coords
            // X, Y, Z = 1 vertex * 3 = 1 face * 12 = 1 cube
            float[] triangleVerticesData =
            {
                -coord, -coord, -coord,
                -coord, -coord, coord,
                -coord, coord,  coord,

                coord,  coord,  -coord,
                -coord, -coord, -coord,
                -coord, coord,  -coord,

                coord,  -coord, coord,
                -coord, -coord, -coord,
                coord,  -coord, -coord,

                coord,  coord,  -coord,
                coord,  -coord, -coord,
                -coord, -coord, -coord,

                -coord, -coord, -coord,
                -coord, coord,  coord,
                -coord, coord,  -coord,

                coord,  -coord, coord,
                -coord, -coord, coord,
                -coord, -coord, -coord,

                -coord, coord,  coord,
                -coord, -coord, coord,
                coord,  -coord, coord,

                coord,  coord,  coord,
                coord,  -coord, -coord,
                coord,  coord,  -coord,

                coord,  -coord, -coord,
                coord,  coord,  coord,
                coord,  -coord, coord,

                coord,  coord,  coord,
                coord,  coord,  -coord,
                -coord, coord,  -coord,

                coord,  coord,  coord,
                -coord, coord,  -coord,
                -coord, coord,  coord,

                coord,  coord,  coord,
                -coord, coord,  coord,
                coord,  -coord, coord
            };

            FloatBuffer mTriangleVertices = ByteBuffer.AllocateDirect(triangleVerticesData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleVertices.Put(triangleVerticesData).Flip();

            // Cube colors
            // R, G, B, A
            float[] triangleColorsData =
            {
                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f
            };

            FloatBuffer mTriangleColors = ByteBuffer.AllocateDirect(triangleColorsData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleColors.Put(triangleColorsData).Flip();

            //Cube texture UV Map
            float[] triangleTextureUVMapData =
            {
                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f,

                0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 0.0f
            };

            FloatBuffer mTriangleTextureUVMap = ByteBuffer.AllocateDirect(triangleTextureUVMapData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleTextureUVMap.Put(triangleTextureUVMapData).Flip();

            //triagles normals
            //This normal array is not right, it is spacialy DO FOR demonstrate how normals work with faces when light is calculated at shader program
            float[] triangleNormalData =
            {
                // Front face
                0.0f,   0.0f,  1.0f,
                0.0f,   0.0f,  1.0f,
                0.0f,   0.0f,  1.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,

                // Right face
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,
                1.0f,   0.0f,  0.0f,

                // Back face
                0.0f,   0.0f, -1.0f,
                0.0f,   0.0f, -1.0f,
                0.0f,   0.0f, -1.0f,
                0.0f,   0.0f, -1.0f,
                0.0f,   0.0f, -1.0f,
                0.0f,   0.0f, -1.0f,

                // Left face
                -1.0f,  0.0f,  0.0f,
                -1.0f,  0.0f,  0.0f,
                -1.0f,  0.0f,  0.0f,
                -1.0f,  0.0f,  0.0f,
                -1.0f,  0.0f,  0.0f,
                -1.0f,  0.0f,  0.0f,

                // Top face
                0.0f,   1.0f,  0.0f,
                0.0f,   1.0f,  0.0f,
                0.0f,   1.0f,  0.0f,
                0.0f,   1.0f,  0.0f,
                0.0f,   1.0f,  0.0f,
                0.0f,   1.0f,  0.0f,

                // Bottom face
                0.0f,  -1.0f,  0.0f,
                0.0f,  -1.0f,  0.0f,
                0.0f,  -1.0f,  0.0f,
                0.0f,  -1.0f,  0.0f,
                0.0f,  -1.0f,  0.0f,
                0.0f,  -1.0f, 0.0f
            };

            FloatBuffer mTriangleNormal = ByteBuffer.AllocateDirect(triangleNormalData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleNormal.Put(triangleNormalData).Flip();

            //Data buffers to VBO
            GLES20.GlGenBuffers(4, VBOBuffers, 0); //2 buffers for vertices, texture and colors

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleVertices.Capacity() * mBytesPerFloat, mTriangleVertices, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[1]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleColors.Capacity() * mBytesPerFloat, mTriangleColors, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[2]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleTextureUVMap.Capacity() * mBytesPerFloat, mTriangleTextureUVMap, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[3]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleNormal.Capacity() * mBytesPerFloat, mTriangleNormal, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            //Load and setup texture

            GLES20.GlGenTextures(1, textureHandle, 0); //init 1 texture storage handle
            if (textureHandle[0] != 0)
            {
                //Android.Graphics cose class Matrix exists at both Android.Graphics and Android.OpenGL and this is only sample of using
                Android.Graphics.BitmapFactory.Options options = new Android.Graphics.BitmapFactory.Options();
                options.InScaled = false; // No pre-scaling
                Android.Graphics.Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.texture1, options);
                GLES20.GlBindTexture(GLES20.GlTexture2d, textureHandle[0]);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlNearest);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlNearest);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
                GLUtils.TexImage2D(GLES20.GlTexture2d, 0, bitmap, 0);
                bitmap.Recycle();
            }

            //Ask android to run RAM garbage cleaner
            System.GC.Collect();

            //Setup OpenGL ES
            GLES20.GlClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            // GLES20.GlEnable(GLES20.GlDepthTest); //uncoment if needs enabled dpeth test
            GLES20.GlEnable(2884); // GlCullFace == 2884 see OpenGL documentation to this constant value
            GLES20.GlCullFace(GLES20.GlBack);


            // Position the eye behind the origin.
            float eyeX = 0.0f;
            float eyeY = 0.0f;
            float eyeZ = 4.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 = coord;
            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(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);

            //all "attribute" variables is "triagles" VBO (arrays) items representation
            //a_Possition[0] <=> a_Color[0] <=> a_TextureCoord[0] <=> a_Normal[0]
            //a_Possition[1] <=> a_Color[1] <=> a_TextureCoord[1] <=> a_Normal[1]
            //...
            //a_Possition[n] <=> a_Color[n] <=> a_TextureCoord[n] <=> a_Normal[n] -- where "n" is object buffers length
            //-> HOW MANY faces in your object (model) in VBO -> how many times the vertex shader will be called by OpenGL
            string vertexShader =
                "uniform mat4 u_MVPMatrix;      \n"         // A constant representing the combined model/view/projection matrix.
                + "uniform vec3 u_LightPos;       \n"       // A constant representing the light source position
                + "attribute vec4 a_Position;     \n"       // Per-vertex position information we will pass in. (it means vec4[x,y,z,w] but we put only x,y,z at this sample
                + "attribute vec4 a_Color;        \n"       // Per-vertex color information we will pass in.
                + "varying vec4 v_Color;          \n"       // This will be passed into the fragment shader.
                + "attribute vec2 a_TextureCoord; \n"       // Per-vertex texture UVMap information we will pass in.
                + "varying vec2 v_TextureCoord;   \n"       // This will be passed into the fragment shader.
                + "attribute vec3 a_Normal;       \n"       // Per-vertex normals information we will pass in.
                + "void main()                    \n"       // The entry point for our vertex shader.
                + "{                              \n"
                //light calculation section for fragment shader
                + "   vec3 modelViewVertex = vec3(u_MVPMatrix * a_Position);\n"
                + "   vec3 modelViewNormal = vec3(u_MVPMatrix * vec4(a_Normal, 0.0));\n"
                + "   float distance = length(u_LightPos - modelViewVertex);\n"
                + "   vec3 lightVector = normalize(u_LightPos - modelViewVertex);\n"
                + "   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);\n"
                + "   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));\n"
                + "   v_Color = a_Color * vec4(diffuse);\n" //Pass the color with light aspect to fragment shader
                + "   v_TextureCoord = a_TextureCoord; \n"  // Pass the texture coordinate through to the fragment shader. It will be interpolated across the triangle.
                + "   gl_Position = u_MVPMatrix   \n"       // gl_Position is a special variable used to store the final position.
                + "                 * a_Position; \n"       // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
                + "}                              \n";

            string fragmentShader =
                "precision mediump float;       \n"                                       // Set the default precision to medium. We don't need as high of a
                                                                                          // precision in the fragment shader.
                + "varying vec4 v_Color;          \n"                                     // This is the color from the vertex shader interpolated across the triangle per fragment.
                + "varying vec2 v_TextureCoord;   \n"                                     // This is the texture coordinate from the vertex shader interpolated across the triangle per fragment.
                + "uniform sampler2D u_Texture;   \n"                                     // This is the texture image handler
                + "void main()                    \n"                                     // The entry point for our fragment shader.
                + "{                              \n"
                + "   gl_FragColor = texture2D(u_Texture, v_TextureCoord) * v_Color;  \n" // Pass the color directly through the pipeline.
                + "}                              \n";

            int vertexShaderHandle = GLES20.GlCreateShader(GLES20.GlVertexShader);

            if (vertexShaderHandle != 0)
            {
                // Pass in the shader source.
                GLES20.GlShaderSource(vertexShaderHandle, vertexShader);

                // Compile the shader.
                GLES20.GlCompileShader(vertexShaderHandle);

                // Get the compilation status.
                int[] compileStatus = new int[1];
                GLES20.GlGetShaderiv(vertexShaderHandle, GLES20.GlCompileStatus, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0)
                {
                    GLES20.GlDeleteShader(vertexShaderHandle);
                    vertexShaderHandle = 0;
                }
            }

            if (vertexShaderHandle == 0)
            {
                throw new Exception("Error creating vertex shader.");
            }

            // Load in the fragment shader shader.
            int fragmentShaderHandle = GLES20.GlCreateShader(GLES20.GlFragmentShader);

            if (fragmentShaderHandle != 0)
            {
                // Pass in the shader source.
                GLES20.GlShaderSource(fragmentShaderHandle, fragmentShader);

                // Compile the shader.
                GLES20.GlCompileShader(fragmentShaderHandle);

                // Get the compilation status.
                int[] compileStatus = new int[1];
                GLES20.GlGetShaderiv(fragmentShaderHandle, GLES20.GlCompileStatus, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0)
                {
                    GLES20.GlDeleteShader(fragmentShaderHandle);
                    fragmentShaderHandle = 0;
                }
            }

            if (fragmentShaderHandle == 0)
            {
                throw new Exception("Error creating fragment shader.");
            }

            // Create a program object and store the handle to it.
            int programHandle = GLES20.GlCreateProgram();

            if (programHandle != 0)
            {
                // Bind the vertex shader to the program.
                GLES20.GlAttachShader(programHandle, vertexShaderHandle);

                // Bind the fragment shader to the program.
                GLES20.GlAttachShader(programHandle, fragmentShaderHandle);

                // Bind attributes
                GLES20.GlBindAttribLocation(programHandle, 0, "a_Position");
                GLES20.GlBindAttribLocation(programHandle, 1, "a_Color");
                GLES20.GlBindAttribLocation(programHandle, 2, "a_TextureCoord");
                GLES20.GlBindAttribLocation(programHandle, 3, "a_Normal");

                // Link the two shaders together into a program.
                GLES20.GlLinkProgram(programHandle);

                // Get the link status.
                int[] linkStatus = new int[1];
                GLES20.GlGetProgramiv(programHandle, GLES20.GlLinkStatus, linkStatus, 0);

                // If the link failed, delete the program.
                if (linkStatus[0] == 0)
                {
                    GLES20.GlDeleteProgram(programHandle);
                    programHandle = 0;
                }
            }

            if (programHandle == 0)
            {
                throw new Exception("Error creating program.");
            }

            // Set program handles. These will later be used to pass in values to the program.
            mMVPMatrixHandle    = GLES20.GlGetUniformLocation(programHandle, "u_MVPMatrix");
            mLightPos           = GLES20.GlGetUniformLocation(programHandle, "u_LightPos");
            mPositionHandle     = GLES20.GlGetAttribLocation(programHandle, "a_Position");
            mColorHandle        = GLES20.GlGetAttribLocation(programHandle, "a_Color");
            mTextureCoordHandle = GLES20.GlGetAttribLocation(programHandle, "a_TextureCoord");
            mNormalHandle       = GLES20.GlGetAttribLocation(programHandle, "a_Normal");
            mTextureHandle      = GLES20.GlGetUniformLocation(programHandle, "u_Texture");


            // Tell OpenGL to use this program when rendering.
            GLES20.GlUseProgram(programHandle);
        }
        /// <summary>
        /// Draws the model.
        /// </summary>
        /// <param name="cameraView">A 4x4 view matrix, in column-major order.</param>
        /// <param name="cameraPerspective">A 4x4 projection matrix, in column-major order.</param>
        /// <param name="lightIntensity">Illumination intensity.  Combined with diffuse and specular material properties.</param>
        /// <seealso cref="BlendMode"/>
        /// <seealso cref="UpdateModelMatrix(float[], float)"/>
        /// <seealso cref="SetMaterialProperties(float, float, float, float)"/>
        /// <seealso cref="Android.Opengl.Matrix"/>
        public void Draw(float[] cameraView, float[] cameraPerspective, float lightIntensity)
        {
            ShaderUtil.CheckGLError(TAG, "Before draw");

            // Build the ModelView and ModelViewProjection matrices
            // for calculating object position and light.
            Android.Opengl.Matrix.MultiplyMM(mModelViewMatrix, 0, cameraView, 0, mModelMatrix, 0);
            Android.Opengl.Matrix.MultiplyMM(mModelViewProjectionMatrix, 0, cameraPerspective, 0, mModelViewMatrix, 0);

            GLES20.GlUseProgram(mProgram);

            // Set the lighting environment properties.
            Android.Opengl.Matrix.MultiplyMV(mViewLightDirection, 0, mModelViewMatrix, 0, LIGHT_DIRECTION, 0);
            NormalizeVec3(mViewLightDirection);
            GLES20.GlUniform4f(mLightingParametersUniform,
                               mViewLightDirection[0], mViewLightDirection[1], mViewLightDirection[2], lightIntensity);

            // Set the object material properties.
            GLES20.GlUniform4f(mMaterialParametersUniform, mAmbient, mDiffuse, mSpecular,
                               mSpecularPower);

            // Attach the object texture.
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]);
            GLES20.GlUniform1i(mTextureUniform, 0);

            // Set the vertex attributes.
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId);

            GLES20.GlVertexAttribPointer(
                mPositionAttribute, COORDS_PER_VERTEX, GLES20.GlFloat, false, 0, mVerticesBaseAddress);
            GLES20.GlVertexAttribPointer(
                mNormalAttribute, 3, GLES20.GlFloat, false, 0, mNormalsBaseAddress);
            GLES20.GlVertexAttribPointer(
                mTexCoordAttribute, 2, GLES20.GlFloat, false, 0, mTexCoordsBaseAddress);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            // Set the ModelViewProjection matrix in the shader.
            GLES20.GlUniformMatrix4fv(
                mModelViewUniform, 1, false, mModelViewMatrix, 0);
            GLES20.GlUniformMatrix4fv(
                mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrix, 0);

            // Enable vertex arrays
            GLES20.GlEnableVertexAttribArray(mPositionAttribute);
            GLES20.GlEnableVertexAttribArray(mNormalAttribute);
            GLES20.GlEnableVertexAttribArray(mTexCoordAttribute);

            if (BlendMode != BlendMode.None)
            {
                GLES20.GlDepthMask(false);
                GLES20.GlEnable(GLES20.GlBlend);
                switch (BlendMode)
                {
                case BlendMode.Shadow:
                    // Multiplicative blending function for Shadow.
                    GLES20.GlBlendFunc(GLES20.GlZero, GLES20.GlOneMinusSrcAlpha);
                    break;

                case BlendMode.Grid:
                    // Grid, additive blending function.
                    GLES20.GlBlendFunc(GLES20.GlSrcAlpha, GLES20.GlOneMinusSrcAlpha);
                    break;
                }
            }

            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId);
            GLES20.GlDrawElements(GLES20.GlTriangles, mIndexCount, GLES20.GlUnsignedShort, 0);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);

            if (BlendMode != BlendMode.None)
            {
                GLES20.GlDisable(GLES20.GlBlend);
                GLES20.GlDepthMask(true);
            }

            // Disable vertex arrays
            GLES20.GlDisableVertexAttribArray(mPositionAttribute);
            GLES20.GlDisableVertexAttribArray(mNormalAttribute);
            GLES20.GlDisableVertexAttribArray(mTexCoordAttribute);

            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);

            ShaderUtil.CheckGLError(TAG, "After draw");
        }
        /// <summary>
        /// Creates and initializes OpenGL resources needed for rendering the model.
        /// </summary>
        /// <param name="context">Context for loading the shader and below-named model and texture assets.</param>
        /// <param name="objAssetName">Name of the OBJ file containing the model geometry.</param>
        /// <param name="diffuseTextureAssetName">Name of the PNG file containing the diffuse texture map.</param>
        public void CreateOnGlThread(Context context, string objAssetName,
                                     string diffuseTextureAssetName)
        {
            // Read the texture.
            Bitmap textureBitmap = BitmapFactory.DecodeStream(
                context.Assets.Open(diffuseTextureAssetName));

            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlGenTextures(mTextures.Length, mTextures, 0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]);

            GLES20.GlTexParameteri(GLES20.GlTexture2d,
                                   GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear);
            GLES20.GlTexParameteri(GLES20.GlTexture2d,
                                   GLES20.GlTextureMagFilter, GLES20.GlLinear);
            GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0);
            GLES20.GlGenerateMipmap(GLES20.GlTexture2d);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);

            textureBitmap.Recycle();

            ShaderUtil.CheckGLError(TAG, "Texture loading");

            // Read the obj file.
            var  objInputStream = context.Assets.Open(objAssetName);
            IObj obj            = ObjReader.Read(objInputStream);

            // Prepare the Obj so that its structure is suitable for
            // rendering with OpenGL:
            // 1. Triangulate it
            // 2. Make sure that texture coordinates are not ambiguous
            // 3. Make sure that normals are not ambiguous
            // 4. Convert it to single-indexed data
            obj = ObjUtils.ConvertToRenderable(obj);

            // OpenGL does not use Java arrays. ByteBuffers are used instead to provide data in a format
            // that OpenGL understands.

            // Obtain the data from the OBJ, as direct buffers:
            IntBuffer   wideIndices = ObjData.GetFaceVertexIndices(obj, 3);
            FloatBuffer vertices    = ObjData.GetVertices(obj);
            FloatBuffer texCoords   = ObjData.GetTexCoords(obj, 2);
            FloatBuffer normals     = ObjData.GetNormals(obj);

            // Convert int indices to shorts for GL ES 2.0 compatibility
            ShortBuffer indices = ByteBuffer.AllocateDirect(2 * wideIndices.Limit())
                                  .Order(ByteOrder.NativeOrder()).AsShortBuffer();

            while (wideIndices.HasRemaining)
            {
                indices.Put((short)wideIndices.Get());
            }
            indices.Rewind();

            int[] buffers = new int[2];
            GLES20.GlGenBuffers(2, buffers, 0);
            mVertexBufferId = buffers[0];
            mIndexBufferId  = buffers[1];

            // Load vertex buffer
            mVerticesBaseAddress  = 0;
            mTexCoordsBaseAddress = mVerticesBaseAddress + 4 * vertices.Limit();
            mNormalsBaseAddress   = mTexCoordsBaseAddress + 4 * texCoords.Limit();
            int totalBytes = mNormalsBaseAddress + 4 * normals.Limit();

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, totalBytes, null, GLES20.GlStaticDraw);
            GLES20.GlBufferSubData(
                GLES20.GlArrayBuffer, mVerticesBaseAddress, 4 * vertices.Limit(), vertices);
            GLES20.GlBufferSubData(
                GLES20.GlArrayBuffer, mTexCoordsBaseAddress, 4 * texCoords.Limit(), texCoords);
            GLES20.GlBufferSubData(
                GLES20.GlArrayBuffer, mNormalsBaseAddress, 4 * normals.Limit(), normals);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            // Load index buffer
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId);
            mIndexCount = indices.Limit();
            GLES20.GlBufferData(
                GLES20.GlElementArrayBuffer, 2 * mIndexCount, indices, GLES20.GlStaticDraw);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);

            ShaderUtil.CheckGLError(TAG, "OBJ buffer load");

            int vertexShader = ShaderUtil.LoadGLShader(TAG, context,
                                                       GLES20.GlVertexShader, Resource.Raw.object_vertex);
            int fragmentShader = ShaderUtil.LoadGLShader(TAG, context,
                                                         GLES20.GlFragmentShader, Resource.Raw.object_fragment);

            mProgram = GLES20.GlCreateProgram();
            GLES20.GlAttachShader(mProgram, vertexShader);
            GLES20.GlAttachShader(mProgram, fragmentShader);
            GLES20.GlLinkProgram(mProgram);
            GLES20.GlUseProgram(mProgram);

            ShaderUtil.CheckGLError(TAG, "Program creation");

            mModelViewUniform           = GLES20.GlGetUniformLocation(mProgram, "u_ModelView");
            mModelViewProjectionUniform =
                GLES20.GlGetUniformLocation(mProgram, "u_ModelViewProjection");

            mPositionAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Position");
            mNormalAttribute   = GLES20.GlGetAttribLocation(mProgram, "a_Normal");
            mTexCoordAttribute = GLES20.GlGetAttribLocation(mProgram, "a_TexCoord");

            mTextureUniform = GLES20.GlGetUniformLocation(mProgram, "u_Texture");

            mLightingParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_LightingParameters");
            mMaterialParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_MaterialParameters");

            ShaderUtil.CheckGLError(TAG, "Program parameters");

            Android.Opengl.Matrix.SetIdentityM(mModelMatrix, 0);
        }
Exemple #4
0
 public void bindTexture()
 {
     GLES20.GlBindTexture(GLES20.GlTexture2d, RBOC);
 }
        /// <summary>
        /// Draw the planes
        /// </summary>
        public void DrawPlanes(IEnumerable <Plane> allPlanes, Pose cameraPose, float[] cameraPerspective)
        {
            // Planes must be sorted by distance from camera so that we draw closer planes first, and
            // they occlude the farther planes.
            List <SortablePlane> sortedPlanes = new List <SortablePlane>();

            float[] normal  = new float[3];
            float   cameraX = cameraPose.Tx();
            float   cameraY = cameraPose.Ty();
            float   cameraZ = cameraPose.Tz();

            foreach (var plane in allPlanes)
            {
                if (plane.GetType() != Plane.Type.HorizontalUpwardFacing ||
                    plane.TrackingState != TrackingState.Tracking)
                {
                    continue;
                }

                var center = plane.CenterPose;

                // Get transformed Y axis of plane's coordinate system.
                center.GetTransformedAxis(1, 1.0f, normal, 0);

                // Compute dot product of plane's normal with vector from camera to plane center.
                float distance = (cameraX - center.Tx()) * normal[0] +
                                 (cameraY - center.Ty()) * normal[1] + (cameraZ - center.Tz()) * normal[2];
                if (distance < 0)
                {  // Plane is back-facing.
                    continue;
                }
                sortedPlanes.Add(new SortablePlane(distance, plane));
            }

            sortedPlanes.Sort((x, y) => x.Distance.CompareTo(y.Distance));

            var cameraView = new float[16];

            cameraPose.Inverse().ToMatrix(cameraView, 0);

            // Planes are drawn with additive blending, masked by the alpha channel for occlusion.

            // Start by clearing the alpha channel of the color buffer to 1.0.
            GLES20.GlClearColor(1, 1, 1, 1);
            GLES20.GlColorMask(false, false, false, true);
            GLES20.GlClear(GLES20.GlColorBufferBit);
            GLES20.GlColorMask(true, true, true, true);

            // Disable depth write.
            GLES20.GlDepthMask(false);

            // Additive blending, masked by alpha chanel, clearing alpha channel.
            GLES20.GlEnable(GLES20.GlBlend);
            GLES20.GlBlendFuncSeparate(
                GLES20.GlDstAlpha, GLES20.GlOne,            // RGB (src, dest)
                GLES20.GlZero, GLES20.GlOneMinusSrcAlpha);  // ALPHA (src, dest)

            // Set up the shader.
            GLES20.GlUseProgram(mPlaneProgram);

            // Attach the texture.
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]);
            GLES20.GlUniform1i(mTextureUniform, 0);

            // Shared fragment uniforms.
            GLES20.GlUniform4fv(mGridControlUniform, 1, GRID_CONTROL, 0);

            // Enable vertex arrays
            GLES20.GlEnableVertexAttribArray(mPlaneXZPositionAlphaAttribute);

            foreach (var sortedPlane in sortedPlanes)
            {
                var plane       = sortedPlane.Plane;
                var planeMatrix = new float[16];
                plane.CenterPose.ToMatrix(planeMatrix, 0);

                UpdatePlaneParameters(planeMatrix, plane.ExtentX,
                                      plane.ExtentZ, plane.Polygon);

                // Get plane index. Keep a map to assign same indices to same planes.

                var planeIndex = -1;
                if (!mPlaneIndexMap.TryGetValue(plane, out planeIndex))
                {
                    planeIndex = Java.Lang.Integer.ValueOf(mPlaneIndexMap.Count).IntValue();
                    mPlaneIndexMap.Add(plane, planeIndex);
                }

                // Set plane color. Computed deterministically from the Plane index.
                var colorIndex = 0; //planeIndex % PLANE_COLORS_RGBA.Length;

                ColorRgbaToFloat(mPlaneColor, PLANE_COLORS_RGBA[colorIndex]);
                GLES20.GlUniform4fv(mLineColorUniform, 1, mPlaneColor, 0);
                GLES20.GlUniform4fv(mDotColorUniform, 1, mPlaneColor, 0);

                // Each plane will have its own angle offset from others, to make them easier to
                // distinguish. Compute a 2x2 rotation matrix from the angle.
                var angleRadians = 0;
                var uScale       = DOTS_PER_METER;
                var vScale       = DOTS_PER_METER * EQUILATERAL_TRIANGLE_SCALE;
                mPlaneAngleUvMatrix[0] = +(float)Math.Cos(angleRadians) * uScale;
                mPlaneAngleUvMatrix[1] = -(float)Math.Sin(angleRadians) * uScale;
                mPlaneAngleUvMatrix[2] = +(float)Math.Sin(angleRadians) * vScale;
                mPlaneAngleUvMatrix[3] = +(float)Math.Cos(angleRadians) * vScale;
                GLES20.GlUniformMatrix2fv(mPlaneUvMatrixUniform, 1, false, mPlaneAngleUvMatrix, 0);
                Draw(cameraView, cameraPerspective);
            }

            // Clean up the state we set
            GLES20.GlDisableVertexAttribArray(mPlaneXZPositionAlphaAttribute);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            GLES20.GlDisable(GLES20.GlBlend);
            GLES20.GlDepthMask(true);
        }
Exemple #6
0
        private void drawOneMaterial(GLSL glsl, ShellSurface surface, RenderList mat)
        {
            // set motion
            if (surface.Animation)
            {
                if (mat.bone_inv_map == null)
                {
                    for (int j = 0; j < surface.RenderBones.Count; j++)
                    {
                        var b = surface.RenderBones[j];
                        if (b != null)
                        {
                            Array.Copy(b.matrix, 0, mBoneMatrix, j * 16, 16);
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < mat.bone_inv_map.Length; j++)
                    {
                        int inv = mat.bone_inv_map[j];
                        if (inv >= 0)
                        {
                            var b = surface.RenderBones[inv];
                            Array.Copy(b.matrix, 0, mBoneMatrix, j * 16, 16);
                        }
                    }
                }
                GLES20.GlUniformMatrix4fv(glsl.muMBone, mat.bone_num, false, mBoneMatrix, 0);

                GLES20.GlEnableVertexAttribArray(glsl.maBlendHandle);
                GLES20.GlVertexAttribPointer(glsl.maBlendHandle, 3, GLES20.GlUnsignedByte, false, 0, mat.weight);
            }

            // initialize color
            for (int i = 0; i < mDifAmb.Count(); i++)
            {
                mDifAmb[i] = 1.0f;
            }

            // diffusion and ambient
            float wi = 0.6f;                    // light color = (0.6, 0.6, 0.6)

            for (int i = 0; i < 3; i++)
            {
                mDifAmb[i] *= mat.material.diffuse_color[i] * wi + mat.material.emmisive_color[i];
            }
            mDifAmb[3] *= mat.material.diffuse_color[3];
            Vector.min(mDifAmb, 1.0f);
            GLES20.GlUniform4fv(glsl.muDif, 1, mDifAmb, 0);

            // speculation
            if (glsl.muPow >= 0)
            {
                GLES20.GlUniform4f(glsl.muSpec, mat.material.specular_color[0], mat.material.specular_color[1], mat.material.specular_color[2], 0);
                GLES20.GlUniform1f(glsl.muPow, mat.material.power);
            }

            // toon
            GLES20.GlUniform1i(glsl.msToonSampler, 0);
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[mat.material.toon_index]).tex);

            // texture
            GLES20.GlUniform1i(glsl.msTextureSampler, 1);
            GLES20.GlActiveTexture(GLES20.GlTexture1);
            if (mat.material.texture != null)
            {
                TexInfo tb = TextureFile.FetchTexInfo(mat.material.texture);
                if (tb != null)
                {
                    GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex);
                }
                else                                                                                              // avoid crash
                {
                    GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex); // white texture using toon0.bmp
                    for (int i = 0; i < 3; i++)                                                                   // for emulate premultiplied alpha
                    {
                        mDifAmb[i] *= mat.material.diffuse_color[3];
                    }
                }
            }
            else
            {
                GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex); // white texture using toon0.bmp
                for (int i = 0; i < 3; i++)                                                                   // for emulate premultiplied alpha
                {
                    mDifAmb[i] *= mat.material.diffuse_color[3];
                }
            }

            // sphere(sph)
            GLES20.GlUniform1i(glsl.msSphSampler, 2);
            GLES20.GlActiveTexture(GLES20.GlTexture2);
            if (mat.material.sph != null)
            {
                TexInfo tb = TextureFile.FetchTexInfo(mat.material.sph);
                if (tb != null)
                {
                    GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex);
                }
                else                                                                                               // avoid crash
                {
                    GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name [0]).tex); // white texture using toon0.bmp
                }
            }
            else
            {
                GLES20.GlBindTexture(GLES20.GlTexture2d, TextureFile.FetchTexInfo(surface.toon_name[0]).tex);                   // white texture using toon0.bmp
            }

            // sphere(spa)
            GLES20.GlUniform1i(glsl.msSpaSampler, 3);
            GLES20.GlActiveTexture(GLES20.GlTexture3);
            if (mat.material.spa != null)
            {
                TexInfo tb = TextureFile.FetchTexInfo(mat.material.spa);
                if (tb != null)
                {
                    GLES20.GlBindTexture(GLES20.GlTexture2d, tb.tex);
                }
            }

            // draw
            surface.IndexBuffer.Position(mat.face_vert_offset);
            GLES20.GlDrawElements(GLES20.GlTriangles, mat.face_vert_count, GLES20.GlUnsignedShort, surface.IndexBuffer);
            checkGlError("glDrawElements");
        }
Exemple #7
0
        public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            GLES20.GlClearColor(0.9f, 0.1f, 0.1f, 1.0f);
            // GLES20.GlViewport(0, 0, glSurfaceView.Width, glSurfaceView.Height);

            textureSize = arSession.CameraConfig.TextureSize;
            arSession.SetDisplayGeometry(1, targetResolution.Width, targetResolution.Height);

            int[] glObjs = new int[1];
            GLES20.GlGenFramebuffers(1, glObjs, 0);
            fboId = glObjs[0];
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, fboId);
            GLES20.GlViewport(0, 0, targetResolution.Width, targetResolution.Height);
            GLES20.GlGenTextures(1, glObjs, 0);
            renderTextureId = glObjs[0];;
            GLES20.GlBindTexture(GLES20.GlTexture2d, renderTextureId);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlNearest);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlNearest);
            GLES20.GlTexImage2D(GLES20.GlTexture2d, 0, GLES20.GlRgba, targetResolution.Width, targetResolution.Height, 0, GLES20.GlRgba, GLES20.GlUnsignedByte, null);

            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            GLES20.GlFramebufferTexture2D(GLES20.GlFramebuffer, GLES20.GlColorAttachment0, GLES20.GlTexture2d, renderTextureId, 0);
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);

            GlUtil.CheckNoGLES2Error("Create render texture.");

            // Create the texture and pass it to ARCore session to be filled during update().
            backgroundRenderer.CreateOnGlThread(/*context=*/ this);
            if (arSession != null)
            {
                arSession.SetCameraTextureName(BackgroundRenderer.TextureId);
            }


            // Prepare the other rendering objects.
            try
            {
                virtualObject.CreateOnGlThread(/*context=*/ this, "andy.obj", "andy.png");
                virtualObject.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);

                virtualObjectShadow.CreateOnGlThread(/*context=*/ this,
                                                     "andy_shadow.obj", "andy_shadow.png");
                virtualObjectShadow.SetBlendMode(ObjectRenderer.BlendMode.Shadow);
                virtualObjectShadow.setMaterialProperties(1.0f, 0.0f, 0.0f, 1.0f);
            }
            catch (Java.IO.IOException e)
            {
                Log.Error(TAG, "Failed to read obj file");
            }

            try
            {
                planeRenderer.CreateOnGlThread(/*context=*/ this, "trigrid.png");
            }
            catch (Java.IO.IOException e)
            {
                Log.Error(TAG, "Failed to read plane texture");
            }
            pointCloudRenderer.CreateOnGlThread(/*context=*/ this);
        }
Exemple #8
0
        /**
         * \brief Draw the video icon (in OpenGL).
         * @param mvpMatrix the model-view-projection matrix.
         * @param status the video state.
         */
        private void DrawIcon(float[] mvpMatrix, PikkartVideoPlayer.VideoSate.VIDEO_STATE status)
        {
            GLES20.GlEnable(GLES20.GlBlend);
            GLES20.GlBlendFunc(GLES20.GlSrcAlpha, GLES20.GlOneMinusSrcAlpha);

            GLES20.GlUseProgram(mKeyframe_Program_GL_ID);

            int vertexHandle       = GLES20.GlGetAttribLocation(mKeyframe_Program_GL_ID, "vertexPosition");
            int textureCoordHandle = GLES20.GlGetAttribLocation(mKeyframe_Program_GL_ID, "vertexTexCoord");
            int mvpMatrixHandle    = GLES20.GlGetUniformLocation(mKeyframe_Program_GL_ID, "modelViewProjectionMatrix");
            int texSampler2DHandle = GLES20.GlGetUniformLocation(mKeyframe_Program_GL_ID, "texSampler2D");

            GLES20.GlVertexAttribPointer(vertexHandle, 3, GLES20.GlFloat, false, 0, mVertices_Buffer);
            GLES20.GlVertexAttribPointer(textureCoordHandle, 2, GLES20.GlFloat, false, 0, mTexCoords_Buffer);

            GLES20.GlEnableVertexAttribArray(vertexHandle);
            GLES20.GlEnableVertexAttribArray(textureCoordHandle);

            GLES20.GlActiveTexture(GLES20.GlTexture0);
            switch ((int)status)
            {
            case 0:    //end
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconPlayTexture_GL_ID);
                break;

            case 1:    //pasued
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconPlayTexture_GL_ID);
                break;

            case 2:    //stopped
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconPlayTexture_GL_ID);
                break;

            case 3:    //playing
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconPlayTexture_GL_ID);
                break;

            case 4:    //ready
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconPlayTexture_GL_ID);
                break;

            case 5:    //not ready
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconBusyTexture_GL_ID);
                break;

            case 6:    //buffering
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconBusyTexture_GL_ID);
                break;

            case 7:    //error
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconErrorTexture_GL_ID);
                break;

            default:
                GLES20.GlBindTexture(GLES20.GlTexture2d, mIconBusyTexture_GL_ID);
                break;
            }
            GLES20.GlUniform1i(texSampler2DHandle, 0);

            GLES20.GlUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0);


            GLES20.GlDrawElements(GLES20.GlTriangles, mIndices_Number, GLES20.GlUnsignedShort, mIndex_Buffer);

            GLES20.GlDisableVertexAttribArray(vertexHandle);
            GLES20.GlDisableVertexAttribArray(textureCoordHandle);

            GLES20.GlUseProgram(0);
            GLES20.GlDisable(GLES20.GlBlend);
        }
Exemple #9
0
        public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            const float coord = 1.0f;

            ObjParser model3D = new ObjParser();

            List <byte[]> test1 = model3D.ParsedObject(context, "buggy");

            float[] vertexArray = new float[test1[0].Length / 4];
            System.Buffer.BlockCopy(test1[0], 0, vertexArray, 0, (int)test1[0].Length);

            modelVerticesData = vertexArray;

            FloatBuffer mTriangleVertices = ByteBuffer.AllocateDirect(modelVerticesData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleVertices.Put(modelVerticesData).Flip();

            // Cube colors
            // R, G, B, A
            float[] modelColorsData =
            {
                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

                1.0f, 0.0f, 0.0f, 0.5f,
                0.0f, 0.5f, 1.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f
            };

            FloatBuffer mTriangleColors = ByteBuffer.AllocateDirect(modelColorsData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleColors.Put(modelColorsData).Flip();


            float[] textureUVMapArray = new float[test1[1].Length / 4];
            System.Buffer.BlockCopy(test1[1], 0, textureUVMapArray, 0, (int)test1[1].Length);

            modelTextureUVMapData = textureUVMapArray;

            FloatBuffer mTriangleTextureUVMap = ByteBuffer.AllocateDirect(modelTextureUVMapData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            mTriangleTextureUVMap.Put(modelTextureUVMapData).Flip();



            //Data buffers to VBO
            GLES20.GlGenBuffers(3, VBOBuffers, 0); //2 buffers for vertices, texture and colors

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleVertices.Capacity() * mBytesPerFloat, mTriangleVertices, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[1]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleColors.Capacity() * mBytesPerFloat, mTriangleColors, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[2]);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleTextureUVMap.Capacity() * mBytesPerFloat, mTriangleTextureUVMap, GLES20.GlStaticDraw);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            //Load and setup texture

            GLES20.GlGenTextures(1, textureHandle, 0); //init 1 texture storage handle
            if (textureHandle[0] != 0)
            {
                //Android.Graphics cose class Matrix exists at both Android.Graphics and Android.OpenGL and this is only sample of using
                Android.Graphics.BitmapFactory.Options options = new Android.Graphics.BitmapFactory.Options();
                options.InScaled = false; // No pre-scaling
                Android.Graphics.Bitmap bitmap = Android.Graphics.BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.iam, options);
                GLES20.GlBindTexture(GLES20.GlTexture2d, textureHandle[0]);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlNearest);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlNearest);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
                GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
                GLUtils.TexImage2D(GLES20.GlTexture2d, 0, bitmap, 0);
                bitmap.Recycle();
            }

            //Ask android to run RAM garbage cleaner
            System.GC.Collect();

            //Setup OpenGL ES
            GLES20.GlClearColor(coord, coord, coord, coord);
            // GLES20.GlEnable(GLES20.GlDepthTest); //uncoment if needs enabled dpeth test
            GLES20.GlEnable(2884); // GlCullFace == 2884 see OpenGL documentation to this constant value
            GLES20.GlCullFace(GLES20.GlBack);


            // Position the eye behind the origin.
            float eyeX = 0.0f;
            float eyeY = 0.0f;
            float eyeZ = 4.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 = coord;
            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(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);

            string vertexShader =
                "uniform mat4 u_MVPMatrix;      \n"         // A constant representing the combined model/view/projection matrix.
                + "attribute vec4 a_Position;     \n"       // Per-vertex position information we will pass in.
                + "attribute vec4 a_Color;        \n"       // Per-vertex color information we will pass in.
                + "varying vec4 v_Color;          \n"       // This will be passed into the fragment shader.
                + "attribute vec2 a_TextureCoord; \n"
                + "varying vec2 v_TextureCoord;   \n"
                + "void main()                    \n"       // The entry point for our vertex shader.
                + "{                              \n"
                + "   v_TextureCoord = a_TextureCoord; \n"  // Pass the color through to the fragment shader. It will be interpolated across the triangle.
                + "   v_Color = a_Color;          \n"       // Pass the color through to the fragment shader. It will be interpolated across the triangle.
                + "   gl_Position = u_MVPMatrix   \n"       // gl_Position is a special variable used to store the final position.
                + "                 * a_Position; \n"       // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
                + "}                              \n";

            string fragmentShader =
                "precision mediump float;       \n"     // Set the default precision to medium. We don't need as high of a
                                                        // precision in the fragment shader.
                + "varying vec4 v_Color;          \n"   // This is the color from the vertex shader interpolated across the triangle per fragment.
                + "varying vec2 v_TextureCoord;   \n"
                + "uniform sampler2D u_Texture;   \n"
                + "void main()                    \n"                           // The entry point for our fragment shader.
                + "{                              \n"
                + "   gl_FragColor = texture2D(u_Texture, v_TextureCoord);  \n" // Pass the color directly through the pipeline.
                + "}                              \n";


            vertexShader   = string.Empty;
            fragmentShader = string.Empty;

            int          resourceId   = context.Resources.GetIdentifier("vertexshadervladimir1", "raw", context.PackageName);
            Stream       fileStream   = context.Resources.OpenRawResource(resourceId);
            StreamReader streamReader = new StreamReader(fileStream);

            string line = string.Empty;

            while ((line = streamReader.ReadLine()) != null)
            {
                vertexShader += line + "\n";
            }

            resourceId   = context.Resources.GetIdentifier("fragmentshadervladimir1", "raw", context.PackageName);
            fileStream   = context.Resources.OpenRawResource(resourceId);
            streamReader = new StreamReader(fileStream);
            while ((line = streamReader.ReadLine()) != null)
            {
                fragmentShader += line + "\n";
            }

            int vertexShaderHandle = GLES20.GlCreateShader(GLES20.GlVertexShader);

            if (vertexShaderHandle != 0)
            {
                // Pass in the shader source.
                GLES20.GlShaderSource(vertexShaderHandle, vertexShader);

                // Compile the shader.
                GLES20.GlCompileShader(vertexShaderHandle);

                // Get the compilation status.
                int[] compileStatus = new int[1];
                GLES20.GlGetShaderiv(vertexShaderHandle, GLES20.GlCompileStatus, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0)
                {
                    GLES20.GlDeleteShader(vertexShaderHandle);
                    vertexShaderHandle = 0;
                }
            }

            if (vertexShaderHandle == 0)
            {
                throw new Exception("Error creating vertex shader.");
            }

            // Load in the fragment shader shader.
            int fragmentShaderHandle = GLES20.GlCreateShader(GLES20.GlFragmentShader);

            if (fragmentShaderHandle != 0)
            {
                // Pass in the shader source.
                GLES20.GlShaderSource(fragmentShaderHandle, fragmentShader);

                // Compile the shader.
                GLES20.GlCompileShader(fragmentShaderHandle);

                // Get the compilation status.
                int[] compileStatus = new int[1];
                GLES20.GlGetShaderiv(fragmentShaderHandle, GLES20.GlCompileStatus, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0)
                {
                    GLES20.GlDeleteShader(fragmentShaderHandle);
                    fragmentShaderHandle = 0;
                }
            }

            if (fragmentShaderHandle == 0)
            {
                throw new Exception("Error creating fragment shader.");
            }

            // Create a program object and store the handle to it.
            int programHandle = GLES20.GlCreateProgram();

            if (programHandle != 0)
            {
                // Bind the vertex shader to the program.
                GLES20.GlAttachShader(programHandle, vertexShaderHandle);

                // Bind the fragment shader to the program.
                GLES20.GlAttachShader(programHandle, fragmentShaderHandle);

                // Bind attributes
                GLES20.GlBindAttribLocation(programHandle, 0, "a_Position");
                GLES20.GlBindAttribLocation(programHandle, 1, "a_Color");
                GLES20.GlBindAttribLocation(programHandle, 2, "a_TextureCoord");

                // Link the two shaders together into a program.
                GLES20.GlLinkProgram(programHandle);

                // Get the link status.
                int[] linkStatus = new int[1];
                GLES20.GlGetProgramiv(programHandle, GLES20.GlLinkStatus, linkStatus, 0);

                // If the link failed, delete the program.
                if (linkStatus[0] == 0)
                {
                    GLES20.GlDeleteProgram(programHandle);
                    programHandle = 0;
                }
            }

            if (programHandle == 0)
            {
                throw new Exception("Error creating program.");
            }

            // Set program handles. These will later be used to pass in values to the program.
            mMVPMatrixHandle    = GLES20.GlGetUniformLocation(programHandle, "u_MVPMatrix");
            mPositionHandle     = GLES20.GlGetAttribLocation(programHandle, "a_Position");
            mColorHandle        = GLES20.GlGetAttribLocation(programHandle, "a_Color");
            mTextureCoordHandle = GLES20.GlGetAttribLocation(programHandle, "a_TextureCoord");
            mTextureHandle      = GLES20.GlGetUniformLocation(programHandle, "u_Texture");


            // Tell OpenGL to use this program when rendering.
            GLES20.GlUseProgram(programHandle);
        }
Exemple #10
0
 public virtual void Bind()
 {
     GLES20.GlBindTexture(GLES20.GlTexture2d, Id);
 }