예제 #1
0
		public Square ()
		{
			// initialize vertex byte buffer for shape coordinates
			ByteBuffer bb = ByteBuffer.AllocateDirect (
			// (# of coordinate values * 4 bytes per float)
			        squareCoords.Length * 4);
			bb.Order (ByteOrder.NativeOrder ());
			vertexBuffer = bb.AsFloatBuffer ();
			vertexBuffer.Put (squareCoords);
			vertexBuffer.Position (0);

			// initialize byte buffer for the draw list
			ByteBuffer dlb = ByteBuffer.AllocateDirect (
			// (# of coordinate values * 2 bytes per short)
			        drawOrder.Length * 2);
			dlb.Order (ByteOrder.NativeOrder ());
			drawListBuffer = dlb.AsShortBuffer ();
			drawListBuffer.Put (drawOrder);
			drawListBuffer.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 Triangle ()
		{
			// initialize vertex byte buffer for shape coordinates
			ByteBuffer bb = ByteBuffer.AllocateDirect (
	                // (number of coordinate values * 4 bytes per float)
				                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 (GLES30.GlVertexShader,
				                   vertexShaderCode);
			int fragmentShader = MyGLRenderer.LoadShader (GLES30.GlFragmentShader,
				                     fragmentShaderCode);

			mProgram = GLES30.GlCreateProgram ();             // create empty OpenGL Program
			GLES30.GlAttachShader (mProgram, vertexShader);   // add the vertex shader to program
			GLES30.GlAttachShader (mProgram, fragmentShader); // add the fragment shader to program
			GLES30.GlLinkProgram (mProgram);                  // create OpenGL program executables
		}
예제 #3
0
 public MainRenderer(MainView view)
 {
     mView = view;
     float[] vtmp = { 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f };
     float[] ttmp = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
     pVertex = ByteBuffer.AllocateDirect(8 * 4).Order(ByteOrder.NativeOrder()).AsFloatBuffer();
     pVertex.Put(vtmp);
     pVertex.Position(0);
     pTexCoord = ByteBuffer.AllocateDirect(8 * 4).Order(ByteOrder.NativeOrder()).AsFloatBuffer();
     pTexCoord.Put(ttmp);
     pTexCoord.Position(0);
 }
예제 #4
0
      public Cube()
      {
         ByteBuffer byteBuf = ByteBuffer.AllocateDirect(vertices.Length * 4);
         byteBuf.Order(ByteOrder.NativeOrder());
         mVertexBuffer = byteBuf.AsFloatBuffer();
         mVertexBuffer.Put(vertices);
         mVertexBuffer.Position(0);

         byteBuf = ByteBuffer.AllocateDirect(colors.Length * 4);
         byteBuf.Order(ByteOrder.NativeOrder());
         mColorBuffer = byteBuf.AsFloatBuffer();
         mColorBuffer.Put(colors);
         mColorBuffer.Position(0);

         mIndexBuffer = ByteBuffer.AllocateDirect(indices.Length);
         mIndexBuffer.Put(indices);
         mIndexBuffer.Position(0);
      }
        private void InitBuffers()
        {
            // Initialize the size of the vertex buffer.
            ByteBuffer byteBufferForVer = ByteBuffer.AllocateDirect(32);

            byteBufferForVer.Order(ByteOrder.NativeOrder());
            mVerBuffer = byteBufferForVer.AsFloatBuffer();
            mVerBuffer.Put(POS);
            mVerBuffer.Position(0);

            // Initialize the size of the texture buffer.
            ByteBuffer byteBufferForTex = ByteBuffer.AllocateDirect(32);

            byteBufferForTex.Order(ByteOrder.NativeOrder());
            mTexBuffer = byteBufferForTex.AsFloatBuffer();
            mTexBuffer.Put(COORD);
            mTexBuffer.Position(0);

            // Initialize the size of the transformed texture buffer.
            ByteBuffer byteBufferForTransformedTex = ByteBuffer.AllocateDirect(32);

            byteBufferForTransformedTex.Order(ByteOrder.NativeOrder());
            mTexTransformedBuffer = byteBufferForTransformedTex.AsFloatBuffer();
        }
예제 #6
0
        public void Init()
        {
            // Create program
            _program = GLToolbox.CreateProgram (VertexShader, FragmentShader);

            // Bind attributes and uniforms
            _texSamplerHandle = GLES20.GlGetUniformLocation (_program,
                                                             "tex_sampler");
            _texCoordHandle = GLES20.GlGetAttribLocation (_program, "a_texcoord");
            _posCoordHandle = GLES20.GlGetAttribLocation (_program, "a_position");

            // Setup coordinate buffers
            _texVertices = ByteBuffer.AllocateDirect (
                TexVertices.Length * FloatSizeBytes)
                    .Order (ByteOrder.NativeOrder ()).AsFloatBuffer ();

            _texVertices.Put (TexVertices).Position (0);

            _posVertices = ByteBuffer.AllocateDirect (
                PosVertices.Length * FloatSizeBytes)
                    .Order (ByteOrder.NativeOrder ()).AsFloatBuffer ();

            _posVertices.Put (PosVertices).Position (0);
        }
예제 #7
0
        private int[] VBOBuffers = new int[2]; //2 buffers for vertices and colors

        public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            const float edge = 1.0f;

            // X, Y, Z,
            float[] triangleVerticesData =
            {
                -1.5f,       -0.25f, 0.0f,
                0.5f,        -0.25f, 0.0f,
                0.0f,  0.559016994f, 0.0f
            };

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

            mTriangleVertices.Put(triangleVerticesData).Flip();

            // 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
            };

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

            mTriangleColors.Put(triangleColorsData).Flip();

            //Use VBO
            GLES20.GlGenBuffers(2, VBOBuffers, 0); //2 buffers for vertices 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, 0);


            GLES20.GlClearColor(1.0f, 1.0f, 1.0f, 1.0f);

            // 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 = 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(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.
                + "void main()                    \n"       // The entry point for our vertex shader.
                + "{                              \n"
                + "   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.
                + "void main()                    \n"   // The entry point for our fragment shader.
                + "{                              \n"
                + "   gl_FragColor = 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");

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

            // Tell OpenGL to use this program when rendering.
            GLES20.GlUseProgram(programHandle);
        }
