android native层的opengltest程序学习例子
来源:互联网 发布:python 绝技 目录 编辑:程序博客网 时间:2024/06/05 04:44
前段时间稍微看了看opengles,试着用android提供的java层代码写了几个小例子,最近几天找到了android6.01的源码中学习opengl的小例子,自己试着写了个小程序分享给大家。opengles从2.0开始编程用的shader变成了可进行编程的shader,书面点说就是由固定管线进化成了可编程管线,opengl 绘图会调用gpu提供的接口,最终工作在gpu中,所以可以减轻cpu的工作,从而在提高绘图效率的同时,减少cpu的消耗,起到降低功耗的目的。这里对这些基本的知识不再阐述,有时间慢慢学习了再给大家分享。另外android自身提供的opengles编程规范也是仿照opengl的,所以二者可以同时学习,但网上大多是1.0的资料,所以大家搜索时一定要搜索2.0的api进行学习。
今天要讲的不多,主要是把自己修改/LINUX/android/frameworks/native/opengl/tests/下的小例子展示给大家,这个例子绘制了一个旋转的同时移动的六面体,自己仿照网上的指导写了定点shader和片段shader,并利用了VBO提高性能。
Android.mk文件
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= \gl2_basic.cppLOCAL_SHARED_LIBRARIES := \libcutils \ libEGL \ libGLESv2 \ libui \ libgui \ libutilsLOCAL_STATIC_LIBRARIES += libglTestLOCAL_C_INCLUDES += $(call include-path-for, opengl-tests-includes)LOCAL_MODULE:= myopenglLOCAL_MODULE_TAGS := optionalLOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPESinclude $(BUILD_EXECUTABLE)
test.cpp程序
#include <stdlib.h>#include <stdio.h>#include <time.h>#include <sched.h>#include <sys/resource.h>#include <math.h>#include <EGL/egl.h>#include <GLES2/gl2.h>#include <GLES2/gl2ext.h>#include <utils/Timers.h>#include <WindowSurface.h>#include <EGLUtils.h>using namespace android;typedef struct _gmVector3 { GLfloat x; GLfloat y; GLfloat z; }gmVector3; typedef struct _gmMatrix4 { GLfloat m[16]; }gmMatrix4; typedef struct _gmVector2{ float x; float y;}gmVector2;typedef struct _gmVector4{ float x; float y; float z; float w;}gmVector4;void gmVec3Normalize(gmVector3* out, gmVector3* in){ GLfloat f = in->x * in->x + in->y * in->y + in->z * in->z; f = 1.0f / sqrt(f); out->x = in->x * f;out->y = in->y * f;out->z = in->z * f;}void gmVec3CrossProduct(gmVector3* out, gmVector3* v1, gmVector3* v2){ gmVector3 result; result.x = v1->y * v2->z - v1->z * v2->y; result.y = v1->z * v2->x - v1->x * v2->z; result.z = v1->x * v2->y - v1->y * v2->x; *out = result;}//实现移动的矩阵操作void gmMatrixTranslate(gmMatrix4* out, GLfloat x, GLfloat y, GLfloat z) { if (out == NULL) { return; } out->m[ 0]=1.0f; out->m[ 4]=0.0f; out->m[ 8]=0.0f; out->m[12]=x; out->m[ 1]=0.0f; out->m[ 5]=1.0f; out->m[ 9]=0.0f; out->m[13]=y; out->m[ 2]=0.0f; out->m[ 6]=0.0f; out->m[10]=1.0f; out->m[14]=z; out->m[ 3]=0.0f; out->m[ 7]=0.0f; out->m[11]=0.0f; out->m[15]=1.0f; } //缩放的操作void gmMatrixScale(gmMatrix4* out, GLfloat x, GLfloat y, GLfloat z) { if (out == NULL) { return; } out->m[ 0]=x; out->m[ 4]=0.0f; out->m[ 8]=0.0f; out->m[12]=0.0f; out->m[ 1]=0.0f; out->m[ 5]=y; out->m[ 9]=0.0f; out->m[13]=0.0f; out->m[ 2]=0.0f; out->m[ 6]=0.0f; out->m[10]=z; out->m[14]=0.0f; out->m[ 3]=0.0f; out->m[ 7]=0.0f; out->m[11]=0.0f; out->m[15]=1.0f; } //绕X旋转的操作void gmMatrixRotateX(gmMatrix4* out, GLfloat x){ if (out == NULL) { return; } GLfloat fcos, fsin; fcos = cos(x); fsin = sin(x); out->m[ 0]=1.0f;out->m[ 4]=0.0f;out->m[ 8]=0.0f;out->m[12]=0.0f;out->m[ 1]=0.0f;out->m[ 5]=fcos;out->m[ 9]=fsin;out->m[13]=0.0f;out->m[ 2]=0.0f;out->m[ 6]=-fsin;out->m[10]=fcos;out->m[14]=0.0f;out->m[ 3]=0.0f;out->m[ 7]=0.0f;out->m[11]=0.0f;out->m[15]=1.0f;}void gmMatrixRotateY(gmMatrix4* out, GLfloat y) { if (out == NULL) { return; } GLfloat fcos, fsin; fcos = cos(y); fsin = sin(y); out->m[ 0]=fcos; out->m[ 4]=0.0f; out->m[ 8]=-fsin; out->m[12]=0.0f; out->m[ 1]=0.0f; out->m[ 5]=1.0f; out->m[ 9]=0.0f; out->m[13]=0.0f; out->m[ 2]=fsin; out->m[ 6]=0.0f; out->m[10]=fcos; out->m[14]=0.0f; out->m[ 3]=0.0f; out->m[ 7]=0.0f; out->m[11]=0.0f; out->m[15]=1.0f; } void gmMatrixRotateZ(gmMatrix4* out, GLfloat z){ if (out == NULL) { return; } GLfloat fcos, fsin; fcos = cos(z); fsin = sin(z); out->m[ 0]=fcos; out->m[ 4]=fsin; out->m[ 8]=0.0f; out->m[12]=0.0f; out->m[ 1]=-fsin; out->m[ 5]=fcos; out->m[ 9]=0.0f; out->m[13]=0.0f; out->m[ 2]=0.0f; out->m[ 6]=0.0f; out->m[10]=1.0f; out->m[14]=0.0f; out->m[ 3]=0.0f; out->m[ 7]=0.0f; out->m[11]=0.0f; out->m[15]=1.0f;}void InitgmMatrix4(gmMatrix4* mat){ if (mat == NULL) { return; } memset(mat, 0, sizeof(gmMatrix4)); mat->m[0] = 1.0f; mat->m[1] = 1.0f; mat->m[2] = 1.0f; mat->m[3] = 1.0f;}void gmMatrixMultiply(gmMatrix4* out, gmMatrix4* m1, gmMatrix4* m2){ if (out == NULL || m1 == NULL || m2 == NULL) { return; } gmMatrix4 tmpout; tmpout.m[ 0] = m1->m[ 0]*m2->m[ 0] + m1->m[ 1]*m2->m[ 4] + m1->m[ 2]*m2->m[ 8] + m1->m[ 3]*m2->m[12]; tmpout.m[ 1] = m1->m[ 0]*m2->m[ 1] + m1->m[ 1]*m2->m[ 5] + m1->m[ 2]*m2->m[ 9] + m1->m[ 3]*m2->m[13]; tmpout.m[ 2] = m1->m[ 0]*m2->m[ 2] + m1->m[ 1]*m2->m[ 6] + m1->m[ 2]*m2->m[10] + m1->m[ 3]*m2->m[14]; tmpout.m[ 3] = m1->m[ 0]*m2->m[ 3] + m1->m[ 1]*m2->m[ 7] + m1->m[ 2]*m2->m[11] + m1->m[ 3]*m2->m[15]; tmpout.m[ 4] = m1->m[ 4]*m2->m[ 0] + m1->m[ 5]*m2->m[ 4] + m1->m[ 6]*m2->m[ 8] + m1->m[ 7]*m2->m[12]; tmpout.m[ 5] = m1->m[ 4]*m2->m[ 1] + m1->m[ 5]*m2->m[ 5] + m1->m[ 6]*m2->m[ 9] + m1->m[ 7]*m2->m[13]; tmpout.m[ 6] = m1->m[ 4]*m2->m[ 2] + m1->m[ 5]*m2->m[ 6] + m1->m[ 6]*m2->m[10] + m1->m[ 7]*m2->m[14]; tmpout.m[ 7] = m1->m[ 4]*m2->m[ 3] + m1->m[ 5]*m2->m[ 7] + m1->m[ 6]*m2->m[11] + m1->m[ 7]*m2->m[15]; tmpout.m[ 8] = m1->m[ 8]*m2->m[ 0] + m1->m[ 9]*m2->m[ 4] + m1->m[10]*m2->m[ 8] + m1->m[11]*m2->m[12]; tmpout.m[ 9] = m1->m[ 8]*m2->m[ 1] + m1->m[ 9]*m2->m[ 5] + m1->m[10]*m2->m[ 9] + m1->m[11]*m2->m[13]; tmpout.m[10] = m1->m[ 8]*m2->m[ 2] + m1->m[ 9]*m2->m[ 6] + m1->m[10]*m2->m[10] + m1->m[11]*m2->m[14]; tmpout.m[11] = m1->m[ 8]*m2->m[ 3] + m1->m[ 9]*m2->m[ 7] + m1->m[10]*m2->m[11] + m1->m[11]*m2->m[15]; tmpout.m[12] = m1->m[12]*m2->m[ 0] + m1->m[13]*m2->m[ 4] + m1->m[14]*m2->m[ 8] + m1->m[15]*m2->m[12]; tmpout.m[13] = m1->m[12]*m2->m[ 1] + m1->m[13]*m2->m[ 5] + m1->m[14]*m2->m[ 9] + m1->m[15]*m2->m[13]; tmpout.m[14] = m1->m[12]*m2->m[ 2] + m1->m[13]*m2->m[ 6] + m1->m[14]*m2->m[10] + m1->m[15]*m2->m[14]; tmpout.m[15] = m1->m[12]*m2->m[ 3] + m1->m[13]*m2->m[ 7] + m1->m[14]*m2->m[11] + m1->m[15]*m2->m[15]; *out = tmpout;}void gmMatrixLookAtLH(gmMatrix4* out, gmVector3* eye, gmVector3* at, gmVector3* up){ gmVector3 f, s, u; gmMatrix4 t; f.x = eye->x - at->x; f.y = eye->y - at->y; f.z = eye->z - at->z; //取最小值 gmVec3Normalize(&f, &f); gmVec3CrossProduct(&s, &f, up); gmVec3Normalize(&s, &s); gmVec3CrossProduct(&u, &s, &f); gmVec3Normalize(&u, &u); out->m[ 0] = s.x; out->m[ 1] = u.x; out->m[ 2] = -f.x; out->m[ 3] = 0; out->m[ 4] = s.y; out->m[ 5] = u.y; out->m[ 6] = -f.y; out->m[ 7] = 0; out->m[ 8] = s.z; out->m[ 9] = u.z; out->m[10] = -f.z; out->m[11] = 0; out->m[12] = 0; out->m[13] = 0; out->m[14] = 0; out->m[15] = 1; gmMatrixTranslate(&t, -eye->x, -eye->y, -eye->z); gmMatrixMultiply(out, &t, out);}void gmMatrixPerspectiveFovLH(gmMatrix4* out, GLfloat foy, GLfloat aspect, GLfloat near, GLfloat far){ GLfloat f, n; f = 1.0f / (GLfloat)tan(foy * 0.5f); n = 1.0f / (far - near); out->m[ 0] = f / aspect; out->m[ 1] = 0; out->m[ 2] = 0; out->m[ 3] = 0; out->m[ 4] = 0; out->m[ 5] = f; out->m[ 6] = 0; out->m[ 7] = 0; out->m[ 8] = 0; out->m[ 9] = 0; out->m[10] = far * n; out->m[11] = 1; out->m[12] = 0; out->m[13] = 0; out->m[14] = -far * near * n; out->m[15] = 0;}static void printGLString(const char *name, GLenum s) { // fprintf(stderr, "printGLString %s, %d\n", name, s); const char *v = (const char *) glGetString(s); // int error = glGetError(); // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, // (unsigned int) v); // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) // fprintf(stderr, "GL %s = %s\n", name, v); // else // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); fprintf(stderr, "GL %s = %s\n", name, v);}static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { if (returnVal != EGL_TRUE) { fprintf(stderr, "%s() returned %d\n", op, returnVal); } for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) { fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), error); }}static void checkGlError(const char* op) { for (GLint error = glGetError(); error; error = glGetError()) { fprintf(stderr, "after %s() glError (0x%x)\n", op, error); }}/*static const char gVertexShader[] = "attribute vec4 vPosition;\n""uniform mat4 vMatrix;\n""varying vec4 vColor;\n" "attribute vec4 aColor;\n" "void main() {\n" " gl_Position = vMatrix*vPosition;\n"" vColor=aColor;\n" "}\n";static const char gFragmentShader[] = "precision mediump float;\n""varying vec4 vColor;\n" "void main() {\n" " gl_FragColor = vColor;\n" "}\n";*/static const char gVertexShader[] = "precision mediump float;\n""attribute vec4 vPosition;\n""attribute vec4 aColor;\n" "uniform mat4 uMvp;\n""varying vec4 vColor;\n" "void main() {\n" "gl_Position = uMvp*vPosition;\n"" vColor = aColor;\n" "}\n";static const char gFragmentShader[] = "precision mediump float;\n""varying vec4 vColor;\n" "void main() {\n""gl_FragColor = vColor;\n" "}\n";GLuint loadShader(GLenum shaderType, const char* pSource) { GLuint shader = glCreateShader(shaderType); if (shader) { glShaderSource(shader, 1, &pSource, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = (char*) malloc(infoLen); if (buf) { glGetShaderInfoLog(shader, infoLen, NULL, buf); fprintf(stderr, "Could not compile shader %d:\n%s\n", shaderType, buf); free(buf); } glDeleteShader(shader); shader = 0; } } } return shader;}GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); if (!vertexShader) { return 0; } GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); if (!pixelShader) { return 0; } GLuint program = glCreateProgram(); if (program) { glAttachShader(program, vertexShader); checkGlError("glAttachShader"); glAttachShader(program, pixelShader); checkGlError("glAttachShader"); glLinkProgram(program); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = (char*) malloc(bufLength); if (buf) { glGetProgramInfoLog(program, bufLength, NULL, buf); fprintf(stderr, "Could not link program:\n%s\n", buf); free(buf); } } glDeleteProgram(program); program = 0; } } return program;}GLfloat cubePositions[] = { -0.5f,0.5f,0.5f, //正面左上0 -0.5f,-0.5f,0.5f, //正面左下1 0.5f,-0.5f,0.5f, //正面右下2 0.5f,0.5f,0.5f, //正面右上3 -0.5f,0.5f,-0.5f, //反面左上4 -0.5f,-0.5f,-0.5f, //反面左下5 0.5f,-0.5f,-0.5f, //反面右下6 0.5f,0.5f,-0.5f //反面右上7 };/*const GLfloat Vertices[] = { -0.5,-0.5,0,// 左下,黑色 0.5,-0.5,0, // 右下,红色 -0.5,0.5,0, // 左上,蓝色 0.5,0.5,0 // 右上,绿色};const GLshort Indices[] = { 0,1,2, // 三角形0 1,2,3 // 三角形1};*/void initMat(gmMatrix4* out){if (out == NULL) { return; } out->m[ 0]=1.0f; out->m[ 4]=0.0f; out->m[ 8]=0.0f; out->m[12]=0.0f; out->m[ 1]=0.0f; out->m[ 5]=1.0f; out->m[ 9]=0.0f; out->m[13]=0.0f; out->m[ 2]=0.0f; out->m[ 6]=0.0f; out->m[10]=1.0f; out->m[14]=0.0f; out->m[ 3]=0.0f; out->m[ 7]=0.0f; out->m[11]=0.0f; out->m[15]=1.0f; } /*const GLfloat Vertices[] = { -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, };*/ const GLfloat Vertices111[] = { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.5f, 0.5f, 1.0f, }; const GLfloat Vertices[] = { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.5f, 0.5f, 1.0f, }; const GLshort Indices1111[] = { 0, 1, 2, 1, 2, 3, 0, 4, 2, 6, 4, 2, 0, 1, 4, 1, 5, 4, 1, 3, 5, 3, 5, 7, 2, 3, 6, 3, 6, 7, 4, 5, 6, 5, 6, 7, };GLshort Indices[]={ 0,3,2,0,2,1, //正面 0,1,5,0,5,4, //左面 0,7,3,0,4,7, //上面 6,7,4,6,4,5, //后面 6,3,7,6,2,3, //右面 6,5,1,6,1,2 //下面 };//八个顶点的颜色,与顶点坐标一一对应GLfloat color[] = { 0.0f,1.0f,0.0f,1.0f, 0.0f,1.0f,0.0f,1.0f, 0.0f,1.0f,0.0f,1.0f, 0.0f,1.0f,0.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, };/////////////////////////////////////////gmMatrix4 mvp;GLuint gProgram;GLuint gvPositionHandle;GLuint gvColorHandle;GLuint uLocMvp; GLuint ibo;GLuint vbo;GLuint cbo;bool setupGraphics(int w, int h) { gProgram = createProgram(gVertexShader, gFragmentShader); if (!gProgram) { return false; } //否则颜色清除错误错误 glUseProgram(gProgram); checkGlError("glUseProgram"); uLocMvp = glGetUniformLocation(gProgram, "uMvp"); gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); checkGlError("glGetAttribLocation"); gvColorHandle = glGetAttribLocation(gProgram, "aColor"); checkGlError("glGetAttribLocation"); initMat(&mvp);glGenBuffers(1, &ibo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(Indices), Indices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER,sizeof(Vertices), Vertices, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, 0); return true;}gmMatrix4 model,view, proj; gmVector3 eye = {0.0f, 2.0f, -2.0f}; gmVector3 at = {0.0f, 0.0f, 0.0f}; gmVector3 up = {0.0f, 1.0f, 0.0f}; void setMatrix(GLfloat viewWidth , GLfloat viewHeight){gmMatrixLookAtLH(&view, &eye, &at, &up); gmMatrixPerspectiveFovLH(&proj, 3.1415f / 2, (GLfloat)viewWidth / (GLfloat)viewHeight, 1.0f, 1000.0f); }GLfloat angle = 0.0f;GLfloat tranx = 0.0f;int changeTime=1;GLfloat changeZ=0.0f;GLfloat flag=1.0f;void renderFrame(int _viewWidth ,int _viewHeight) {/*//多种效果复合 gmMatrix4 model, view, proj; gmMatrix4 modelnum; gmMatrix4 modelx, modely,modelz;//在多种变换同时施加到顶点上时以相反的顺序矩阵相乘 //gmMatrixTranslate(&model,tranx,0,0); // gmMatrixRotateY(&model, angle); gmMatrixRotateY(&modelx,angle); gmMatrixRotateZ(&modely,angle); gmMatrixRotateX(&modelz,angle); gmMatrixMultiply(&modelnum, &modelx, &modely); gmMatrixMultiply(&model, &modelnum, &modelz); angle += 0.05f;*/ gmMatrix4 modela,modelb, view, proj; gmMatrixTranslate(&modela,0,0,changeZ); gmMatrixRotateY(&modelb, angle); gmMatrixMultiply(&model, &modelb, &modela); changeZ=changeZ+0.001f; angle += 0.05f; if(angle>=44){ angle=0.0f; } gmVector3 eye = {0.0f, 0.0f, -2.0f}; gmVector3 at = {0.0f, 0.0f, 0.0f}; gmVector3 up = {0.0f, 1.0f, 0.0f}; gmMatrixLookAtLH(&view, &eye, &at, &up); gmMatrixPerspectiveFovLH(&proj, 3.1415f / 2, (float)_viewWidth / (float)_viewHeight, 1.0f, 1000.0f); gmMatrixMultiply(&mvp, &model, &view); gmMatrixMultiply(&mvp, &mvp, &proj); glUniformMatrix4fv(uLocMvp, 1, 0, (GLfloat*)&mvp); //剔除不需要的面,那其实言外之意就是我们认为逆时针为正面 // glEnable(GL_CULL_FACE); // glCullFace(GL_CW); //深度测试 glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); //glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); checkGlError("glClearColor"); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); checkGlError("glClear"); glUseProgram(gProgram); checkGlError("glUseProgram"); // glUseProgram(gProgram); // checkGlError("glUseProgram"); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, 0); //glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, vertices); checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(gvPositionHandle); checkGlError("glEnableVertexAttribArray"); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*7, 0); glVertexAttribPointer(gvColorHandle, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*7, (GLvoid*)(sizeof(GLfloat)*4)); //glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, vertices); checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(gvPositionHandle); checkGlError("glEnableVertexAttribArray");checkGlError("glVertexAttribPointer"); glEnableVertexAttribArray(gvColorHandle); checkGlError("glEnableVertexAttribArray"); //glBindBuffer(GL_ARRAY_BUFFER, gvColorHandle); // glVertexAttribPointer(gvColorHandle, 4, GL_FLOAT, GL_FALSE, 0, color); // glVertexAttribPointer(gvColorHandle, 4, GL_FLOAT, GL_FALSE, 0, 0); //checkGlError("glVertexAttribPointer"); //glEnableVertexAttribArray(gvColorHandle); // checkGlError("glEnableVertexAttribArray"); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glDrawElements(GL_TRIANGLES,36, GL_UNSIGNED_SHORT, 0); checkGlError("glDrawElements");}void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {#define X(VAL) {VAL, #VAL} struct {EGLint attribute; const char* name;} names[] = { X(EGL_BUFFER_SIZE), X(EGL_ALPHA_SIZE), X(EGL_BLUE_SIZE), X(EGL_GREEN_SIZE), X(EGL_RED_SIZE), X(EGL_DEPTH_SIZE), X(EGL_STENCIL_SIZE), X(EGL_CONFIG_CAVEAT), X(EGL_CONFIG_ID), X(EGL_LEVEL), X(EGL_MAX_PBUFFER_HEIGHT), X(EGL_MAX_PBUFFER_PIXELS), X(EGL_MAX_PBUFFER_WIDTH), X(EGL_NATIVE_RENDERABLE), X(EGL_NATIVE_VISUAL_ID), X(EGL_NATIVE_VISUAL_TYPE), X(EGL_SAMPLES), X(EGL_SAMPLE_BUFFERS), X(EGL_SURFACE_TYPE), X(EGL_TRANSPARENT_TYPE), X(EGL_TRANSPARENT_RED_VALUE), X(EGL_TRANSPARENT_GREEN_VALUE), X(EGL_TRANSPARENT_BLUE_VALUE), X(EGL_BIND_TO_TEXTURE_RGB), X(EGL_BIND_TO_TEXTURE_RGBA), X(EGL_MIN_SWAP_INTERVAL), X(EGL_MAX_SWAP_INTERVAL), X(EGL_LUMINANCE_SIZE), X(EGL_ALPHA_MASK_SIZE), X(EGL_COLOR_BUFFER_TYPE), X(EGL_RENDERABLE_TYPE), X(EGL_CONFORMANT), };#undef X for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { EGLint value = -1; EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); EGLint error = eglGetError(); if (returnVal && error == EGL_SUCCESS) { printf(" %s: ", names[j].name); printf("%d (0x%x)", value, value); } } printf("\n");}int printEGLConfigurations(EGLDisplay dpy) { EGLint numConfig = 0; EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig); checkEglError("eglGetConfigs", returnVal); if (!returnVal) { return false; } printf("Number of EGL configuration: %d\n", numConfig); EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig); if (! configs) { printf("Could not allocate configs.\n"); return false; } returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig); checkEglError("eglGetConfigs", returnVal); if (!returnVal) { free(configs); return false; } for(int i = 0; i < numConfig; i++) { printf("Configuration %d\n", i); printEGLConfiguration(dpy, configs[i]); } free(configs); return true;}int main(int argc, char** argv) { EGLBoolean returnValue; EGLConfig myConfig = {0}; EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; //第四步:指定需要的配置属性,一个EGL的配置描述了Surfaces上像素的格式信息。//当前我们要的是Windows的surface,在屏幕上是可见的,以EGL_NONE结尾。 EGLint s_configAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLint majorVersion; EGLint minorVersion; EGLContext context; EGLSurface surface; EGLint w, h; EGLDisplay dpy; checkEglError("<init>"); //获得默认的Display。通常我们只有一块屏幕,参数传EGL_DEFAULT_DISPLAY就可以了。 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); checkEglError("eglGetDisplay"); if (dpy == EGL_NO_DISPLAY) { printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); return 0; } //第三步:初始化EGL,如果我们不想要版本号,后两个参数也可以传NULL进去。 returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); checkEglError("eglInitialize", returnValue); fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); if (returnValue != EGL_TRUE) { printf("eglInitialize failed\n"); return 0; } if (!printEGLConfigurations(dpy)) { printf("printEGLConfigurations failed\n"); return 0; } checkEglError("printEGLConfigurations"); WindowSurface windowSurface; EGLNativeWindowType window = windowSurface.getSurface(); returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); if (returnValue) { printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); return 0; } checkEglError("EGLUtils::selectConfigForNativeWindow"); printf("Chose this configuration:\n"); // printEGLConfiguration(dpy, myConfig); //第六步:创建一个可画的surface。 surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); checkEglError("eglCreateWindowSurface"); if (surface == EGL_NO_SURFACE) { printf("gelCreateWindowSurface failed.\n"); return 0; } //第七步:创建Context。我们OpenGL ES的资源,比如纹理只有在这个context里是可见的。 context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); checkEglError("eglCreateContext"); if (context == EGL_NO_CONTEXT) { printf("eglCreateContext failed\n"); return 0; } //第八步:将创建的context绑定到当前的线程,使用我们创建的surface进行读和写。//Context绑定到线程上,可不用担心其他进程影响你的OpenGLES应用程序。 returnValue = eglMakeCurrent(dpy, surface, surface, context); checkEglError("eglMakeCurrent", returnValue); if (returnValue != EGL_TRUE) { return 0; }//Surface也有一些attribute,基本上都可以故名思意,//EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET //EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL,通过eglSurfaceAttrib()设置、eglQuerySurface()读取。 eglQuerySurface(dpy, surface, EGL_WIDTH, &w); checkEglError("eglQuerySurface"); eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); checkEglError("eglQuerySurface"); GLint dim = w < h ? w : h; fprintf(stderr, "Window dimensions: %d x %d\n", w, h); printGLString("Version", GL_VERSION); printGLString("Vendor", GL_VENDOR); printGLString("Renderer", GL_RENDERER); printGLString("Extensions", GL_EXTENSIONS); GLfloat rotatex=10; GLfloat step=0.001f; GLfloat angle = 0.1f; //开始绘制 if(!setupGraphics(w, h)) { fprintf(stderr, "Could not set up graphics.\n"); return 0; } for (;;) { renderFrame(w,h); eglSwapBuffers(dpy, surface); checkEglError("eglSwapBuffers"); } return 0;}
上面的程序直接放到源码中,利用Android.mk文件进行编译,会生成可执行的文件,push到android设备中,直接就可以执行看到效果。
0 0
- android native层的opengltest程序学习例子
- Android Service Framework (Native层的一个例子)
- android native层printf的一个bug
- 【PhoneGAP学习】Android PhoneGap框架(3)--重要知识点的预先学习 (JS层与 Native 层之间通信)
- Android NDK (学习笔记五) —— java层和native层进行字符串的交互处理
- android native层进程通信
- Android Native层log经验总结
- android--服务程序的例子
- Android系统的Binder机制及其native层应用
- android 中native 层的打印堆栈(c++)
- 在Android Native层直接调用MediaCodec接口的实现
- Android Java层与Native通信踩过的坑
- android native 程序崩溃的调试方法
- react native 学习实践----运行facebook官方提供的例子
- Android中framework层的cpp文件中调用native层c函数的方法
- Android Java层,Native层,Lib层打印Log简介
- Android开发Bitmap在Native层与Java层内存的两种生成方式
- Android开发Bitmap在Native层与Java层内存的两种生成方式
- Python selenium 三种等待方式详解
- python的sorted用法
- 微信小程序的简单登录
- [LeetCode]122. Best Time to Buy and Sell Stock II
- 机器学习13-支持向量机大边界的直观理解
- android native层的opengltest程序学习例子
- jsp的九大内置对象和四大作用域
- Node.js Buffer(缓冲区)
- 斐波那契博弈
- 重载,覆盖,隐藏
- java初学者集合类关系及注重事项
- 提高篇——复制字符串空格除外
- NYOJ 463
- Android网络访问之HttpURLConnection和HttpClient