编译Shader代码
1.封装一个编译shader的接口
GLuint CompileShader(GLenum shaderType,const char *shaderCode){GLuint shader=glCreateShader(shaderType);glShaderSource(shader,1,&shaderCode,NULL);glCompileShader(shader);GLint compileResult=GL_TRUE;glGetShaderiv(shader,GL_COMPILE_STATUS,&compileResult);if(compileResult==GL_FALSE){char szLog[1024]={0};GLsizei logLen=0;glGetShaderInfoLog(shader,1024,&logLen,szLog);__android_log_print(ANDROID_LOG_INFO,"BattleFire","CompileShader %s\n%s\n",szLog,shaderCode);glDeleteShader(shader);shader=0;}return shader;
}
2.调用编译shader的接口
//编译shaderint filesize=0;unsigned char *filecontent=LoadfileContent("test.vs",filesize);GLuint vsshader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;filecontent=LoadfileContent("test.fs",filesize);GLuint fsshader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;
生成GPU程序
1.实现生成GPU程序接口
GLuint CreateProgram(GLuint vs,GLuint fs){GLuint program=glCreateProgram();glAttachShader(program,vs);glAttachShader(program,fs);glLinkProgram(program);glDetachShader(program,vs);glDetachShader(program,fs);GLint nResult;glGetProgramiv(program,GL_LINK_STATUS,&nResult);if(nResult==GL_FALSE){char szLog[1024]={0};GLsizei logLen=0;glGetProgramInfoLog(program,1024,&logLen,szLog);__android_log_print(ANDROID_LOG_INFO,"BattleFire","CreateProgram %s\n",szLog);glDeleteProgram(program);program=0;}return program;
}
2.编译与生成GPU程序合并封装
GLuint CreateStanarProgram(const char *vertex_shader_path,const char * fragment_shader_path)
{//编译shaderint filesize=0;unsigned char *filecontent=LoadfileContent(vertex_shader_path,filesize);GLuint vsShade = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;filecontent=LoadfileContent(fragment_shader_path,filesize);GLuint fsShader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;GLuint program=CreateProgram(vsShade,fsShader);glDeleteShader(vsShade);glDeleteShader(fsShader);return program;
}
配置好属性组并进行绘制
extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_Render(JNIEnv* env,jobject /* this */) {//__android_log_print(ANDROID_LOG_INFO,HANGYU_LOG_TAG,"Render");glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);glBindBuffer(GL_ARRAY_BUFFER,vbo);//设置状态机glUseProgram(program);glUniformMatrix4fv(modelMatrixLocation,1,GL_FALSE,glm::value_ptr(modelMatrix));//模型矩阵glUniformMatrix4fv(viewMatrixLocation,1,GL_FALSE,glm::value_ptr(viewMatrix));//视口矩阵glUniformMatrix4fv(projectionMatrixLocation,1,GL_FALSE,glm::value_ptr(projectionMatrix));//投影矩阵//set attribute//激活属性组glEnableVertexAttribArray(positionLocation);//激活属性位置glVertexAttribPointer(positionLocation,4,GL_FLOAT,GL_FALSE,sizeof(Vectice),0);
// glEnableVertexAttribArray(colorLocation);
// glVertexAttribPointer(colorLocation,4,GL_FLOAT,GL_FALSE,sizeof(float)*8,(void*)(sizeof(float)*4));glDrawArrays(GL_TRIANGLES,0,3);//从第0个点绘制,绘制三个点,会从vbo中取值glBindBuffer(GL_ARRAY_BUFFER,0);glUseProgram(0);}
属性在shader间的传递
1.VS
attribute vec4 position;
attribute vec4 color;
uniform mat4 U_ModelMatrix;
uniform mat4 U_ViewMatrix;
uniform mat4 U_ProjectionMatrix;
varying vec4 V_Color;
void main(){V_Color=color;gl_Position=U_ProjectionMatrix*U_ViewMatrix*U_ModelMatrix*position;
}
2.FS
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 V_Color;
void main(){gl_FragColor=V_Color;
}
模型矩阵的使用
1.在世界坐标Z为0的时候,由于平行不能看见任何东西。在这种情况我们可以使用模型矩阵整体平移(原理:是uniform变量,会影响所有点)
//平移
modelMatrix=glm::translate(0.0f,0.0f,-2.0f)
//缩放
glm::scale(0.5f,0.5f,0.5f)
//旋转
glm::rotate(30.0f,0.0f,0.0f,1.0f);//旋转角度,旋转哪个轴修改哪个轴
正交投影与2DUI元素的绘制
备注:透视投影,进大远小。
1.根据屏幕像素坐标来写绘图数据,而不需要3D坐标,使用前提必须写成以下内容才可以正确使用。
float half_width=float(width)/2.0f; //画布的宽
float half_height=float(height)/2.0f;//画布的高
//左边界,有边界,下边界,上边界,最近点,最远点
projectionMatrix=glm::ortho(-half_width,half_width,-half_height,half_height,0.1f,100.0f);
控制UI前后关系的方法之一
1.通过修改模型矩阵来修改UI前后关系。
2.可以通过修改Z的坐标来确定谁覆盖谁,前提是需要开启深度缓冲区才能管理物体远近关系。
glEnable(GL_DEPTH_TEST)
使用索引数据绘制UI
1.定义一个 GLuint ibo;//index buffer object ,element array buffer object
unsigned short indexes[]={ 0,1,2,1,3,2};glGenBuffers(1,&ibo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned short)*6, nullptr,GL_STATIC_DRAW);//alloc gpuglBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,sizeof(unsigned short)*6,indexes);//cpu -> gpu//glBufferData(GL_ARRAY_BUFFER,sizeof(Vertice)*3,vertices,GL_STATIC_DRAW);//cpu -> gpuglBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
2.绘制修改,改变的是绘制三角形的方式
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0);//glDrawArrays(GL_TRIANGLE_STRIP,0,4);glUniformMatrix4fv(modelMatrixLocation,1,GL_FALSE,glm::value_ptr(modelMatrix2));glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0);//glDrawArrays(GL_TRIANGLE_STRIP,0,4);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
封装VBO和IBO相关API
GLuint CreateBufferObject(GLenum type,void * data,int size,GLenum usage){GLuint object_to_ret;glGenBuffers(1,&object_to_ret);glBindBuffer(type,object_to_ret);glBufferData(type,size,data,usage);//cpu -> gpuglBindBuffer(type,0);return object_to_ret;
}
void UpdateBufferObject(GLuint object,GLenum type,void * data,int size,int offset){glBindBuffer(type,object);glBufferSubData(type,offset,size,data);//cpu -> gpuglBindBuffer(type,0);
}