void templateAppDraw(void) { static const float POSITION[8] = { 0.0f, 0.0f, // Down left (pivot point) 1.0f, 0.0f, // Up left 0.0f, 1.0f, // Down right 1.0f, 1.0f // Up right }; static const float COLOR[16] = { 1.0f, 0.0f, 0.0f, 1.0f, // Red 0.0f, 1.0f, 0.0f, 1.0f, // Green 0.0f, 0.0f, 1.0f, 1.0f, // Blue 1.0f, 1.0f, 0.0f, 1.0f // Yellow }; glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); GFX_set_matrix_mode(MODELVIEW_MATRIX); GFX_load_identity(); GFX_scale(100.0f, 100.0f, 0.0f); if (program->pid) { char attribute, uniform; glUseProgram(program->pid); uniform = PROGRAM_get_uniform_location(program, (char *)"MODELVIEWPROJECTIONMATRIX"); glUniformMatrix4fv(uniform, 1 /* How many 4x4 matrix */ , GL_FALSE /* Transpose the matrix? */ , (float *)GFX_get_modelview_projection_matrix()); attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"POSITION"); glEnableVertexAttribArray(attribute); glVertexAttribPointer(attribute, 2, GL_FLOAT, GL_FALSE, 0, POSITION); attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"COLOR"); glEnableVertexAttribArray(attribute); glVertexAttribPointer(attribute, 4, GL_FLOAT, GL_FALSE, 0, COLOR); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } }
void templateAppInit(int width, int height) { GFX_start(); glViewport(0.0f, 0.0f, width, height); GFX_set_matrix_mode(PROJECTION_MATRIX); GFX_load_identity(); GFX_set_perspective(45.0f, (float)width / (float)height, 0.1f, 100.0f, 0.0f); program = PROGRAM_create((char *)"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, DEBUG_SHADERS, NULL, program_draw_callback); obj = OBJ_load(OBJ_FILE, 1); unsigned char *vertex_array = NULL, *vertex_start = NULL; unsigned int i = 0, index = 0, stride = 0, size = 0; objmesh = &obj->objmesh[0]; size = objmesh->n_objvertexdata * sizeof(vec3) * sizeof(vec3) * sizeof(vec2); vertex_array = (unsigned char *)malloc(size); vertex_start = vertex_array; while (i != objmesh->n_objvertexdata) { index = objmesh->objvertexdata[i].vertex_index; memcpy(vertex_array, &obj->indexed_vertex[index], sizeof(vec3)); vertex_array += sizeof(vec3); memcpy(vertex_array, &obj->indexed_normal[index], sizeof(vec3)); vertex_array += sizeof(vec3); memcpy(vertex_array, &obj->indexed_uv[objmesh->objvertexdata[i].uv_index], sizeof(vec2)); vertex_array += sizeof(vec2); ++i; } glGenBuffers(1, &objmesh->vbo); glBindBuffer(GL_ARRAY_BUFFER, objmesh->vbo); glBufferData(GL_ARRAY_BUFFER, size, vertex_start, GL_STATIC_DRAW); free(vertex_start); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &objmesh->objtrianglelist[0].vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[0].vbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[0].n_indice_array * sizeof(unsigned short), objmesh->objtrianglelist[0].indice_array, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); unsigned char attribute; stride = sizeof(vec3) + sizeof(vec3) + sizeof(vec2); glGenVertexArraysOES(1, &objmesh->vao); glBindVertexArrayOES(objmesh->vao); glBindBuffer(GL_ARRAY_BUFFER, objmesh->vbo); attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"POSITION"); glEnableVertexAttribArray(attribute); glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, stride, (void *)NULL); attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"NORMAL"); glEnableVertexAttribArray(attribute); glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(sizeof(vec3))); attribute = PROGRAM_get_vertex_attrib_location(program, (char *)"TEXCOORD0"); glEnableVertexAttribArray(attribute); glVertexAttribPointer(attribute, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(sizeof(vec3) + sizeof(vec3))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[0].vbo); glBindVertexArrayOES(0); texture = TEXTURE_create(obj->objmaterial[0].map_diffuse, obj->objmaterial[0].map_diffuse, 1, TEXTURE_MIPMAP, TEXTURE_FILTER_2X, 0.0f); }
/*! Helper function to debug draw the navigation mesh. Call this function at the end of your rendering loop to overlay the navigation mesh on top of your current scene. \param[in] navigation A valid NAVIGATION structure pointer. */ void NAVIGATION_draw( NAVIGATION *navigation ) { if( !navigation->program ) { navigation->program = PROGRAM_init( navigation->name ); navigation->program->vertex_shader = SHADER_init( navigation->name, GL_VERTEX_SHADER ); SHADER_compile( navigation->program->vertex_shader, "uniform highp mat4 MODELVIEWPROJECTIONMATRIX;" "attribute highp vec3 POSITION;" "void main( void ) {" "gl_Position = MODELVIEWPROJECTIONMATRIX * vec4( POSITION, 1.0 ); }", 0 ); navigation->program->fragment_shader = SHADER_init( navigation->name, GL_FRAGMENT_SHADER ); SHADER_compile( navigation->program->fragment_shader, "void main( void ) {" "gl_FragColor = vec4( 0.25, 0.5, 1.0, 0.65 ); }", 0 ); PROGRAM_link( navigation->program, 0 ); } char vertex_attribute = PROGRAM_get_vertex_attrib_location( navigation->program, ( char * )"POSITION" ); glBindVertexArrayOES( 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); PROGRAM_draw( navigation->program ); glUniformMatrix4fv( PROGRAM_get_uniform_location( navigation->program, ( char * )"MODELVIEWPROJECTIONMATRIX"), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); glEnableVertexAttribArray( vertex_attribute ); unsigned int j = 0; while( j != navigation->dtnavmesh->getMaxTiles() ) { dtMeshTile *_dtMeshTile = navigation->dtnavmesh->getTile( j ); if( !_dtMeshTile->header ) { continue; } unsigned int k = 0; while( k != _dtMeshTile->header->polyCount ) { dtPoly *_dtPoly = &_dtMeshTile->polys[ k ]; if( _dtPoly->type == DT_POLYTYPE_OFFMESH_CONNECTION ) { continue; } else { dtPolyDetail* pd = &_dtMeshTile->detailMeshes[ k ]; unsigned int l = 0; while( l != pd->triCount ) { vec3 v[ 3 ]; const unsigned char *t = &_dtMeshTile->detailTris[ ( pd->triBase + l ) << 2 ]; int m = 2; while( m != -1 ) { if( t[ m ] < _dtPoly->vertCount ) { memcpy( &v[ m ], &_dtMeshTile->verts[ _dtPoly->verts[ t[ m ] ] * 3 ], sizeof( vec3 ) ); recast_to_vec3( &v[ m ] ); } else { memcpy( &v[ m ], &_dtMeshTile->detailVerts[ ( pd->vertBase + t[ m ] - _dtPoly->vertCount ) * 3 ], sizeof( vec3 ) ); recast_to_vec3( &v[ m ] ); } --m; } glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, ( float * )v ); glDrawArrays( GL_TRIANGLES, 0, 3 ); ++l; } } ++k; } ++j; } glDisable( GL_BLEND ); }
//获取obj文件,再获取该文件的网格 void templateAppInit( int width, int height ) { atexit( templateAppExit ); GFX_start(); glViewport( 0.0f, 0.0f, width, height ); GFX_set_matrix_mode( PROJECTION_MATRIX ); GFX_load_identity(); //建立透视投影矩阵 GFX_set_perspective( 45.0f, ( float )width / ( float )height, 0.1f, 100.0f, 0.0f ); //新建一个可自动加载、编译和链接着色器程序的着色器程序 program = PROGRAM_create( ( char * )"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, DEBUG_SHADERS, NULL, //属性回调函数 program_draw_callback ); //绘制回调函数 //加载obj文件 obj = OBJ_load( OBJ_FILE, 1 ); unsigned char *vertex_array = NULL, *vertex_start = NULL; unsigned int i = 0, index = 0, stride = 0, size = 0; //获取结构指针中第一个网格的指针, objmesh = &obj->objmesh[ 0 ]; //里面包含多个obj文件的实体 //计算顶点数据数组的总大小,以便可以分配为VBO构建GLES友好的顶点数据数组所需的内存大小 size = objmesh->n_objvertexdata * sizeof( vec3 ) * sizeof( vec3 ); vertex_array = ( unsigned char * ) malloc( size ); vertex_start = vertex_array; //根据索引的顶点位置以及objmesh结构中包含的顶点法线构建顶点数据数组 while( i != objmesh->n_objvertexdata ) { index = objmesh->objvertexdata[ i ].vertex_index; memcpy( vertex_array, &obj->indexed_vertex[ index ], sizeof( vec3 ) ); vertex_array += sizeof( vec3 ); memcpy( vertex_array, &obj->indexed_normal[ index ], sizeof( vec3 ) ); vertex_array += sizeof( vec3 ); ++i; } //请求驱动程序为VBO创建一个新的缓冲区索引,并使其处于活动状态 glGenBuffers( 1, &objmesh->vbo ); glBindBuffer( GL_ARRAY_BUFFER, objmesh->vbo ); //将顶点数据数组从本地存储器转移到视频存储器 glBufferData( GL_ARRAY_BUFFER, size, vertex_start, GL_STATIC_DRAW ); free( vertex_start ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); //---------------------------------------------------- //为第一个objmesh三角形列表创建一个新id,并使当前索引处于活动状态 glGenBuffers( 1, &objmesh->objtrianglelist[ 0 ].vbo ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[ 0 ].vbo ); //以类似发送数组缓冲区的方式,将该索引数组发送到GPU glBufferData( GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[ 0 ].n_indice_array * sizeof( unsigned short ), objmesh->objtrianglelist[ 0 ].indice_array, GL_STATIC_DRAW ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); //创建VAO //计算不同顶点数据之间的顶点数组跨度 unsigned char attribute; stride = sizeof( vec3 )+ sizeof( vec3 ); //创建一个新的VAO索引,并使其保持活动状态 glGenVertexArraysOES( 1, &objmesh->vao ); glBindVertexArrayOES( objmesh->vao ); //开始构建VAO列表绑定,其中包括相关的调用来设置数组缓冲区 glBindBuffer( GL_ARRAY_BUFFER, objmesh->vbo ); //在VAO列表中包括POSITION顶点属性调用 attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"POSITION" ); glEnableVertexAttribArray( attribute ); glVertexAttribPointer( attribute, 3, GL_FLOAT, GL_FALSE, stride, ( void * )NULL ); //-------------------------------------------------------- //以处理顶点位置相同的方式处理顶点法线,但是顶点属性指针调用的最后一个参数稍有不同,必须指定距离下一个 //数据类型的偏移量 attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"NORMAL" ); glEnableVertexAttribArray( attribute ); glVertexAttribPointer( attribute, 3, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET( sizeof( vec3 ) ) ); //在关闭VAO列表之前绑定数组元素缓冲区(索引) glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, objmesh->objtrianglelist[ 0 ].vbo ); //停用当前的VAO,其次对前面所调用的类似数组的所有命令进行编译,然后将它们与VAO索引相关亮 glBindVertexArrayOES( 0 ); }
void templateAppDraw( void ) { static const float POSITION[ 12 ] = { -0.5f, 0.0f, -0.5f, // Bottom left 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, 0.5f // Top right }; static const float COLOR[ 16 ] = { 1.0f, 0.0f, 0.0f, 1.0f, // Red 0.0f, 1.0f, 0.0f, 1.0f, // Green 0.0f, 0.0f, 1.0f, 1.0f, // Blue 1.0f, 1.0f, 0.0f, 1.0f // Yellow }; glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); vec3 e = { 0.0f, -3.0f, 0.0f }, c = { 0.0f, 0.0f, 0.0f }, u = { 0.0f, 0.0f, 1.0f }; GFX_look_at( &e, &c, &u ); static float y = 0.0f; y += 0.1f; //GFX_translate( 0.0f, y, 0.0f ); GFX_rotate( y * 50.0f, 1.0f, 1.0f, 1.0f ); if( program->pid ) { char attribute, uniform; glUseProgram( program->pid ); uniform = PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ); glUniformMatrix4fv( uniform, 1 /* How many 4x4 matrix */, GL_FALSE /* Transpose the matrix? */, ( float * )GFX_get_modelview_projection_matrix() ); attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"POSITION" ); glEnableVertexAttribArray( attribute ); glVertexAttribPointer( attribute, 3, GL_FLOAT, GL_FALSE, 0, POSITION ); attribute = PROGRAM_get_vertex_attrib_location( program, ( char * )"COLOR" ); glEnableVertexAttribArray( attribute ); glVertexAttribPointer( attribute, 4, GL_FLOAT, GL_FALSE, 0, COLOR ); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } }
void FONT_print( FONT *font, float x, float y, char *text, vec4 *color ) { char vertex_attribute = PROGRAM_get_vertex_attrib_location( font->program, ( char * )"POSITION" ), texcoord_attribute = PROGRAM_get_vertex_attrib_location( font->program, ( char * )"TEXCOORD0" ); glBindVertexArrayOES( 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glDisable( GL_CULL_FACE ); glDisable( GL_DEPTH_TEST ); glDepthMask( GL_FALSE ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); PROGRAM_draw( font->program ); glUniformMatrix4fv( PROGRAM_get_uniform_location( font->program, ( char * )"MODELVIEWPROJECTIONMATRIX"), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); glUniform1i( PROGRAM_get_uniform_location( font->program, ( char * )"DIFFUSE" ), 0 ); if( color ) glUniform4fv( PROGRAM_get_uniform_location( font->program, ( char * )"COLOR" ), 1, ( float * )color ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, font->tid ); glEnableVertexAttribArray( vertex_attribute ); glEnableVertexAttribArray( texcoord_attribute ); while( *text ) { if( *text >= font->first_character && *text <= ( font->first_character + font->count_character ) ) { vec2 vert[ 4 ]; vec2 uv[ 4 ]; stbtt_aligned_quad quad; stbtt_bakedchar *bakedchar = font->character_data + ( *text - font->first_character ); int round_x = STBTT_ifloor( x + bakedchar->xoff ); int round_y = STBTT_ifloor( y - bakedchar->yoff ); quad.x0 = ( float )round_x; quad.y0 = ( float )round_y; quad.x1 = ( float )round_x + bakedchar->x1 - bakedchar->x0; quad.y1 = ( float )round_y - bakedchar->y1 + bakedchar->y0; quad.s0 = bakedchar->x0 / ( float )font->texture_width; quad.t0 = bakedchar->y0 / ( float )font->texture_width; quad.s1 = bakedchar->x1 / ( float )font->texture_height; quad.t1 = bakedchar->y1 / ( float )font->texture_height; x += bakedchar->xadvance; vert[ 0 ].x = quad.x1; vert[ 0 ].y = quad.y0; uv [ 0 ].x = quad.s1; uv [ 0 ].y = quad.t0; vert[ 1 ].x = quad.x0; vert[ 1 ].y = quad.y0; uv [ 1 ].x = quad.s0; uv [ 1 ].y = quad.t0; vert[ 2 ].x = quad.x1; vert[ 2 ].y = quad.y1; uv [ 2 ].x = quad.s1; uv [ 2 ].y = quad.t1; vert[ 3 ].x = quad.x0; vert[ 3 ].y = quad.y1; uv [ 3 ].x = quad.s0; uv [ 3 ].y = quad.t1; glVertexAttribPointer( vertex_attribute, 2, GL_FLOAT, GL_FALSE, 0, ( float * )&vert[ 0 ] ); glVertexAttribPointer( texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, ( float * )&uv[ 0 ] ); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } ++text; } glEnable( GL_CULL_FACE ); glEnable( GL_DEPTH_TEST ); glDepthMask( GL_TRUE ); glDisable( GL_BLEND ); }