예제 #8
0
        /**
         * Updates the plane model transform matrix and extents.
         */
        private void updatePlaneParameters(float[] planeMatrix, float extentX, float extentZ,
                                           FloatBuffer boundary)
        {
            Array.Copy(planeMatrix, 0, mModelMatrix, 0, 16);
            if (boundary == null)
            {
                mVertexBuffer.Limit(0);
                mIndexBuffer.Limit(0);
                return;
            }

            // Generate a new set of vertices and a corresponding triangle strip index set so that
            // the plane boundary polygon has a fading edge. This is done by making a copy of the
            // boundary polygon vertices and scaling it down around center to push it inwards. Then
            // the index buffer is setup accordingly.
            boundary.Rewind();
            int boundaryVertices = boundary.Limit() / 2;
            int numVertices;
            int numIndices;

            numVertices = boundaryVertices * VERTS_PER_BOUNDARY_VERT;
            // drawn as GL_TRIANGLE_STRIP with 3n-2 triangles (n-2 for fill, 2n for perimeter).
            numIndices = boundaryVertices * INDICES_PER_BOUNDARY_VERT;

            if (mVertexBuffer.Capacity() < numVertices * COORDS_PER_VERTEX)
            {
                int size = mVertexBuffer.Capacity();
                while (size < numVertices * COORDS_PER_VERTEX)
                {
                    size *= 2;
                }
                mVertexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_FLOAT * size)
                                .Order(ByteOrder.NativeOrder()).AsFloatBuffer();
            }
            mVertexBuffer.Rewind();
            mVertexBuffer.Limit(numVertices * COORDS_PER_VERTEX);


            if (mIndexBuffer.Capacity() < numIndices)
            {
                int size = mIndexBuffer.Capacity();
                while (size < numIndices)
                {
                    size *= 2;
                }
                mIndexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_SHORT * size)
                               .Order(ByteOrder.NativeOrder()).AsShortBuffer();
            }
            mIndexBuffer.Rewind();
            mIndexBuffer.Limit(numIndices);

            // Note: when either dimension of the bounding box is smaller than 2*FADE_RADIUS_M we
            // generate a bunch of 0-area triangles.  These don't get rendered though so it works
            // out ok.
            float xScale = Math.Max((extentX - 2 * FADE_RADIUS_M) / extentX, 0.0f);
            float zScale = Math.Max((extentZ - 2 * FADE_RADIUS_M) / extentZ, 0.0f);

            while (boundary.HasRemaining)
            {
                float x = boundary.Get();
                float z = boundary.Get();
                mVertexBuffer.Put(x);
                mVertexBuffer.Put(z);
                mVertexBuffer.Put(0.0f);
                mVertexBuffer.Put(x * xScale);
                mVertexBuffer.Put(z * zScale);
                mVertexBuffer.Put(1.0f);
            }

            // step 1, perimeter
            mIndexBuffer.Put((short)((boundaryVertices - 1) * 2));
            for (int i = 0; i < boundaryVertices; ++i)
            {
                mIndexBuffer.Put((short)(i * 2));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            mIndexBuffer.Put((short)1);
            // This leaves us on the interior edge of the perimeter between the inset vertices
            // for boundary verts n-1 and 0.

            // step 2, interior:
            for (int i = 1; i < boundaryVertices / 2; ++i)
            {
                mIndexBuffer.Put((short)((boundaryVertices - 1 - i) * 2 + 1));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            if (boundaryVertices % 2 != 0)
            {
                mIndexBuffer.Put((short)((boundaryVertices / 2) * 2 + 1));
            }
        }
        /**
         * Creates the buffers we use to store information about the 3D world.
         *
         * OpenGL doesn't use Java arrays, but rather needs data in a format it can understand.
         * Hence we use ByteBuffers.
         */
        public void OnSurfaceCreated(Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            Android.Util.Log.Info(TAG, "onSurfaceCreated");

            GLES20.GlClearColor(0.1f, 0.1f, 0.1f, 0.5f);  // Dark background so text shows up well.

            var bbVertices = ByteBuffer.AllocateDirect(WorldLayoutData.CUBE_COORDS.Length * 4);

            bbVertices.Order(ByteOrder.NativeOrder());
            cubeVertices = bbVertices.AsFloatBuffer();
            cubeVertices.Put(WorldLayoutData.CUBE_COORDS);
            cubeVertices.Position(0);

            var bbColors = ByteBuffer.AllocateDirect(WorldLayoutData.CUBE_COLORS.Length * 4);

            bbColors.Order(ByteOrder.NativeOrder());
            cubeColors = bbColors.AsFloatBuffer();
            cubeColors.Put(WorldLayoutData.CUBE_COLORS);
            cubeColors.Position(0);

            var bbFoundColors = ByteBuffer.AllocateDirect(WorldLayoutData.CUBE_FOUND_COLORS.Length * 4);

            bbFoundColors.Order(ByteOrder.NativeOrder());
            cubeFoundColors = bbFoundColors.AsFloatBuffer();
            cubeFoundColors.Put(WorldLayoutData.CUBE_FOUND_COLORS);
            cubeFoundColors.Position(0);

            var bbNormals = ByteBuffer.AllocateDirect(WorldLayoutData.CUBE_NORMALS.Length * 4);

            bbNormals.Order(ByteOrder.NativeOrder());
            cubeNormals = bbNormals.AsFloatBuffer();
            cubeNormals.Put(WorldLayoutData.CUBE_NORMALS);
            cubeNormals.Position(0);

            // make a floor
            var bbFloorVertices = ByteBuffer.AllocateDirect(WorldLayoutData.FLOOR_COORDS.Length * 4);

            bbFloorVertices.Order(ByteOrder.NativeOrder());
            floorVertices = bbFloorVertices.AsFloatBuffer();
            floorVertices.Put(WorldLayoutData.FLOOR_COORDS);
            floorVertices.Position(0);

            var bbFloorNormals = ByteBuffer.AllocateDirect(WorldLayoutData.FLOOR_NORMALS.Length * 4);

            bbFloorNormals.Order(ByteOrder.NativeOrder());
            floorNormals = bbFloorNormals.AsFloatBuffer();
            floorNormals.Put(WorldLayoutData.FLOOR_NORMALS);
            floorNormals.Position(0);

            var bbFloorColors = ByteBuffer.AllocateDirect(WorldLayoutData.FLOOR_COLORS.Length * 4);

            bbFloorColors.Order(ByteOrder.NativeOrder());
            floorColors = bbFloorColors.AsFloatBuffer();
            floorColors.Put(WorldLayoutData.FLOOR_COLORS);
            floorColors.Position(0);

            int vertexShader      = loadGLShader(GLES20.GlVertexShader, Resource.Raw.light_vertex);
            int gridShader        = loadGLShader(GLES20.GlFragmentShader, Resource.Raw.grid_fragment);
            int passthroughShader = loadGLShader(GLES20.GlFragmentShader, Resource.Raw.passthrough_fragment);

            cubeProgram = GLES20.GlCreateProgram();
            GLES20.GlAttachShader(cubeProgram, vertexShader);
            GLES20.GlAttachShader(cubeProgram, passthroughShader);
            GLES20.GlLinkProgram(cubeProgram);
            GLES20.GlUseProgram(cubeProgram);

            CheckGLError("Cube program");

            cubePositionParam = GLES20.GlGetAttribLocation(cubeProgram, "a_Position");
            cubeNormalParam   = GLES20.GlGetAttribLocation(cubeProgram, "a_Normal");
            cubeColorParam    = GLES20.GlGetAttribLocation(cubeProgram, "a_Color");

            cubeModelParam               = GLES20.GlGetUniformLocation(cubeProgram, "u_Model");
            cubeModelViewParam           = GLES20.GlGetUniformLocation(cubeProgram, "u_MVMatrix");
            cubeModelViewProjectionParam = GLES20.GlGetUniformLocation(cubeProgram, "u_MVP");
            cubeLightPosParam            = GLES20.GlGetUniformLocation(cubeProgram, "u_LightPos");

            CheckGLError("Cube program params");

            floorProgram = GLES20.GlCreateProgram();
            GLES20.GlAttachShader(floorProgram, vertexShader);
            GLES20.GlAttachShader(floorProgram, gridShader);
            GLES20.GlLinkProgram(floorProgram);
            GLES20.GlUseProgram(floorProgram);

            CheckGLError("Floor program");

            floorModelParam               = GLES20.GlGetUniformLocation(floorProgram, "u_Model");
            floorModelViewParam           = GLES20.GlGetUniformLocation(floorProgram, "u_MVMatrix");
            floorModelViewProjectionParam = GLES20.GlGetUniformLocation(floorProgram, "u_MVP");
            floorLightPosParam            = GLES20.GlGetUniformLocation(floorProgram, "u_LightPos");

            floorPositionParam = GLES20.GlGetAttribLocation(floorProgram, "a_Position");
            floorNormalParam   = GLES20.GlGetAttribLocation(floorProgram, "a_Normal");
            floorColorParam    = GLES20.GlGetAttribLocation(floorProgram, "a_Color");

            CheckGLError("Floor program params");

            Matrix.SetIdentityM(modelFloor, 0);
            Matrix.TranslateM(modelFloor, 0, 0, -floorDepth, 0);  // Floor appears below user.

            // Avoid any delays during start-up due to decoding of sound files.
            System.Threading.Tasks.Task.Run(() => {
                // Start spatial audio playback of SOUND_FILE at the model postion. The returned
                //soundId handle is stored and allows for repositioning the sound object whenever
                // the cube position changes.
                gvrAudioEngine.PreloadSoundFile(SOUND_FILE);
                soundId = gvrAudioEngine.CreateSoundObject(SOUND_FILE);
                gvrAudioEngine.SetSoundObjectPosition(
                    soundId, modelPosition [0], modelPosition [1], modelPosition [2]);
                gvrAudioEngine.PlaySound(soundId, true /* looped playback */);
            });

            UpdateModelPosition();

            CheckGLError("onSurfaceCreated");
        }
예제 #10
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);
        }
        /**
        * Creates the buffers we use to store information about the 3D world.
        *
        * OpenGL doesn't use Java arrays, but rather needs data in a format it can understand.
        * Hence we use ByteBuffers.
        */
        public void OnSurfaceCreated (Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            Android.Util.Log.Info (TAG, "onSurfaceCreated");

            GLES20.GlClearColor (0.1f, 0.1f, 0.1f, 0.5f); // Dark background so text shows up well.

            var bbVertices = ByteBuffer.AllocateDirect (WorldLayoutData.CUBE_COORDS.Length * 4);
            bbVertices.Order (ByteOrder.NativeOrder ());
            cubeVertices = bbVertices.AsFloatBuffer ();
            cubeVertices.Put (WorldLayoutData.CUBE_COORDS);
            cubeVertices.Position (0);

            var bbColors = ByteBuffer.AllocateDirect (WorldLayoutData.CUBE_COLORS.Length * 4);
            bbColors.Order (ByteOrder.NativeOrder ());
            cubeColors = bbColors.AsFloatBuffer ();
            cubeColors.Put (WorldLayoutData.CUBE_COLORS);
            cubeColors.Position (0);

            var bbFoundColors = ByteBuffer.AllocateDirect (WorldLayoutData.CUBE_FOUND_COLORS.Length * 4);
            bbFoundColors.Order (ByteOrder.NativeOrder ());
            cubeFoundColors = bbFoundColors.AsFloatBuffer ();
            cubeFoundColors.Put (WorldLayoutData.CUBE_FOUND_COLORS);
            cubeFoundColors.Position (0);

            var bbNormals = ByteBuffer.AllocateDirect (WorldLayoutData.CUBE_NORMALS.Length * 4);
            bbNormals.Order (ByteOrder.NativeOrder ());
            cubeNormals = bbNormals.AsFloatBuffer ();
            cubeNormals.Put (WorldLayoutData.CUBE_NORMALS);
            cubeNormals.Position (0);

            // make a floor
            var bbFloorVertices = ByteBuffer.AllocateDirect (WorldLayoutData.FLOOR_COORDS.Length * 4);
            bbFloorVertices.Order (ByteOrder.NativeOrder ());
            floorVertices = bbFloorVertices.AsFloatBuffer ();
            floorVertices.Put (WorldLayoutData.FLOOR_COORDS);
            floorVertices.Position (0);

            var bbFloorNormals = ByteBuffer.AllocateDirect (WorldLayoutData.FLOOR_NORMALS.Length * 4);
            bbFloorNormals.Order (ByteOrder.NativeOrder ());
            floorNormals = bbFloorNormals.AsFloatBuffer ();
            floorNormals.Put (WorldLayoutData.FLOOR_NORMALS);
            floorNormals.Position (0);

            var bbFloorColors = ByteBuffer.AllocateDirect (WorldLayoutData.FLOOR_COLORS.Length * 4);
            bbFloorColors.Order (ByteOrder.NativeOrder ());
            floorColors = bbFloorColors.AsFloatBuffer ();
            floorColors.Put (WorldLayoutData.FLOOR_COLORS);
            floorColors.Position (0);

            int vertexShader = loadGLShader (GLES20.GlVertexShader, Resource.Raw.light_vertex);
            int gridShader = loadGLShader (GLES20.GlFragmentShader, Resource.Raw.grid_fragment);
            int passthroughShader = loadGLShader (GLES20.GlFragmentShader, Resource.Raw.passthrough_fragment);

            cubeProgram = GLES20.GlCreateProgram ();
            GLES20.GlAttachShader (cubeProgram, vertexShader);
            GLES20.GlAttachShader (cubeProgram, passthroughShader);
            GLES20.GlLinkProgram (cubeProgram);
            GLES20.GlUseProgram (cubeProgram);

            CheckGLError ("Cube program");

            cubePositionParam = GLES20.GlGetAttribLocation (cubeProgram, "a_Position");
            cubeNormalParam = GLES20.GlGetAttribLocation (cubeProgram, "a_Normal");
            cubeColorParam = GLES20.GlGetAttribLocation (cubeProgram, "a_Color");

            cubeModelParam = GLES20.GlGetUniformLocation (cubeProgram, "u_Model");
            cubeModelViewParam = GLES20.GlGetUniformLocation (cubeProgram, "u_MVMatrix");
            cubeModelViewProjectionParam = GLES20.GlGetUniformLocation (cubeProgram, "u_MVP");
            cubeLightPosParam = GLES20.GlGetUniformLocation (cubeProgram, "u_LightPos");

            CheckGLError ("Cube program params");

            floorProgram = GLES20.GlCreateProgram ();
            GLES20.GlAttachShader (floorProgram, vertexShader);
            GLES20.GlAttachShader (floorProgram, gridShader);
            GLES20.GlLinkProgram (floorProgram);
            GLES20.GlUseProgram (floorProgram);

            CheckGLError ("Floor program");

            floorModelParam = GLES20.GlGetUniformLocation (floorProgram, "u_Model");
            floorModelViewParam = GLES20.GlGetUniformLocation (floorProgram, "u_MVMatrix");
            floorModelViewProjectionParam = GLES20.GlGetUniformLocation (floorProgram, "u_MVP");
            floorLightPosParam = GLES20.GlGetUniformLocation (floorProgram, "u_LightPos");

            floorPositionParam = GLES20.GlGetAttribLocation (floorProgram, "a_Position");
            floorNormalParam = GLES20.GlGetAttribLocation (floorProgram, "a_Normal");
            floorColorParam = GLES20.GlGetAttribLocation (floorProgram, "a_Color");

            CheckGLError ("Floor program params");

            Matrix.SetIdentityM (modelFloor, 0);
            Matrix.TranslateM (modelFloor, 0, 0, -floorDepth, 0); // Floor appears below user.

            // Avoid any delays during start-up due to decoding of sound files.
            System.Threading.Tasks.Task.Run (() => {
                // Start spatial audio playback of SOUND_FILE at the model postion. The returned
                //soundId handle is stored and allows for repositioning the sound object whenever
                // the cube position changes.
                gvrAudioEngine.PreloadSoundFile (SOUND_FILE);
                soundId = gvrAudioEngine.CreateSoundObject (SOUND_FILE);
                gvrAudioEngine.SetSoundObjectPosition (
                    soundId, modelPosition [0], modelPosition [1], modelPosition [2]);
                gvrAudioEngine.PlaySound (soundId, true /* looped playback */);
            });

            UpdateModelPosition ();

            CheckGLError ("onSurfaceCreated");
        }
