void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); { vec3 e = { 0.0f, -4.0f, 0.0f }, c = { 0.0f, 0.0f, 0.0f }, u = { 0.0f, 0.0f, 1.0f }; GFX_look_at( &e, &c, &u ); } glBindVertexArrayOES( objmesh->vao ); if( auto_rotate ) rot_angle.z += 2.0f; GFX_rotate( rot_angle.x, 1.0f, 0.0f, 0.0f ); GFX_rotate( rot_angle.z, 0.0f, 0.0f, 1.0f ); PROGRAM_draw( program ); glDrawElements( GL_TRIANGLES, objmesh->objtrianglelist[ 0 ].n_indice_array, GL_UNSIGNED_SHORT, ( void * )NULL ); }
void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, -1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); //创建一个关键矩阵,并在Y轴上设置一个向后的偏移量,以便能够看到模型 GFX_load_identity(); { vec3 e = { 0.0f, -4.0f, 0.0f }, c = { 0.0f, 0.0f, 0.0f }, u = { 0.0f, 0.0f, 1.0f }; GFX_look_at( &e, &c, &u ); } //绑定VAO glBindVertexArrayOES( objmesh->vao ); if (auto_rotate) rot_angle.z += 2.0f; GFX_rotate(rot_angle.x, 1.0f, 0.0f, 0.0f); GFX_rotate(rot_angle.z, 0.0f, 0.0f, 1.0f); //设置绘制的着色器程序(自动使用glUseProgram绑定到着色器程序,然后发送program_draw_callback中执行指针,调用该函数) PROGRAM_draw( program ); //绘图语句 glDrawElements( GL_TRIANGLES, objmesh->objtrianglelist[ 0 ].n_indice_array, GL_UNSIGNED_SHORT, ( void * )NULL ); }
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(80.0f, (float)width / (float)height, 0.1f, 100.0f, -90.0f); obj = OBJ_load(OBJ_FILE, 1); unsigned int i = 0; while (i != obj->n_objmesh) { OBJ_optimize_mesh(obj, i, 128); OBJ_build_mesh(obj, i); OBJ_free_mesh_vertex_data(obj, i); ++i; } i = 0; while (i != obj->n_texture) { OBJ_build_texture(obj, i, obj->texture_path, TEXTURE_MIPMAP | TEXTURE_16_BITS, TEXTURE_FILTER_2X, 0.0f); ++i; } i = 0; while (i != obj->n_objmaterial) { OBJ_build_material(obj, i, NULL); ++i; } program = PROGRAM_create((char *)"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, 0, program_bind_attrib_location, NULL); PROGRAM_draw(program); glUniform1i(PROGRAM_get_uniform_location(program, (char *)"DIFFUSE"), 1); }
void templateAppInit( int width, int height ) { atexit( templateAppExit ); GFX_start(); init_physic_world(); gContactAddedCallback = contact_added_callback; 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, -90.0f ); obj = OBJ_load( OBJ_FILE, 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJ_build_mesh( obj, i ); OBJMESH *objmesh = &obj->objmesh[ i ]; if( !strcmp( objmesh->name, "Cube" ) ) { objmesh->rotation.x = objmesh->rotation.y = objmesh->rotation.z = 35.0f; add_rigid_body( objmesh, 1.0f ); } else add_rigid_body( objmesh, 0.0f ); OBJ_free_mesh_vertex_data( obj, i ); ++i; } program = PROGRAM_create( ( char * )"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, 0, program_bind_attrib_location, NULL ); PROGRAM_draw( program ); }
void load_game( void ) { init_physic_world(); gContactAddedCallback = contact_added_callback; obj = OBJ_load( OBJ_FILE, 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJMESH *objmesh = &obj->objmesh[ i ]; OBJ_optimize_mesh( obj, i, 128 ); OBJ_build_mesh( obj, i ); OBJ_free_mesh_vertex_data( obj, i ); ++i; } i = 0; while( i != obj->n_texture ) { OBJ_build_texture( obj, i, obj->texture_path, TEXTURE_MIPMAP | TEXTURE_16_BITS, TEXTURE_FILTER_2X, 0.0f ); ++i; } program = PROGRAM_create( ( char * )"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, 0, program_bind_attrib_location, NULL ); i = 0; while( i != obj->n_objmaterial ) { OBJ_build_material( obj, i, NULL ); ++i; } PROGRAM_draw( program ); glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 ); }
void load_game(void) { init_physic_world(); gContactAddedCallback = contact_added_callback; obj = OBJ_load(OBJ_FILE, 1); unsigned int i = 0; while (i != obj->n_objmesh) { OBJMESH *objmesh = &obj->objmesh[i]; OBJ_optimize_mesh(obj, i, 128); OBJ_build_mesh(obj, i); if (strstr(objmesh->name, "momo")) add_rigid_body(objmesh, SPHERE, 2.0f, 0); else if (strstr(objmesh->name, "barrel")) add_rigid_body(objmesh, CYLINDER, 1.0f, 0); else if (strstr(objmesh->name, "plank")) add_rigid_body(objmesh, BOX, 1.0f, 0); else if (strstr(objmesh->name, "ground")) add_rigid_body(objmesh, BOX, 0.0f, 0); else if (strstr(objmesh->name, "steel")) add_rigid_body(objmesh, CYLINDER, 0.0f, 0); else if (strstr(objmesh->name, "banana")) { add_rigid_body(objmesh, SPHERE, 1.0f, 1); objmesh->btrigidbody->setCollisionFlags(objmesh->btrigidbody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); objmesh->btrigidbody->forceActivationState(ISLAND_SLEEPING); ++banana; } else if (strstr(objmesh->name, "gameover")) { objmesh->visible = 0; gameover = objmesh; } OBJ_free_mesh_vertex_data(obj, i); ++i; } i = 0; while (i != obj->n_texture) { OBJ_build_texture(obj, i, obj->texture_path, TEXTURE_MIPMAP | TEXTURE_16_BITS, TEXTURE_FILTER_2X, 0.0f); ++i; } program = PROGRAM_create((char *)"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, 0, program_bind_attrib_location, NULL); i = 0; while (i != obj->n_objmaterial) { OBJ_build_material(obj, i, NULL); ++i; } PROGRAM_draw(program); glUniform1i(PROGRAM_get_uniform_location(program, (char *)"DIFFUSE"), 1); momo_index = 0; center.x = eye.x = 3.5f; get_next_momo(); }
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, -90.0f); obj = OBJ_load(OBJ_FILE, 1); unsigned int i = 0; while (i != obj->n_objmesh) { OBJ_build_mesh(obj, i); OBJ_free_mesh_vertex_data(obj, i); ++i; } program = PROGRAM_create((char *)"default", VERTEX_SHADER, FRAGMENT_SHADER, 1, 0, program_bind_attrib_location, NULL); PROGRAM_draw(program); }
void templateAppDraw(void) { glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); GFX_set_matrix_mode(MODELVIEW_MATRIX); GFX_load_identity(); if (view_delta.x || view_delta.y) { if (view_delta.y) next_rotz -= view_delta.y; if (view_delta.x) { next_rotx -= view_delta.x; next_rotx = CLAMP(next_rotx, 0.0f, 90.0f); } view_delta.x = view_delta.y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye.x = center.x + distance * cosf(rotx * DEG_TO_RAD) * sinf(rotz * DEG_TO_RAD); eye.y = center.y - distance * cosf(rotx * DEG_TO_RAD) * cosf(rotz * DEG_TO_RAD); eye.z = center.z + distance * sinf(rotx * DEG_TO_RAD); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center.x = maze->location.x; center.y = maze->location.y; center.z = maze->location.z; GFX_look_at(&eye, ¢er, &up); PROGRAM_draw(program); glUniform1i(PROGRAM_get_uniform_location(program, (char *)"DIFFUSE"), 1); unsigned int i = 0; while (i != obj->n_objmesh) { OBJMESH *objmesh = &obj->objmesh[i]; GFX_push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix((float *)&mat); memcpy(&objmesh->location, (vec3 *) & mat.m[3], sizeof(vec3)); GFX_multiply_matrix(&mat); glUniformMatrix4fv(PROGRAM_get_uniform_location(program, (char *)"MODELVIEWPROJECTIONMATRIX"), 1, GL_FALSE, (float *)GFX_get_modelview_projection_matrix()); OBJ_draw_mesh(obj, i); GFX_pop_matrix(); ++i; } NAVIGATION_draw(navigation); dynamicsworld->stepSimulation(1.0f / 60.0f); }
void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); if( view_delta.x || view_delta.y ) { if( view_delta.y ) next_rotz -= view_delta.y; if( view_delta.x ) { next_rotx -= view_delta.x; next_rotx = CLAMP( next_rotx, 0.0f, 90.0f ); } view_delta.x = view_delta.y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye.x = center.x + distance * cosf( rotx * DEG_TO_RAD ) * sinf( rotz * DEG_TO_RAD ); eye.y = center.y - distance * cosf( rotx * DEG_TO_RAD ) * cosf( rotz * DEG_TO_RAD ); eye.z = center.z + distance * sinf( rotx * DEG_TO_RAD ); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center.x = maze->location.x; center.y = maze->location.y; center.z = maze->location.z; GFX_look_at( &eye, ¢er, &up ); if( double_tap ) { vec3 location; if( GFX_unproject( view_location.x, viewport_matrix[ 3 ] - view_location.y, 1.0f, GFX_get_modelview_matrix(), GFX_get_projection_matrix(), viewport_matrix, &location.x, &location.y, &location.z ) ) { btVector3 ray_from( eye.x, eye.y, eye.z ), ray_to( location.x + eye.x, location.y + eye.y, location.z + eye.z ); btCollisionWorld::ClosestRayResultCallback collision_ray( ray_from, ray_to ); dynamicsworld->rayTest( ray_from, ray_to, collision_ray ); if( collision_ray.hasHit() && collision_ray.m_collisionObject == maze->btrigidbody ) { collision_ray.m_hitNormalWorld.normalize(); if( collision_ray.m_hitNormalWorld.z() == 1.0f ) { navigationpath_player.start_location.x = player->location.x; navigationpath_player.start_location.y = player->location.y; navigationpath_player.start_location.z = player->location.z; navigationpath_player.end_location.x = collision_ray.m_hitPointWorld.x(); navigationpath_player.end_location.y = collision_ray.m_hitPointWorld.y(); navigationpath_player.end_location.z = collision_ray.m_hitPointWorld.z(); if( NAVIGATION_get_path( navigation, &navigationpath_player, &navigationpathdata_player ) ) { player_next_point = 1; unsigned int i = 0; while( i != navigationpathdata_player.path_point_count + 1 ) { console_print( "%d: %f %f %f\n", i, navigationpathdata_player.path_point_array[ i ].x, navigationpathdata_player.path_point_array[ i ].y, navigationpathdata_player.path_point_array[ i ].z ); ++i; } printf( "\n" ); } } } } double_tap = 0; } if( navigationpathdata_player.path_point_count ) { move_entity( player, &navigationpathdata_player, &player_next_point, 3.0f ); } PROGRAM_draw( program ); glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJMESH *objmesh = &obj->objmesh[ i ]; GFX_push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat ); memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) ); GFX_multiply_matrix( &mat ); glUniformMatrix4fv( PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); OBJ_draw_mesh( obj, i ); GFX_pop_matrix(); ++i; } NAVIGATION_draw( navigation ); dynamicsworld->stepSimulation( 1.0f / 60.0f ); }
void draw_navigation_points( NAVIGATIONPATHDATA *navigationpathdata, vec3 *color ) { unsigned int i = 0; while( i != navigationpathdata->path_point_count + 1 ) { navigationpathdata->path_point_array[ i ].z = 1.0f; ++i; } glBindVertexArrayOES( 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( !path_point ) { path_point = PROGRAM_create( ( char * )"path_point", ( char * )"point_vert.glsl", ( char * )"point_frag.glsl", 1, 0, program_bind_attrib_location, NULL ); } PROGRAM_draw( path_point ); glUniformMatrix4fv( PROGRAM_get_uniform_location( path_point, ( char * )"MODELVIEWPROJECTIONMATRIX" ), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); glUniform3fv( PROGRAM_get_uniform_location( path_point, ( char * )"COLOR" ), 1, ( float * )color ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, navigationpathdata->path_point_array ); glDrawArrays( GL_POINTS, 0, navigationpathdata->path_point_count + 1 ); glDrawArrays( GL_LINE_STRIP, 0, navigationpathdata->path_point_count + 1 ); glDisable( GL_BLEND ); }
/*! 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 ); }
void templateAppDraw( void ) { glClearColor( 0.5f, 0.5f, 0.5f, 1.0f ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); GFX_set_matrix_mode( PROJECTION_MATRIX ); GFX_load_identity(); GFX_set_perspective( 80.0f, ( float )viewport_matrix[ 2 ] / ( float )viewport_matrix[ 3 ], 1.0f, 1000.0f, -90.0f ); if( game_over == 2 ) { templateAppExit(); load_game(); game_over = 0; } GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); if( view_delta.x || view_delta.y ) { if( view_delta.y ) next_rotz -= view_delta.y; if( view_delta.x ) { next_rotx -= view_delta.x; next_rotx = CLAMP( next_rotx, 0.0f, 90.0f ); } view_delta.x = view_delta.y = 0.0f; } rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; eye.x = center.x + distance * cosf( rotx * DEG_TO_RAD ) * sinf( rotz * DEG_TO_RAD ); eye.y = center.y - distance * cosf( rotx * DEG_TO_RAD ) * cosf( rotz * DEG_TO_RAD ); eye.z = center.z + distance * sinf( rotx * DEG_TO_RAD ); rotx = rotx * 0.9f + next_rotx * 0.1f; rotz = rotz * 0.9f + next_rotz * 0.1f; center.x = maze->location.x; center.y = maze->location.y; center.z = maze->location.z; GFX_look_at( &eye, ¢er, &up ); if( double_tap ) { vec3 location; if( GFX_unproject( view_location.x, viewport_matrix[ 3 ] - view_location.y, 1.0f, GFX_get_modelview_matrix(), GFX_get_projection_matrix(), viewport_matrix, &location.x, &location.y, &location.z ) ) { btVector3 ray_from( eye.x, eye.y, eye.z ), ray_to( location.x + eye.x, location.y + eye.y, location.z + eye.z ); btCollisionWorld::ClosestRayResultCallback collision_ray( ray_from, ray_to ); dynamicsworld->rayTest( ray_from, ray_to, collision_ray ); if( collision_ray.hasHit() && collision_ray.m_collisionObject == maze->btrigidbody ) { collision_ray.m_hitNormalWorld.normalize(); if( collision_ray.m_hitNormalWorld.z() == 1.0f ) { navigationpath_player.start_location.x = player->location.x; navigationpath_player.start_location.y = player->location.y; navigationpath_player.start_location.z = player->location.z; navigationpath_player.end_location.x = collision_ray.m_hitPointWorld.x(); navigationpath_player.end_location.y = collision_ray.m_hitPointWorld.y(); navigationpath_player.end_location.z = collision_ray.m_hitPointWorld.z(); if( NAVIGATION_get_path( navigation, &navigationpath_player, &navigationpathdata_player ) ) { player_next_point = 1; unsigned int i = 0; while( i != navigationpathdata_player.path_point_count + 1 ) { console_print( "%d: %f %f %f\n", i, navigationpathdata_player.path_point_array[ i ].x, navigationpathdata_player.path_point_array[ i ].y, navigationpathdata_player.path_point_array[ i ].z ); ++i; } printf( "\n" ); } } } } double_tap = 0; } if( navigationpathdata_player.path_point_count ) { vec3 color = { 0.0f, 0.0f, 1.0f }; draw_navigation_points( &navigationpathdata_player, &color ); move_entity( player, &navigationpathdata_player, &player_next_point, 3.0f ); } static unsigned int start_time = get_milli_time(); if( get_milli_time() - start_time > 1000 ) { navigationpath_enemy.start_location.x = enemy->location.x; navigationpath_enemy.start_location.y = enemy->location.y; navigationpath_enemy.start_location.z = enemy->location.z; navigationpath_enemy.end_location.x = player->location.x; navigationpath_enemy.end_location.y = player->location.y; navigationpath_enemy.end_location.z = player->location.z; NAVIGATION_get_path( navigation, &navigationpath_enemy, &navigationpathdata_enemy ); enemy_next_point = 1; start_time = get_milli_time(); } if( navigationpathdata_enemy.path_point_count ) { vec3 color = { 1.0f, 0.0f, 0.0f }; move_entity( enemy, &navigationpathdata_enemy, &enemy_next_point, 4.0f ); draw_navigation_points( &navigationpathdata_enemy, &color ); } PROGRAM_draw( program ); glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 ); unsigned int i = 0; while( i != obj->n_objmesh ) { OBJMESH *objmesh = &obj->objmesh[ i ]; GFX_push_matrix(); mat4 mat; objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat ); memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) ); GFX_multiply_matrix( &mat ); glUniformMatrix4fv( PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); OBJ_draw_mesh( obj, i ); GFX_pop_matrix(); ++i; } if( !game_over ) dynamicsworld->stepSimulation( 1.0f / 60.0f ); else { GFX_set_matrix_mode( PROJECTION_MATRIX ); GFX_load_identity(); float half_width = ( float )viewport_matrix[ 2 ] * 0.5f, half_height = ( float )viewport_matrix[ 3 ] * 0.5f; GFX_set_orthographic_2d( -half_width, half_width, -half_height, half_height ); GFX_rotate( -90.0f, 0.0f, 0.0f, 1.0f ); GFX_translate( -half_height, -half_width, 0.0f ); GFX_set_matrix_mode( MODELVIEW_MATRIX ); GFX_load_identity(); vec4 color = { 0.0f, 0.0f, 0.0f, 1.0f }; char msg[ MAX_CHAR ] = {"GAME OVER!"}; if( !font ) { font = FONT_init( ( char * )"foo.ttf" ); FONT_load( font, font->name, 1, 64.0f, 512, 512, 32, 96 ); } float posx = ( viewport_matrix[ 3 ] * 0.5f ) - ( FONT_length( font, msg ) * 0.5f ), posy = viewport_matrix[ 2 ] - font->font_size; FONT_print( font, posx + 4.0f, posy - 4.0f, msg, &color ); color.y = 1.0f; FONT_print( font, posx, posy, msg, &color ); } }
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 ); }