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 }
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); }
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(); }
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); }
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); }
/** * 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"); }
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"); }
public void SetVertices(float[] vertices, int offset, int length) { _vertices.Clear(); _vertices.Put(vertices, offset, length); _vertices.Flip(); }
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); }
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); }
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; }
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); } }