public void Initialize() { GLES20.GlClearColor(0.1f, 0.1f, 0.1f, 0.5f); // Dark background so text shows up well cubeVertices = PrepareBuffer(WorldLayoutData.CubeCoords); cubeNormals = PrepareBuffer(WorldLayoutData.CubeNormals); cubeTextureCoords = PrepareBuffer(WorldLayoutData.CubeTexCoords); floorVertices = PrepareBuffer(WorldLayoutData.FloorCoords); floorNormals = PrepareBuffer(WorldLayoutData.FloorNormals); floorColors = PrepareBuffer(WorldLayoutData.FloorColors); monkeyFound = DrawingUtils.LoadGlTexture(resources, Resource.Drawable.texture2); monkeyNotFound = DrawingUtils.LoadGlTexture(resources, Resource.Drawable.texture1); int vertexShader = DrawingUtils.LoadGlShader(GLES20.GlVertexShader, resources, Resource.Raw.vertex); int gridShader = DrawingUtils.LoadGlShader(GLES20.GlFragmentShader, resources, Resource.Raw.fragment); glProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(glProgram, vertexShader); GLES20.GlAttachShader(glProgram, gridShader); GLES20.GlLinkProgram(glProgram); GLES20.GlEnable(GLES20.GlDepthTest); // Object first appears directly in front of user Matrix.SetIdentityM(modelCube, 0); Matrix.TranslateM(modelCube, 0, 0, 0, -mObjectDistance); Matrix.SetIdentityM(modelFloor, 0); Matrix.TranslateM(modelFloor, 0, 0, -mFloorDepth, 0); // Floor appears below user CheckGlError("onSurfaceCreated"); }
/// <summary> /// Allocates and initializes OpenGL resources needed by the plane renderer. Must be /// called on the OpenGL thread, typically in /// {@link GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)}. /// </summary> public void CreateOnGlThread(Context context) { //ShaderHelper.CheckGLError(TAG, "before create"); var buffers = new int[1]; GLES20.GlGenBuffers(1, buffers, 0); mVbo = buffers[0]; GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mVboSize = INITIAL_BUFFER_POINTS * BYTES_PER_POINT; GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); var vertexShader = ShaderHelper.Load(TAG, context, GLES20.GlVertexShader, Resource.Raw.point_cloud_vertex); var passthroughShader = ShaderHelper.Load(TAG, context, GLES20.GlFragmentShader, Resource.Raw.passthrough_fragment); mProgramName = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgramName, vertexShader); GLES20.GlAttachShader(mProgramName, passthroughShader); GLES20.GlLinkProgram(mProgramName); GLES20.GlUseProgram(mProgramName); mPositionAttribute = GLES20.GlGetAttribLocation(mProgramName, "a_Position"); mColorUniform = GLES20.GlGetUniformLocation(mProgramName, "u_Color"); mModelViewProjectionUniform = GLES20.GlGetUniformLocation( mProgramName, "u_ModelViewProjection"); mPointSizeUniform = GLES20.GlGetUniformLocation(mProgramName, "u_PointSize"); }
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 }
private static int CreateGlProgram() { int vertex = LoadShader(GLES20.GlVertexShader, FACE_GEOMETRY_VERTEX); if (vertex == 0) { return(0); } int fragment = LoadShader(GLES20.GlFragmentShader, FACE_GEOMETRY_FRAGMENT); if (fragment == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, vertex); GLES20.GlAttachShader(program, fragment); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { Log.Debug(TAG, "Could not link program: " + GLES20.GlGetProgramInfoLog(program)); GLES20.GlDeleteProgram(program); program = 0; } } return(program); }
private int createProgram(String vertexSource, String fragmentSource) { int vertexShader = loadShader(GLES20.GlVertexShader, vertexSource); if (vertexShader == 0) { return 0; } int pixelShader = loadShader(GLES20.GlFragmentShader, fragmentSource); if (pixelShader == 0) { return 0; } int program = GLES20.GlCreateProgram(); checkGlError("glCreateProgram"); if (program == 0) { Log.Error(TAG, "Could not create program"); } GLES20.GlAttachShader(program, vertexShader); checkGlError("glAttachShader"); GLES20.GlAttachShader(program, pixelShader); checkGlError("glAttachShader"); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { Log.Error(TAG, "Could not link program: "); Log.Error(TAG, GLES20.GlGetProgramInfoLog(program)); GLES20.GlDeleteProgram(program); program = 0; } return program; }
/** * Sets up the drawing object data for use in an OpenGL ES context. */ 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 = MainRenderer.loadShader(GLES20.GlVertexShader, vertexShaderCode); int fragmentShader = MainRenderer.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 }
/** * \brief Create a gl shader from source code. * @param vertexShaderSrc vertex shader code. * @param fragmentShaderSrc fragment shader code. * @return gl program id. */ public static int createProgramFromShaderSrc(string vertexShaderSrc, string fragmentShaderSrc) { int vertShader = initShader(GLES20.GlVertexShader, vertexShaderSrc); int fragShader = initShader(GLES20.GlFragmentShader, fragmentShaderSrc); if (vertShader == 0 || fragShader == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, vertShader); GLES20.GlAttachShader(program, fragShader); GLES20.GlLinkProgram(program); int[] glStatusVar = { GLES20.GlFalse }; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, glStatusVar, 0); if (glStatusVar[0] == GLES20.GlFalse) { //Log.e("RenderUtils", "createProgramFromShaderSrc could NOT link program : " + GLES20.GlGetProgramInfoLog(program)); GLES20.GlDeleteProgram(program); program = 0; } } return(program); }
/** * Allocates and initializes OpenGL resources needed by the background renderer. Must be * called on the OpenGL thread, typically in * {@link GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)}. * * @param context Needed to access shader source. */ public void CreateOnGlThread(Context context) { // Generate the background texture. var textures = new int[1]; //GLES20 = OpenGL ES 2.0 //Gibt eine bestimmte Anzahl an freien Texturnamen zurück. GLES20.GlGenTextures(1, textures, 0); TextureId = textures[0]; GLES20.GlBindTexture(mTextureTarget, TextureId); GLES20.GlTexParameteri(mTextureTarget, GLES20.GlTextureWrapS, GLES20.GlClampToEdge); GLES20.GlTexParameteri(mTextureTarget, GLES20.GlTextureWrapT, GLES20.GlClampToEdge); GLES20.GlTexParameteri(mTextureTarget, GLES20.GlTextureMinFilter, GLES20.GlNearest); GLES20.GlTexParameteri(mTextureTarget, GLES20.GlTextureMagFilter, GLES20.GlNearest); int numVertices = 4; if (numVertices != QUAD_COORDS.Length / COORDS_PER_VERTEX) { throw new Exception("Unexpected number of vertices in BackgroundRenderer."); } var bbVertices = ByteBuffer.AllocateDirect(QUAD_COORDS.Length * FLOAT_SIZE); bbVertices.Order(ByteOrder.NativeOrder()); mQuadVertices = bbVertices.AsFloatBuffer(); mQuadVertices.Put(QUAD_COORDS); mQuadVertices.Position(0); var bbTexCoords = ByteBuffer.AllocateDirect(numVertices * TEXCOORDS_PER_VERTEX * FLOAT_SIZE); bbTexCoords.Order(ByteOrder.NativeOrder()); mQuadTexCoord = bbTexCoords.AsFloatBuffer(); mQuadTexCoord.Put(QUAD_TEXCOORDS); mQuadTexCoord.Position(0); var bbTexCoordsTransformed = ByteBuffer.AllocateDirect(numVertices * TEXCOORDS_PER_VERTEX * FLOAT_SIZE); bbTexCoordsTransformed.Order(ByteOrder.NativeOrder()); mQuadTexCoordTransformed = bbTexCoordsTransformed.AsFloatBuffer(); int vertexShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlVertexShader, Resource.Raw.screenquad_vertex); int fragmentShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlFragmentShader, Resource.Raw.screenquad_fragment_oes); mQuadProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mQuadProgram, vertexShader); GLES20.GlAttachShader(mQuadProgram, fragmentShader); GLES20.GlLinkProgram(mQuadProgram); GLES20.GlUseProgram(mQuadProgram); ShaderUtil.CheckGLError(TAG, "Program creation"); mQuadPositionParam = GLES20.GlGetAttribLocation(mQuadProgram, "a_Position"); mQuadTexCoordParam = GLES20.GlGetAttribLocation(mQuadProgram, "a_TexCoord"); ShaderUtil.CheckGLError(TAG, "Program parameters"); }
// Compile & attach a |type| shader specified by |source| to |program|. private static void addShaderTo(int type, string source, int program) { int[] result = new int[] { GLES20.GlFalse }; int shader = GLES20.GlCreateShader(type); GLES20.GlShaderSource(shader, source); GLES20.GlCompileShader(shader); GLES20.GlGetShaderiv(shader, GLES20.GlCompileStatus, result, 0); abortUnless(result[0] == GLES20.GlTrue, GLES20.GlGetShaderInfoLog(shader) + ", source: " + source); GLES20.GlAttachShader(program, shader); GLES20.GlDeleteShader(shader); checkNoGLES2Error(); }
private int CreateProgram(string vertexSource, string fragmentSource) { var vertexShader = LoadShader(GLES20.GlVertexShader, vertexSource); if (vertexShader == 0) { return(0); } var fragmentShader = LoadShader(GLES20.GlFragmentShader, fragmentSource); if (fragmentShader == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { int[] shaderStatus = new int[1]; GLES20.GlAttachShader(program, vertexShader); program = DefaultProgramIfFail("glAttachShader", program); if (program == 0) { return(0); } GLES20.GlAttachShader(program, fragmentShader); program = DefaultProgramIfFail("glAttachShader", program); if (program == 0) { return(0); } GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { var error = "Could not link program: " + GLES20.GlGetProgramInfoLog(program); GLES20.GlDeleteProgram(program); return(0); } } return(program); }
public void compileShader() { int vShader = GLES20.GlCreateShader(GLES20.GlVertexShader); GLES20.GlShaderSource(vShader, shaderSource); GLES20.GlCompileShader(vShader); int[] compileStatus = new int[1]; GLES20.GlGetShaderiv(vShader, GLES20.GlCompileStatus, compileStatus, 0); if (compileStatus[0] != GLES20.GlTrue) { result += "vShader: \n"; result += GLES20.GlGetShaderInfoLog(vShader) + "\n"; ShowMessage.ShowCrash(result); } // ---------------------------------------------------------------------- int fShader = GLES20.GlCreateShader(GLES20.GlFragmentShader); GLES20.GlShaderSource(fShader, fragmentSource); GLES20.GlCompileShader(fShader); GLES20.GlGetShaderiv(fShader, GLES20.GlCompileStatus, compileStatus, 0); if (compileStatus[0] != GLES20.GlTrue) { result += "fShader: \n"; result += GLES20.GlGetShaderInfoLog(fShader) + "\n"; ShowMessage.ShowCrash(result); } // ---------------------------------------------------------------------- program = GLES20.GlCreateProgram(); GLES20.GlAttachShader(program, vShader); GLES20.GlAttachShader(program, fShader); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { result += "Could not link program: \n"; result += GLES20.GlGetProgramInfoLog(program) + "\n"; ShowMessage.ShowCrash(result); } }
/// <summary> /// Allocates and initializes OpenGL resources needed by the plane renderer. Must be /// called on the OpenGL thread, typically in /// <see cref="GLSurfaceView.IRenderer.OnSurfaceCreated(IGL10, Javax.Microedition.Khronos.Egl.EGLConfig)"/> /// </summary> /// <param name="context">Needed to access shader source and texture PNG.</param> /// <param name="gridDistanceTextureName">Name of the PNG file containing the grid texture.</param> public void CreateOnGlThread(Context context, String gridDistanceTextureName) { int vertexShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlVertexShader, Resource.Raw.plane_vertex); int passthroughShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlFragmentShader, Resource.Raw.plane_fragment); mPlaneProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mPlaneProgram, vertexShader); GLES20.GlAttachShader(mPlaneProgram, passthroughShader); GLES20.GlLinkProgram(mPlaneProgram); GLES20.GlUseProgram(mPlaneProgram); ShaderUtil.CheckGLError(TAG, "Program creation"); // Read the texture. var textureBitmap = Android.Graphics.BitmapFactory.DecodeStream( context.Assets.Open(gridDistanceTextureName)); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlGenTextures(mTextures.Length, mTextures, 0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear); GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0); GLES20.GlGenerateMipmap(GLES20.GlTexture2d); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); ShaderUtil.CheckGLError(TAG, "Texture loading"); mPlaneXZPositionAlphaAttribute = GLES20.GlGetAttribLocation(mPlaneProgram, "a_XZPositionAlpha"); mPlaneModelUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_Model"); mPlaneModelViewProjectionUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_ModelViewProjection"); mTextureUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_Texture"); mLineColorUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_lineColor"); mDotColorUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_dotColor"); mGridControlUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_gridControl"); mPlaneUvMatrixUniform = GLES20.GlGetUniformLocation(mPlaneProgram, "u_PlaneUvMatrix"); ShaderUtil.CheckGLError(TAG, "Program parameters"); }
public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config) { // Create the triangle SetupTriangle(); // Create the image information SetupImage(); // Set the clear color to yellow GLES20.GlClearColor(1.0f, 1.0f, 0f, 1); GLES20.GlEnable(GLES20.GlBlend); GLES20.GlBlendFunc(GLES20.GlOne, GLES20.GlOneMinusSrcAlpha); #region Solid colors mode /* * // Create the shaders, solid color * int vertexShader = ShaderHelper.LoadShader(GLES20.GlVertexShader, ShaderHelper.VsSolidColor); * int fragmentShader = ShaderHelper.LoadShader(GLES20.GlFragmentShader, ShaderHelper.FsSolidColor); * * ShaderHelper.SpSolidColor = GLES20.GlCreateProgram(); // create empty OpenGL ES Program * GLES20.GlAttachShader(ShaderHelper.SpSolidColor, vertexShader); // add the vertex shader to program * GLES20.GlAttachShader(ShaderHelper.SpSolidColor, fragmentShader); // add the fragment shader to program * GLES20.GlLinkProgram(ShaderHelper.SpSolidColor); // creates OpenGL ES program executables * * // Set our shader programm * GLES20.GlUseProgram(ShaderHelper.SpSolidColor); */ #endregion #region Texture mode // Create the shaders, images int vertexShader = ShaderHelper.LoadShader(GLES20.GlVertexShader, ShaderHelper.VsImage); int fragmentShader = ShaderHelper.LoadShader(GLES20.GlFragmentShader, ShaderHelper.FsImage); ShaderHelper.SpImage = GLES20.GlCreateProgram(); GLES20.GlAttachShader(ShaderHelper.SpImage, vertexShader); GLES20.GlAttachShader(ShaderHelper.SpImage, fragmentShader); GLES20.GlLinkProgram(ShaderHelper.SpImage); // Set our shader programm GLES20.GlUseProgram(ShaderHelper.SpImage); #endregion }
public Trajectory(int lineWidth) { mLineWidth = lineWidth; // Reset the model matrix to the identity Matrix.SetIdentityM(ModelMatrix, 0); // Allocate a vertex buffer ByteBuffer vertexByteBuffer = ByteBuffer.AllocateDirect(MAX_VERTICES * BYTES_PER_FLOAT); vertexByteBuffer.Order(ByteOrder.NativeOrder()); mVertexBuffer = vertexByteBuffer.AsFloatBuffer(); // Load the vertex and fragment shaders, then link the program int vertexShader = RenderUtils.loadShader(GLES20.GlVertexShader, mVertexShaderCode); int fragShader = RenderUtils.loadShader(GLES20.GlFragmentShader, mFragmentShaderCode); mProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgram, vertexShader); GLES20.GlAttachShader(mProgram, fragShader); GLES20.GlLinkProgram(mProgram); }
public static int CreateProgram(string vertexSource, string fragmentSource) { try { int vertexShader = LoadShader(GLES20.GlVertexShader, vertexSource); if (vertexShader == 0) { return(0); } int pixelShader = LoadShader(GLES20.GlFragmentShader, fragmentSource); if (pixelShader == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, vertexShader); CheckGlError("glAttachShader"); GLES20.GlAttachShader(program, pixelShader); CheckGlError("glAttachShader"); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { string info = GLES20.GlGetProgramInfoLog(program); GLES20.GlDeleteProgram(program); throw new RuntimeException("Could not link program: " + info); } } return(program); } catch (Exception e) { Console.WriteLine(e); return(0); } }
private static int loadShader(String vss, String fss) { int vshader = GLES20.GlCreateShader(GLES20.GlVertexShader); GLES20.GlShaderSource(vshader, vss); GLES20.GlCompileShader(vshader); int[] compiled = new int[1]; GLES20.GlGetShaderiv(vshader, GLES20.GlCompileStatus, compiled, 0); if (compiled[0] == 0) { //Log.e("Shader", "Could not compile vshader"); //Log.v("Shader", "Could not compile vshader:" + GLES20.glGetShaderInfoLog(vshader)); GLES20.GlDeleteShader(vshader); vshader = 0; } int fshader = GLES20.GlCreateShader(GLES20.GlFragmentShader); GLES20.GlShaderSource(fshader, fss); GLES20.GlCompileShader(fshader); GLES20.GlGetShaderiv(fshader, GLES20.GlCompileStatus, compiled, 0); if (compiled[0] == 0) { /*Log.e("Shader", "Could not compile fshader"); * Log.v("Shader", "Could not compile fshader:" + GLES20.glGetShaderInfoLog(fshader));*/ GLES20.GlDeleteShader(fshader); fshader = 0; } int program = GLES20.GlCreateProgram(); GLES20.GlAttachShader(program, vshader); GLES20.GlAttachShader(program, fshader); GLES20.GlLinkProgram(program); return(program); }
public static int CreateProgram(string vertexSource, string fragmentSource) { int vertexShader = LoadShader(GLES20.GlVertexShader, vertexSource); if (vertexShader == 0) { return(0); } int pixelShader = LoadShader(GLES20.GlFragmentShader, fragmentSource); if (pixelShader == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, vertexShader); CheckGLError("glAttachShader"); GLES20.GlAttachShader(program, pixelShader); CheckGLError("glAttachShader"); GLES20.GlLinkProgram(program); var linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus [0] != GLES20.GlTrue) { String info = GLES20.GlGetProgramInfoLog(program); GLES20.GlDeleteProgram(program); throw new InvalidOperationException("Could not link program: " + info); } } return(program); }
private int createProgram(String vertexSource, String fragmentSource) { int vertexShader = loadShader(35633, vertexSource); if (vertexShader == 0) { return(0); } int pixelShader = loadShader(35632, fragmentSource); if (pixelShader == 0) { return(0); } int program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, vertexShader); checkGlError("glAttachShader"); GLES20.GlAttachShader(program, pixelShader); checkGlError("glAttachShader"); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, 35714, linkStatus, 0); if (linkStatus[0] != 1) { Log.Error("DistortionRenderer", "Could not link program: "); Log.Error("DistortionRenderer", GLES20.GlGetProgramInfoLog(program)); GLES20.GlDeleteProgram(program); program = 0; } } return(program); }
/** * Compiles vertex and fragment shaders and links them into a program one * can use for rendering. Once OpenGL context is lost and onSurfaceCreated * is called, there is no need to reset existing GlslShader objects but one * can simply reload shader. * * @param vertexSource * String presentation for vertex shader * @param fragmentSource * String presentation for fragment shader */ public void SetProgram(string vertexSource, string fragmentSource) { _shaderVertex = LoadShader(GLES20.GlVertexShader, vertexSource); _shaderFragment = LoadShader(GLES20.GlFragmentShader, fragmentSource); var program = GLES20.GlCreateProgram(); if (program != 0) { GLES20.GlAttachShader(program, _shaderVertex); GLES20.GlAttachShader(program, _shaderFragment); GLES20.GlLinkProgram(program); int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(program, GLES20.GlLinkStatus, linkStatus, 0); if (linkStatus[0] != GLES20.GlTrue) { var error = GLES20.GlGetProgramInfoLog(program); DeleteProgram(); throw new Exception(error); } } _program = program; mShaderHandleMap.Clear(); }
/** * Creates and initializes OpenGL resources needed for rendering the model. * * @param context Context for loading the shader and below-named model and texture assets. * @param objAssetName Name of the OBJ file containing the model geometry. * @param diffuseTextureAssetName Name of the PNG file containing the diffuse texture map. */ public void CreateOnGlThread(Context context, string objAssetName, string diffuseTextureAssetName) { // Read the texture. var textureBitmap = BitmapFactory.DecodeStream(context.Assets.Open(diffuseTextureAssetName)); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlGenTextures(mTextures.Length, mTextures, 0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear); GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0); GLES20.GlGenerateMipmap(GLES20.GlTexture2d); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); textureBitmap.Recycle(); ShaderUtil.CheckGLError(TAG, "Texture loading"); // Read the obj file. var objInputStream = context.Assets.Open(objAssetName); var obj = ObjReader.Read(objInputStream); // Prepare the Obj so that its structure is suitable for // rendering with OpenGL: // 1. Triangulate it // 2. Make sure that texture coordinates are not ambiguous // 3. Make sure that normals are not ambiguous // 4. Convert it to single-indexed data obj = ObjUtils.ConvertToRenderable(obj); // OpenGL does not use Java arrays. ByteBuffers are used instead to provide data in a format // that OpenGL understands. // Obtain the data from the OBJ, as direct buffers: IntBuffer wideIndices = ObjData.GetFaceVertexIndices(obj, 3); FloatBuffer vertices = ObjData.GetVertices(obj); FloatBuffer texCoords = ObjData.GetTexCoords(obj, 2); FloatBuffer normals = ObjData.GetNormals(obj); // Convert int indices to shorts for GL ES 2.0 compatibility ShortBuffer indices = ByteBuffer.AllocateDirect(2 * wideIndices.Limit()) .Order(ByteOrder.NativeOrder()).AsShortBuffer(); while (wideIndices.HasRemaining) { indices.Put((short)wideIndices.Get()); } indices.Rewind(); var buffers = new int[2]; GLES20.GlGenBuffers(2, buffers, 0); mVertexBufferId = buffers[0]; mIndexBufferId = buffers[1]; // Load vertex buffer mVerticesBaseAddress = 0; mTexCoordsBaseAddress = mVerticesBaseAddress + 4 * vertices.Limit(); mNormalsBaseAddress = mTexCoordsBaseAddress + 4 * texCoords.Limit(); int totalBytes = mNormalsBaseAddress + 4 * normals.Limit(); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); GLES20.GlBufferData(GLES20.GlArrayBuffer, totalBytes, null, GLES20.GlStaticDraw); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mVerticesBaseAddress, 4 * vertices.Limit(), vertices); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mTexCoordsBaseAddress, 4 * texCoords.Limit(), texCoords); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mNormalsBaseAddress, 4 * normals.Limit(), normals); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); // Load index buffer GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); mIndexCount = indices.Limit(); GLES20.GlBufferData( GLES20.GlElementArrayBuffer, 2 * mIndexCount, indices, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); ShaderUtil.CheckGLError(TAG, "OBJ buffer load"); int vertexShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlVertexShader, Resource.Raw.object_vertex); int fragmentShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlFragmentShader, Resource.Raw.object_fragment); mProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgram, vertexShader); GLES20.GlAttachShader(mProgram, fragmentShader); GLES20.GlLinkProgram(mProgram); GLES20.GlUseProgram(mProgram); ShaderUtil.CheckGLError(TAG, "Program creation"); mModelViewUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelView"); mModelViewProjectionUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelViewProjection"); mPositionAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Position"); mNormalAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Normal"); mTexCoordAttribute = GLES20.GlGetAttribLocation(mProgram, "a_TexCoord"); mTextureUniform = GLES20.GlGetUniformLocation(mProgram, "u_Texture"); mLightingParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_LightingParameters"); mMaterialParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_MaterialParameters"); ShaderUtil.CheckGLError(TAG, "Program parameters"); Android.Opengl.Matrix.SetIdentityM(mModelMatrix, 0); }
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); }
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); }
void GLSurfaceView.IRenderer.OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config) { //Set the background clear color to gray GLES20.GlClearColor(0.5f, 0.5f, 0.5f, 0.5f); //Position the eye behind the origin. float eyeX = 0.0f; float eyeY = 0.0f; float eyeZ = 0.0f; //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 wold be pointing were we holding the camera float upX = 0.0f; float upY = 1.0f; float upZ = 0.0f; Matrix.SetLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); string vertexShader = "uniform mat4 u_MVPMatrix; \n" + "attribute vec4 a_Position;\n" + "attribute vec4 a_Color;\n" + "varying vec4 v_Color; \n" + "void main() \n" + "{ \n" + "v_Color = a_Color; \n" + "gl_Position = u_MVPMatrix \n" + "*a_Position; \n" + "} \n"; string fragmentShader = "precision mediump float; \n" + "varying vec4 v_Color; \n" + "void main() \n" + "{ \n" + "gl_FragColor=v_Color; \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); 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 ArgumentException("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); int[] compileStatus = new int[1]; GLES20.GlGetShaderiv(fragmentShaderHandle, GLES20.GlCompileStatus, compileStatus, 0); if (compileStatus[0] == 0) { GLES20.GlDeleteShader(fragmentShaderHandle); fragmentShaderHandle = 0; } } if (fragmentShaderHandle == 0) { throw new ArgumentException("Error createing 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 ArgumentException("Error creating program."); } //Set program handles. These will later be used to pass in values 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); }
public string Compile() { string result = string.Empty; string vertexShader = string.Empty; string fragmentShader = string.Empty; int resourceId = context.Resources.GetIdentifier(vertexShaderFile, "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(fragmentShaderFile, "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) { result += "vertex shader error"; result += GLES20.GlGetProgramInfoLog(vertexShaderHandle); GLES20.GlDeleteShader(vertexShaderHandle); vertexShaderHandle = 0; } } // 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) { result += "fragment shader error"; result += GLES20.GlGetProgramInfoLog(fragmentShaderHandle); GLES20.GlDeleteShader(fragmentShaderHandle); fragmentShaderHandle = 0; return(result); } } // Create a program object and store the handle to it. 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) { result += "shader link error"; result += GLES20.GlGetProgramInfoLog(programHandle); GLES20.GlDeleteProgram(programHandle); programHandle = 0; return(result); } } // 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"); return(result); }
public virtual void Attach(Shader shader) { GLES20.GlAttachShader(_handle, shader.Handle()); }
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 CreateOnGlThread(Context context, string objAssetName, string diffuseTextureAssetName) { // Read the texture. var textureBitmap = BitmapFactory.DecodeStream(context.Assets.Open(diffuseTextureAssetName)); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlGenTextures(mTextures.Length, mTextures, 0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear); GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear); GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0); GLES20.GlGenerateMipmap(GLES20.GlTexture2d); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); textureBitmap.Recycle(); ShaderUtil.CheckGLError(TAG, "Texture loading"); // Read the obj file. var objInputStream = context.Assets.Open(objAssetName); var obj = JavaGl.Obj.ObjReader.Read(objInputStream); obj = JavaGl.Obj.ObjUtils.ConvertToRenderable(obj); IntBuffer wideIndices = JavaGl.Obj.ObjData.GetFaceVertexIndices(obj, 3); FloatBuffer vertices = JavaGl.Obj.ObjData.GetVertices(obj); FloatBuffer texCoords = JavaGl.Obj.ObjData.GetTexCoords(obj, 2); FloatBuffer normals = JavaGl.Obj.ObjData.GetNormals(obj); ShortBuffer indices = ByteBuffer.AllocateDirect(2 * wideIndices.Limit()) .Order(ByteOrder.NativeOrder()).AsShortBuffer(); while (wideIndices.HasRemaining) { indices.Put((short)wideIndices.Get()); } indices.Rewind(); var buffers = new int[2]; GLES20.GlGenBuffers(2, buffers, 0); mVertexBufferId = buffers[0]; mIndexBufferId = buffers[1]; mVerticesBaseAddress = 0; mTexCoordsBaseAddress = mVerticesBaseAddress + 4 * vertices.Limit(); mNormalsBaseAddress = mTexCoordsBaseAddress + 4 * texCoords.Limit(); int totalBytes = mNormalsBaseAddress + 4 * normals.Limit(); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); GLES20.GlBufferData(GLES20.GlArrayBuffer, totalBytes, null, GLES20.GlStaticDraw); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mVerticesBaseAddress, 4 * vertices.Limit(), vertices); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mTexCoordsBaseAddress, 4 * texCoords.Limit(), texCoords); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mNormalsBaseAddress, 4 * normals.Limit(), normals); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); mIndexCount = indices.Limit(); GLES20.GlBufferData( GLES20.GlElementArrayBuffer, 2 * mIndexCount, indices, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); ShaderUtil.CheckGLError(TAG, "OBJ buffer load"); int vertexShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlVertexShader, Resource.Raw.object_vertex); int fragmentShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlFragmentShader, Resource.Raw.object_fragment); mProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgram, vertexShader); GLES20.GlAttachShader(mProgram, fragmentShader); GLES20.GlLinkProgram(mProgram); GLES20.GlUseProgram(mProgram); ShaderUtil.CheckGLError(TAG, "Program creation"); mModelViewUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelView"); mModelViewProjectionUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelViewProjection"); mPositionAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Position"); mNormalAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Normal"); mTexCoordAttribute = GLES20.GlGetAttribLocation(mProgram, "a_TexCoord"); mTextureUniform = GLES20.GlGetUniformLocation(mProgram, "u_Texture"); mLightingParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_LightingParameters"); mMaterialParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_MaterialParameters"); ShaderUtil.CheckGLError(TAG, "Program parameters"); Android.Opengl.Matrix.SetIdentityM(mModelMatrix, 0); }
/** * 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"); }