private void drawNonAlpha(ShellSurface surface, GLSL glsl) { var mats = surface.RenderLists; int max = mats.Count; // draw non-alpha material // GLES20.GlEnable(GLES20.GlCullFace); GLES20.GlEnable(2884); GLES20.GlCullFace(GLES20.GlBack); GLES20.GlDisable(GLES20.GlBlend); for (int r = 0; r < max; r++) { var mat = mats[r]; TexInfo tb = null; if (mat.material.texture != null) { tb = TextureFile.FetchTexInfo(mat.material.texture); } if (mat.material.diffuse_color[3] >= 1.0 && (tb == null || !tb.has_alpha)) { drawOneMaterial(glsl, surface, mat); } } }
/** * \brief Draw this mesh (in OpenGL). * @param modelViewProjection this mesh model-view-projection matrix. */ public void DrawMesh(float[] modelViewProjection) { //set up gl state GLES20.GlEnable(GLES20.GlDepthTest); //GLES20.GlDisable(GLES20.GlCullFaceMode); GLES20.GlCullFace(GLES20.GlBack); GLES20.GlFrontFace(GLES20.GlCw); //set shader program to use GLES20.GlUseProgram(mProgram_GL_ID); RenderUtils.CheckGLError("DrawMesh:glUseProgram"); //find attrib and unifroms in shader program int vertexHandle = GLES20.GlGetAttribLocation(mProgram_GL_ID, "vertexPosition"); //int normalHandle = GLES20.GlGetAttribLocation(Program_GL_ID, "vertexNormal"); int textureCoordHandle = GLES20.GlGetAttribLocation(mProgram_GL_ID, "vertexTexCoord"); int mvpMatrixHandle = GLES20.GlGetUniformLocation(mProgram_GL_ID, "modelViewProjectionMatrix"); int texSampler2DHandle = GLES20.GlGetUniformLocation(mProgram_GL_ID, "texSampler2D"); RenderUtils.CheckGLError("DrawMesh:get attribs and uniforms"); //upload mesh data to OpenGL attribs GLES20.GlVertexAttribPointer(vertexHandle, 3, GLES20.GlFloat, false, 0, mVertices_Buffer); //GLES20.GlVertexAttribPointer(normalHandle, 3, GLES20.GlFloat, false, 0, Normals_Buffer); GLES20.GlVertexAttribPointer(textureCoordHandle, 2, GLES20.GlFloat, false, 0, mTexCoords_Buffer); RenderUtils.CheckGLError("DrawMesh:put attrib pointers"); //enable gl attribs to use GLES20.GlEnableVertexAttribArray(vertexHandle); //GLES20.GlEnableVertexAttribArray(normalHandle); GLES20.GlEnableVertexAttribArray(textureCoordHandle); RenderUtils.CheckGLError("DrawMesh:enable attrib arrays"); // activate texture 0, bind it, and pass to shader GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTexture_GL_ID); GLES20.GlUniform1i(texSampler2DHandle, 0); RenderUtils.CheckGLError("DrawMesh:activate texturing"); // pass the model view matrix to the shader GLES20.GlUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0); RenderUtils.CheckGLError("DrawMesh:upload matrix"); // finally draw the teapot GLES20.GlDrawElements(GLES20.GlTriangles, mIndices_Number, GLES20.GlUnsignedShort, mIndex_Buffer); RenderUtils.CheckGLError("DrawMesh:draw elements"); // disable the enabled arrays GLES20.GlDisableVertexAttribArray(vertexHandle); //GLES20.GlDisableVertexAttribArray(normalHandle); GLES20.GlDisableVertexAttribArray(textureCoordHandle); RenderUtils.CheckGLError("DrawMesh:disable attrib arrays"); }
public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config) { if (RenderManager.externalPaused) { RenderManager.initShaders(); } else { RenderManager.createObjects(); } GLES20.GlClearColor(0.1f, 0.1f, 0.9f, 0.0f); GLES20.GlEnable(GLES20.GlDepthTest); GLES20.GlEnable(GLES20.GlCullFaceMode); GLES20.GlCullFace(GLES20.GlBack); }
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); }
public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config) { mTriangle1Vertices = ByteBuffer.AllocateDirect(triangle1VerticesData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer(); mTriangle1Vertices.Put(triangle1VerticesData).Position(0); mTriangle1Vertices2 = ByteBuffer.AllocateDirect(triangle1VerticesData2.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer(); mTriangle1Vertices2.Put(triangle1VerticesData2).Position(0); GLES20.GlClearColor(1.0f, 1.0f, 1.0f, 1.0f); //GLES20.GlEnable(GLES20.GlDepthTest); //GLES20.GlEnable(2884); //GlCullFace == 2884 GLES20.GlCullFace(GLES20.GlFrontAndBack); // Position the eye behind the origin. float eyeX = 0.0f; float eyeY = 0.0f; float eyeZ = 1.5f; // We are looking toward the distance float lookX = 0.0f; float lookY = 0.0f; float lookZ = -10f; // 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 = -5.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); }
/** * \brief Draw the video mesh /with keyframe and icons too) (in OpenGL). * @param modelView the model-view matrix. * @param projection the projection matrix. */ public void DrawMesh(float[] modelView, float[] projection) { PikkartVideoPlayer.VideoSate.VIDEO_STATE currentStatus = PikkartVideoPlayer.VideoSate.VIDEO_STATE.NOT_READY; if (mPikkartVideoPlayer != null) { currentStatus = mPikkartVideoPlayer.getVideoStatus(); if (!mPikkartVideoPlayer.isFullscreen()) { if (mPikkartVideoPlayer.getVideoStatus() == PikkartVideoPlayer.VideoSate.VIDEO_STATE.PLAYING) { mPikkartVideoPlayer.updateVideoData(); } mPikkartVideoPlayer.getSurfaceTextureTransformMatrix(mTexCoordTransformationMatrix); SetVideoDimensions(mPikkartVideoPlayer.getVideoWidth(), mPikkartVideoPlayer.getVideoHeight(), mTexCoordTransformationMatrix); mVideoTexCoords_Buffer = FillBuffer(videoTextureCoordsTransformed); } } Marker currentMarker = RecognitionFragment.CurrentMarker; if (currentMarker != null) { float markerWidth = currentMarker.Width; float markerHeight = currentMarker.Height; GLES20.GlEnable(GLES20.GlDepthTest); //GLES20.GlDisable(GLES20.GlCullFaceMode); GLES20.GlCullFace(GLES20.GlBack); GLES20.GlFrontFace(GLES20.GlCw); if ((currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.READY) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.END) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.NOT_READY) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.ERROR)) { float[] scaleMatrix = new float[16]; RenderUtils.matrix44Identity(scaleMatrix); scaleMatrix[0] = markerWidth; scaleMatrix[5] = markerWidth * keyframeAspectRatio; scaleMatrix[10] = markerWidth; float[] temp_mv = new float[16]; RenderUtils.matrixMultiply(4, 4, modelView, 4, 4, scaleMatrix, temp_mv); float[] temp_mvp = new float[16]; RenderUtils.matrixMultiply(4, 4, projection, 4, 4, temp_mv, temp_mvp); float[] mvpMatrix = new float[16]; RenderUtils.matrix44Transpose(temp_mvp, mvpMatrix); DrawKeyFrame(mvpMatrix); } else { float[] scaleMatrix = new float[16]; RenderUtils.matrix44Identity(scaleMatrix); scaleMatrix[0] = markerWidth; scaleMatrix[5] = markerWidth * videoAspectRatio; scaleMatrix[10] = markerWidth; float[] temp_mv = new float[16]; RenderUtils.matrixMultiply(4, 4, modelView, 4, 4, scaleMatrix, temp_mv); float[] temp_mvp = new float[16]; RenderUtils.matrixMultiply(4, 4, projection, 4, 4, temp_mv, temp_mvp); float[] mvpMatrix = new float[16]; RenderUtils.matrix44Transpose(temp_mvp, mvpMatrix); DrawVideo(mvpMatrix); } if ((currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.READY) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.END) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.PAUSED) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.NOT_READY) || (currentStatus == PikkartVideoPlayer.VideoSate.VIDEO_STATE.ERROR)) { float[] translateMatrix = new float[16]; RenderUtils.matrix44Identity(translateMatrix); //scale a bit translateMatrix[0] = 0.4f; translateMatrix[5] = 0.4f; translateMatrix[10] = 0.4f; //translate a bit translateMatrix[3] = 0.0f; translateMatrix[7] = 0.45f; translateMatrix[11] = -0.05f; float[] temp_mv = new float[16]; RenderUtils.matrixMultiply(4, 4, modelView, 4, 4, translateMatrix, temp_mv); float[] temp_mvp = new float[16]; RenderUtils.matrixMultiply(4, 4, projection, 4, 4, temp_mv, temp_mvp); float[] mvpMatrix = new float[16]; RenderUtils.matrix44Transpose(temp_mvp, mvpMatrix); DrawIcon(mvpMatrix, currentStatus); } RenderUtils.CheckGLError("VideoMesh:end video renderer"); } }
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); }