opengles2.0 headfirst Simple_VertexShader
来源:互联网 发布:淘宝金牌客服培训 编辑:程序博客网 时间:2024/06/07 03:10
在这篇文章里记录笔者在阅读《OpenGL(R) ES 2.0 Programming Guide》1-8章里面觉得重要的知识点,在开始分析代码之前,先分析两个api调用:
void glDrawArrays(GLenum mode , GLint first , GLsizei count )
mode specifies the primitive to render. Valid values are:
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
first specifies the starting vertex index in the enabled vertex arrays
count specifies the number of indices to be drawn.
void glDrawElements(GLenum mode , GLsizei count ,
GLenum type , const GLvoid * indices )
mode specifies the primitive to render. Valid values are:
GL_POINTS
GL_LINES
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
count specifies the number of indices
type specifies the type of element indices stored in indices.Valid
values are:
GL_UNSIGNED_BYTE
GL_UNSIGNED_SHORT
GL_UNSIGNED_INT —optional (can be used only if the
OES_element_index_uint extension is implemented)
indices specifies a pointer to location where element indices are stored.
大致概括下这块书上的分析,glDrawArrays在大量接续的,不共享的图元绘制情况下有很大优势;
但是在现实的绘制场景中(连续而大量共享顶点),glDrawElements能表现出更优的性能,减少内存和子宽的占用;比如在下面的场景中:
使用glDrawArrays实现,
#define VERTEX_POS_INDX 0#define NUM_FACES 6GLfloat vertices[] = { … }; // (x, y, z) per vertexglEnableVertexAttribArray(VERTEX_POS_INDX);glVertexAttribPointer(VERTEX_POS_INDX, 3, GL_FLOAT, GL_FALSE,0, vertices);for (i=0; i<NUM_FACES; i++){glDrawArrays(GL_TRIANGLE_FAN, first, 4);first += 4;}
或者
glDrawArrays(GL_TRIANGLES, 0, 36);为了绘制这个立方体,需要为每个面调用一次glDrawArrays,并且要为每个复用顶点进行复制,意味着本来的8个顶点,我们需要分配24个顶点的内存。或者36个顶点内存。
使用glDrawElements实现,
#define VERTEX_POS_INDX 0GLfloat vertices[] = { … };// (x, y, z) per vertexGLubyte indices[36] = { 0, 1, 2, 0, 2, 3,0, 3, 4, 0, 4, 5,0, 5, 6, 0, 6, 1,7, 6, 1, 7, 1, 2,7, 4, 5, 7, 5, 6,7, 2, 3, 7, 3, 4 };glEnableVertexAttribArray(VERTEX_POS_INDX);glVertexAttribPointer(VERTEX_POS_INDX, 3, GL_FLOAT, GL_FALSE,0, vertices);glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte),GL_UNSIGNED_BYTE, indices);
接下来我们分析下书本上的几个例子,这里贴出相关Opengles的部分,因为EGL部分都是通用的esutils来实现的,源码里面。书本上有几个知识点没有在例子代码上写出来,文章后面我单独列一下。
Simple_VertexShader:
//// Book: OpenGL(R) ES 2.0 Programming Guide// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner// ISBN-10: 0321502795// ISBN-13: 9780321502797// Publisher: Addison-Wesley Professional// URLs: http://safari.informit.com/9780321563835// http://www.opengles-book.com//// Simple_VertexShader.c//// This is a simple example that draws a rotating cube in perspective// using a vertex shader to transform the object//#include <stdlib.h>#include "esUtil.h"typedef struct{ // Handle to a program object GLuint programObject; // Attribute locations GLint positionLoc; // Uniform locations GLint mvpLoc; // Vertex daata GLfloat *vertices; GLuint *indices; int numIndices; // Rotation angle GLfloat angle; // MVP matrix ESMatrix mvpMatrix;} UserData;///// Initialize the shader and program object//int Init ( ESContext *esContext ){ UserData *userData = esContext->userData; GLbyte vShaderStr[] = "uniform mat4 u_mvpMatrix; \n" "attribute vec4 a_position; \n" "void main() \n" "{ \n" " gl_Position = u_mvpMatrix * a_position; \n" "} \n"; GLbyte fShaderStr[] = "precision mediump float; \n" "void main() \n" "{ \n" " gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); \n" "} \n"; // Load the shaders and get a linked program object userData->programObject = esLoadProgram ( vShaderStr, fShaderStr ); // Get the attribute locations userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" ); // Get the uniform locations userData->mvpLoc = glGetUniformLocation( userData->programObject, "u_mvpMatrix" ); // Generate the vertex data userData->numIndices = esGenCube( 1.0, &userData->vertices, NULL, NULL, &userData->indices ); // Starting rotation angle for the cube userData->angle = 45.0f; glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); return TRUE;}///// Update MVP matrix based on time//void Update ( ESContext *esContext, float deltaTime ){ UserData *userData = (UserData*) esContext->userData; ESMatrix perspective; ESMatrix modelview; float aspect; // Compute a rotation angle based on time to rotate the cube userData->angle += ( deltaTime * 40.0f ); if( userData->angle >= 360.0f ) userData->angle -= 360.0f; // Compute the window aspect ratio aspect = (GLfloat) esContext->width / (GLfloat) esContext->height; // Generate a perspective matrix with a 60 degree FOV esMatrixLoadIdentity( &perspective ); esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f ); // Generate a model view matrix to rotate/translate the cube esMatrixLoadIdentity( &modelview ); // Translate away from the viewer esTranslate( &modelview, 0.0, 0.0, -2.0 ); // Rotate the cube esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 ); // Compute the final MVP by multiplying the // modevleiw and perspective matrices together esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );}///// Draw a triangle using the shader pair created in Init()//void Draw ( ESContext *esContext ){ UserData *userData = esContext->userData; // Set the viewport glViewport ( 0, 0, esContext->width, esContext->height ); // Clear the color buffer glClear ( GL_COLOR_BUFFER_BIT ); // Use the program object glUseProgram ( userData->programObject ); // Load the vertex position glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), userData->vertices ); glEnableVertexAttribArray ( userData->positionLoc ); // Load the MVP matrix glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] ); // Draw the cube glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_INT, userData->indices ); eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );}///// Cleanup//void ShutDown ( ESContext *esContext ){ UserData *userData = esContext->userData; if ( userData->vertices != NULL ) { free ( userData->vertices ); } if ( userData->indices != NULL ) { free ( userData->indices ); } // Delete program object glDeleteProgram ( userData->programObject );}int main ( int argc, char *argv[] ){ ESContext esContext; UserData userData; esInitContext ( &esContext ); esContext.userData = &userData; esCreateWindow ( &esContext, "Simple Texture 2D", 320, 240, ES_WINDOW_RGB ); if ( !Init ( &esContext ) ) return 0; esRegisterDrawFunc ( &esContext, Draw ); esRegisterUpdateFunc ( &esContext, Update ); esMainLoop ( &esContext ); ShutDown ( &esContext );}
- opengles2.0 headfirst Simple_VertexShader
- opengles2.0 headfirst sample triangle
- openglES2.0 时代来临?
- opengles2.0中的纹理
- opengles2.0 shader备忘
- OpenGLes2.0 什么是Pbuffer
- ndk opengles2.0 配置
- Opengles2.0入门
- 浅学OpenGLES2.0
- 浅学OpenGLES2.0
- 浅学OpenGLES2.0
- OpenGLES2.0笔记
- OpenGLES2.0 概念
- OpenGLES2.0原理浅析
- Android OpenGLES2.0(一)——了解OpenGLES2.0
- Android OpenGLES2.0(一)——了解OpenGLES2.0
- Android opengles2.0 背景透明
- opengles2.0 programming guide: attribute
- json的初级使用
- 【JAVASE_学习笔记】流程控制语句
- 固定debain的IP
- java.lang.ClassNotFoundException: org.apache.commons.lang.exception.NestableRuntimeException
- windows装机过程
- opengles2.0 headfirst Simple_VertexShader
- 练习赛一 F AlvinZH的儿时梦想——机器人篇
- html点击按钮切换图片,并自动定时轮换
- 第三周项目一 顺序表的基本运算
- SDUT 3399 数据结构实验之排序二-交换排序
- ImageLoader的配置
- 反射
- MINST数据softmax进行数字识别
- Spring定时任务的实现方式--ScheduledExecutorService and ScheduledExecutorFactoryBean的简单源码解析以及使用