예제 #12
0
 public void SetVertices(float[] vertices, int offset, int length)
 {
     _vertices.Clear();
     _vertices.Put(vertices, offset, length);
     _vertices.Flip();
 }
예제 #13
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);
        }
예제 #14
0
            public DistortionMesh(EyeParams eye, Distortion distortion, float screenWidthM, float screenHeightM, float xEyeOffsetMScreen, float yEyeOffsetMScreen, float textureWidthM, float textureHeightM, float xEyeOffsetMTexture, float yEyeOffsetMTexture, float viewportXMTexture, float viewportYMTexture, float viewportWidthMTexture, float viewportHeightMTexture)
            {
                float mPerUScreen  = screenWidthM;
                float mPerVScreen  = screenHeightM;
                float mPerUTexture = textureWidthM;
                float mPerVTexture = textureHeightM;

                float[] vertexData   = new float[8000];
                int     vertexOffset = 0;

                for (int row = 0; row < 40; row++)
                {
                    for (int col = 0; col < 40; col++)
                    {
                        float uTexture = col / 39.0F * (viewportWidthMTexture / textureWidthM) + viewportXMTexture / textureWidthM;

                        float vTexture = row / 39.0F * (viewportHeightMTexture / textureHeightM) + viewportYMTexture / textureHeightM;

                        float xTexture    = uTexture * mPerUTexture;
                        float yTexture    = vTexture * mPerVTexture;
                        float xTextureEye = xTexture - xEyeOffsetMTexture;
                        float yTextureEye = yTexture - yEyeOffsetMTexture;
                        float rTexture    = (float)Math.Sqrt(xTextureEye * xTextureEye + yTextureEye * yTextureEye);

                        float textureToScreen = rTexture > 0.0F ? distortion.distortInverse(rTexture) / rTexture : 1.0F;

                        float xScreen = xTextureEye * textureToScreen + xEyeOffsetMScreen;
                        float yScreen = yTextureEye * textureToScreen + yEyeOffsetMScreen;
                        float uScreen = xScreen / mPerUScreen;
                        float vScreen = yScreen / mPerVScreen;
                        float vignetteSizeMTexture = 0.002F / textureToScreen;

                        float dxTexture = xTexture - DistortionRenderer.clamp(xTexture, viewportXMTexture + vignetteSizeMTexture, viewportXMTexture + viewportWidthMTexture - vignetteSizeMTexture);

                        float dyTexture = yTexture - DistortionRenderer.clamp(yTexture, viewportYMTexture + vignetteSizeMTexture, viewportYMTexture + viewportHeightMTexture - vignetteSizeMTexture);

                        float drTexture = (float)Math.Sqrt(dxTexture * dxTexture + dyTexture * dyTexture);

                        float vignette = 1.0F - DistortionRenderer.clamp(drTexture / vignetteSizeMTexture, 0.0F, 1.0F);

                        vertexData[(vertexOffset + 0)] = (2.0F * uScreen - 1.0F);
                        vertexData[(vertexOffset + 1)] = (2.0F * vScreen - 1.0F);
                        vertexData[(vertexOffset + 2)] = vignette;
                        vertexData[(vertexOffset + 3)] = uTexture;
                        vertexData[(vertexOffset + 4)] = vTexture;

                        vertexOffset += 5;
                    }
                }

                nIndices = 3158;
                int[] indexData   = new int[nIndices];
                int   indexOffset = 0;

                vertexOffset = 0;
                for (int row = 0; row < 39; row++)
                {
                    if (row > 0)
                    {
                        indexData[indexOffset] = indexData[(indexOffset - 1)];
                        indexOffset++;
                    }
                    for (int col = 0; col < 40; col++)
                    {
                        if (col > 0)
                        {
                            if (row % 2 == 0)
                            {
                                vertexOffset++;
                            }
                            else
                            {
                                vertexOffset--;
                            }
                        }
                        indexData[(indexOffset++)] = vertexOffset;
                        indexData[(indexOffset++)] = (vertexOffset + 40);
                    }
                    vertexOffset += 40;
                }

                FloatBuffer vertexBuffer = ByteBuffer.AllocateDirect(vertexData.Length * 4).Order(ByteOrder.NativeOrder()).AsFloatBuffer();

                vertexBuffer.Put(vertexData).Position(0);

                IntBuffer indexBuffer = ByteBuffer.AllocateDirect(indexData.Length * 4).Order(ByteOrder.NativeOrder()).AsIntBuffer();

                indexBuffer.Put(indexData).Position(0);

                int[] bufferIds = new int[2];
                GLES20.GlGenBuffers(2, bufferIds, 0);
                mArrayBufferId   = bufferIds[0];
                mElementBufferId = bufferIds[1];

                GLES20.GlBindBuffer(34962, mArrayBufferId);
                GLES20.GlBufferData(34962, vertexData.Length * 4, vertexBuffer, 35044);

                GLES20.GlBindBuffer(34963, mElementBufferId);
                GLES20.GlBufferData(34963, indexData.Length * 4, indexBuffer, 35044);

                GLES20.GlBindBuffer(34962, 0);
                GLES20.GlBindBuffer(34963, 0);
            }
