【Android OpenGL ES 开发 (三)】Shader 扩展
生活随笔
收集整理的這篇文章主要介紹了
【Android OpenGL ES 开发 (三)】Shader 扩展
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
編譯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); }?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【Android OpenGL ES 开发 (三)】Shader 扩展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OPPO A38 手机渲染图和配置曝光,
- 下一篇: 【Android OpenGL ES 开