예제 #15
0
        protected internal virtual void UpdateVertices()
        {
            _Width  = 0;
            _Height = 0;

            if (text == null)
            {
                text = "";
            }

            Quads      = Quad.CreateSet(text.Length);
            RealLength = 0;

            var length = text.Length;

            for (var i = 0; i < length; i++)
            {
                var rect = ((TextureFilm)font).Get(text[i]);

                var w = font.Width(rect);
                var h = font.Height(rect);

                Vertices[0] = Width;
                Vertices[1] = 0;

                Vertices[2] = rect.Left;
                Vertices[3] = rect.Top;

                Vertices[4] = Width + w;
                Vertices[5] = 0;

                Vertices[6] = rect.Right;
                Vertices[7] = rect.Top;

                Vertices[8] = Width + w;
                Vertices[9] = h;

                Vertices[10] = rect.Right;
                Vertices[11] = rect.Bottom;

                Vertices[12] = Width;
                Vertices[13] = h;

                Vertices[14] = rect.Left;
                Vertices[15] = rect.Bottom;

                Quads.Put(Vertices);
                RealLength++;

                _Width += w + font.tracking;
                if (h > Height)
                {
                    _Height = h;
                }
            }

            if (length > 0)
            {
                _Width -= font.tracking;
            }

            Dirty = false;
        }
예제 #16
0
        public bool loadingBinModel(String fileName)
        {
            float[] floatArray;
            long    size;

            try
            {
                // Vertex
                vertexBuffer = null;
                System.GC.Collect();
                int          resourceId = context.Resources.GetIdentifier(fileName + "_vert", "raw", context.PackageName);
                Stream       fileIn     = context.Resources.OpenRawResource(resourceId) as Stream;
                MemoryStream m          = new MemoryStream();
                fileIn.CopyTo(m);
                size       = m.Length;
                floatArray = new float[size / 4];
                System.Buffer.BlockCopy(m.ToArray(), 0, floatArray, 0, (int)size);

                vertexBuffer = FloatBuffer.Allocate((int)size / 4); // float array to
                vertexBuffer.Put(floatArray, 0, (int)size / 4);
                vertexBuffer.Flip();

                VBOManager.setSize(fileName, vertexBuffer.Capacity() / 4); //is size of vertex count = 1 vertex 4 float x,y,z, 1
                floatArray = null;
                fileIn.Close();
                m.Close();
                //----------------------------------------------------------------------------------------------------

                normalBuffer = null;
                System.GC.Collect();
                resourceId = context.Resources.GetIdentifier(fileName + "_norm", "raw", context.PackageName);
                fileIn     = context.Resources.OpenRawResource(resourceId) as Stream;
                m          = new MemoryStream();
                fileIn.CopyTo(m);
                size       = m.Length;
                floatArray = new float[size / 4];
                System.Buffer.BlockCopy(m.ToArray(), 0, floatArray, 0, (int)size);

                normalBuffer = FloatBuffer.Allocate((int)size / 4); // float array to
                normalBuffer.Put(floatArray, 0, (int)size / 4);
                normalBuffer.Flip();

                floatArray = null;
                fileIn.Close();
                m.Close();
                //----------------------------------------------------------------------------------------------------
                textureBuffer = null;
                System.GC.Collect();
                resourceId = context.Resources.GetIdentifier(fileName + "_texture", "raw", context.PackageName);
                fileIn     = context.Resources.OpenRawResource(resourceId) as Stream;
                m          = new MemoryStream();
                fileIn.CopyTo(m);
                size       = m.Length;
                floatArray = new float[size / 4];
                System.Buffer.BlockCopy(m.ToArray(), 0, floatArray, 0, (int)size);

                textureBuffer = FloatBuffer.Allocate((int)size / 4); // float array to
                textureBuffer.Put(floatArray, 0, (int)size / 4);
                textureBuffer.Flip();

                floatArray = null;
                fileIn.Close();
                m.Close();

                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }
        }