Example #1
0
void bthresher_init(t_bthresher *x, short initialized)
{
int i; 

  if(!x->D)
    x->D = 256;
  if(!x->R)
    x->R = 44100;
  if(!power_of_two(x->overlap))
    x->overlap = 4;
  if(!power_of_two(x->winfac))
    x->winfac = 1;

  x->N = x->D * x->overlap;
  x->Nw = x->N * x->winfac;
    
limit_fftsize(&x->N,&x->Nw,OBJECT_NAME);

  x->mult = 1. / (float) x->N;
  x->N2 = (x->N)>>1;
  x->Nw2 = (x->Nw)>>1;
  x->in_count = -(x->Nw);
  x->c_fundamental =  (float) x->R/((x->N2)<<1 );
  x->c_factor_in =  (float) x->R/((float)x->D * TWOPI);
  x->c_factor_out = TWOPI * (float)  x->D / (float) x->R;
	      
	if(!initialized){
	  x->first_frame = 1;
	  x->max_hold_time = 60.0 ;
	  x->thresh_connected = 0;
	  x->damping_connected = 0;
	  x->thresh_scalar = 1;
	  x->damp_scalar = 1;
	  x->mute = 0;
	  x->bypass = 0;
	  x->inf_hold = 0;
	  x->Wanal = (float *) getbytes((MAX_Nw) * sizeof(float));	
	  x->Wsyn = (float *) getbytes((MAX_Nw) * sizeof(float));	
	  x->Hwin = (float *) getbytes((MAX_Nw) * sizeof(float));
	  x->input = (float *) getbytes((MAX_Nw) * sizeof(float));	
	  x->buffer = (float *) getbytes((MAX_N) * sizeof(float));
	  x->channel = (float *) getbytes(((MAX_N+2)) * sizeof(float));
	  x->output = (float *) getbytes((MAX_Nw) * sizeof(float));
	  x->bitshuffle = (int *) getbytes((MAX_N * 2) * sizeof(int));
	  x->trigland = (float *) getbytes((MAX_N * 2) * sizeof(float));

	  x->c_lastphase_in = (float *) getbytes((MAX_N2+1)* sizeof(float));
	  x->c_lastphase_out = (float *) getbytes((MAX_N2+1)* sizeof(float));
	  	  	  
	  x->composite_frame = (float *) getbytes( (MAX_N+2)* sizeof(float));
	  x->frames_left = (int *) getbytes((MAX_N+2)* sizeof(int));

	  // TRIPLETS OF bin# damp_factor threshold
	  x->list_data = (t_atom *) getbytes((MAX_N2 + 1) * 3 * sizeof(t_atom));

	  x->move_threshold = (float *) getbytes((MAX_N2+1)* sizeof(float));
	  x->damping_factor = (float *) getbytes((MAX_N2+1)* sizeof(float));
	  

	} 
  if(initialized == 0 || initialized == 1){
	  for(i = 0; i < x->N2+1; i++) {
	    x->move_threshold[i] = x->init_thresh;
	    x->damping_factor[i] = x->init_damping;
	  }
  }

	memset((char *)x->input,0,x->Nw * sizeof(float));
	memset((char *)x->output,0,x->Nw * sizeof(float));
	memset((char *)x->buffer,0,x->N * sizeof(float));
	memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float));
	memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float));


  x->tadv = (float) x->D / (float) x->R;
  x->max_hold_frames = x->max_hold_time / x->tadv;
  init_rdft(x->N, x->bitshuffle, x->trigland);
  makehanning(x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0);
}
void MovieTexture_FFMpeg::CreateTexture()
{
    if( m_uTexHandle )
        return;

	CHECKPOINT;

	RageTextureID actualID = GetID();
	actualID.iAlphaBits = 0;

	/* Cap the max texture size to the hardware max. */
	actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() );

	m_iSourceWidth  = decoder->m_stream->codec.width;
	m_iSourceHeight = decoder->m_stream->codec.height;

	/* image size cannot exceed max size */
	m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize );
	m_iImageHeight = min( m_iSourceHeight, actualID.iMaxSize );

	/* Texture dimensions need to be a power of two; jump to the next. */
	m_iTextureWidth = power_of_two(m_iImageWidth);
	m_iTextureHeight = power_of_two(m_iImageHeight);

	/* Bogus assignment to shut gcc up. */
    RageDisplay::PixelFormat pixfmt = RageDisplay::FMT_RGBA8;
	bool PreferHighColor = (TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32);
	m_AVTexfmt = FindCompatibleAVFormat( pixfmt, PreferHighColor );

	if( m_AVTexfmt == -1 )
		m_AVTexfmt = FindCompatibleAVFormat( pixfmt, !PreferHighColor );

	if( m_AVTexfmt == -1 )
	{
		/* No dice.  Use the first avcodec format of the preferred bit depth,
		 * and let the display system convert. */
		for( m_AVTexfmt = 0; AVPixelFormats[m_AVTexfmt].bpp; ++m_AVTexfmt )
			if( AVPixelFormats[m_AVTexfmt].HighColor == PreferHighColor )
				break;
		ASSERT( AVPixelFormats[m_AVTexfmt].bpp );

		switch( TEXTUREMAN->GetPrefs().m_iMovieColorDepth )
		{
		default:
			ASSERT(0);
		case 16:
			if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB5) )
				pixfmt = RageDisplay::FMT_RGB5;
			else
				pixfmt = RageDisplay::FMT_RGBA4; // everything supports RGBA4

			break;

		case 32:
			if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB8) )
				pixfmt = RageDisplay::FMT_RGB8;
			else if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGBA8) )
				pixfmt = RageDisplay::FMT_RGBA8;
			else if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB5) )
				pixfmt = RageDisplay::FMT_RGB5;
			else
				pixfmt = RageDisplay::FMT_RGBA4; // everything supports RGBA4
			break;
		}
	}
	
	if( !m_img )
	{
		const AVPixelFormat_t *pfd = &AVPixelFormats[m_AVTexfmt];

		LOG->Trace("format %i, %08x %08x %08x %08x",
			pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]);

		m_img = CreateSurface( m_iTextureWidth, m_iTextureHeight, pfd->bpp,
			pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );
	}

    m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_img, false );
}
Example #3
0
VALUE rb_big_barrett_mu(VALUE m)
{
    long len = RBIGNUM_LEN(m);
    return rb_big_div(power_of_two(2 * len * BITSPERDIG), m);
}
Example #4
0
//! A bit vector which interleaves the original bit_vector with rank information.
/*!
 * This class is a uncompressed bit vector representation. It copies the original
 * bit_vector and interleaves the data every t_bs bits with a cumulative
 * sum of set bits before the current position. Each cumulative sum is stored
 * in a 64 bit word.
 *
 * \tparam t_bs Block size in bits. t_bs has to be a power of 2 and t_bs >= 64.
 */
template<uint32_t t_bs=512>
class bit_vector_il
{
    private:
        static_assert(t_bs >= 64 , "bit_vector_il: blocksize must be be at least 64 bits.");
        static_assert(power_of_two(t_bs), "bit_vector_il: blocksize must be a power of two.");
    public:
        typedef bit_vector::size_type                       size_type;
        typedef size_type                                   value_type;
        typedef bit_vector::difference_type                 difference_type;
        typedef random_access_const_iterator<bit_vector_il> iterator;
        typedef bv_tag                                      index_category;

        friend class rank_support_il<1,t_bs>;
        friend class rank_support_il<0,t_bs>;
        friend class select_support_il<1,t_bs>;
        friend class select_support_il<0,t_bs>;

        typedef rank_support_il<1,t_bs>     rank_1_type;
        typedef rank_support_il<0,t_bs>     rank_0_type;
        typedef select_support_il<1,t_bs> select_1_type;
Example #5
0
GLuint Graphic::SDL_GL_LoadTexture( SDL_Surface *surface, GLfloat *texcoord ) {
    GLuint tex;
    int w, h;
    SDL_Surface *image;
    SDL_Rect area;
    SDL_BlendMode saved_mode;

    /* Use the surface width and height expanded to powers of 2 */
    w = power_of_two(surface->w);
    h = power_of_two(surface->h);
    texcoord[0] = 0.0f;         /* Min X */
    texcoord[1] = 0.0f;         /* Min Y */
    texcoord[2] = (GLfloat)surface->w / w;  /* Max X */
    texcoord[3] = (GLfloat)surface->h / h;  /* Max Y */

    image = SDL_CreateRGBSurface(
                SDL_SWSURFACE,
                w, h,
                32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
                0x000000FF,
                0x0000FF00,
                0x00FF0000,
                0xFF000000
#else
                0xFF000000,
                0x00FF0000,
                0x0000FF00,
                0x000000FF
#endif
            );
    if ( image == NULL ) {
        return 0;
    }

    SDL_GetSurfaceBlendMode(surface, &saved_mode);
    SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);

    /* Copy the surface into the GL texture image */
    area.x = 0;
    area.y = 0;
    area.w = surface->w;
    area.h = surface->h;
    SDL_BlitSurface(surface, &area, image, &area);

    SDL_SetSurfaceBlendMode(surface, saved_mode);
    /* Create an OpenGL texture for the image */
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGBA,
                 w, h,
                 0,
                 GL_RGBA,
                 GL_UNSIGNED_BYTE,
                 image->pixels);
    SDL_FreeSurface(image); /* No longer needed */

    return tex;
}
Example #6
0
void presidency_init(t_presidency *x, short initialized)
{
	int i;
	long oldsize,newsize;
	int oldN = x->N;
	int oldN2 = x->N2;
	int oldNw = x->Nw;
	int last_framecount = x->framecount;
	x->lock = 1;
	x->virgin = 1;
	
	if(!power_of_two(x->winfac))
		x->winfac = 1;
	if(!power_of_two(x->overlap))
		x->overlap = 4;
	if(!x->R)
		x->R = 44100;
	if(!x->D){
		x->D = 256;
		x->vector_size = x->D;
	}
	x->N = x->D * x->overlap;
	x->Nw = x->N * x->winfac;
	limit_fftsize(&x->N, &x->Nw, OBJECT_NAME);
	
	x->N2 = (x->N)>>1;
	x->Nw2 = (x->Nw)>>1;
	x->inCount = -(x->Nw);
	x->mult = 1. / (float) x->N;
//	post("mult %f N %d",x->mult,x->N);
	x->current_frame = 0;
	x->fpos = x->last_fpos = 0;
	x->tadv = (float)x->D/(float)x->R;
	x->c_fundamental = (float)x->R/((x->N2)<<1);
	x->c_factor_in = (float) x->R/((float)x->D * TWOPI);
	x->c_factor_out = TWOPI * (float)x->D / (float)x->R;
	x->table_length = 8192;
	x->table_si = (float) x->table_length / (float) x->R;
	x->pitch_increment = 1.0 * x->table_si;
	
	if( x->duration <= 0 ){
		x->duration = 1.0;
	}
	
	x->framecount =  x->duration / x->tadv ;
	x->hopsize = (float)x->N / x->overlap;
	x->read_me = 0;
	
	if(!initialized){
		x->mute = 0;
		x->in2_connected = 0;
		x->in3_connected = 0;
		x->sync = 0;
		x->playthrough = 0;
		x->frame_increment = 1.0;
		x->verbose = 0;
		x->table = (float *) getbytes(x->table_length * sizeof(float));
		x->Wanal = (float *) getbytes(MAX_Nw*sizeof(float));	
		x->Wsyn = (float *) getbytes(MAX_Nw*sizeof(float));	
		x->input = (float *) getbytes(MAX_Nw*sizeof(float));	
		x->Hwin = (float *) getbytes(MAX_Nw*sizeof(float));
		x->bindex = (float *) getbytes( (MAX_N+1) * sizeof(float) );
		x->buffer = (float *) getbytes(MAX_N*sizeof(float));
		x->channel = (float *) getbytes((MAX_N+2)*sizeof(float));
		x->output = (float *) getbytes(MAX_Nw*sizeof(float));
		x->bitshuffle = (int *) getbytes((MAX_N*2)*sizeof(int));
		x->trigland = (float *) getbytes((MAX_N*2)*sizeof(float));
		x->c_lastphase_in = (float *) getbytes((MAX_N2+1)*sizeof(float));
		x->c_lastphase_out = (float *) getbytes((MAX_N2+1)*sizeof(float));
		x->lastamp = (float *) getbytes((MAX_N+1) * sizeof(float));
		x->lastfreq = (float *) getbytes((MAX_N+1) * sizeof(float));
		x->local_frame = (float *) getbytes((MAX_N+2)*sizeof(float));
		x->loveboat = (float **) getbytes(x->framecount*sizeof(float *));
		

		/* here we stay with old reallocation approach and pray */
		for(i=0;i<x->framecount;i++){
			x->loveboat[i] = (float *) getbytes(((x->N)+2)*sizeof(float));
			if(x->loveboat[i] == NULL){
				error("memory error");
				return;
			}
			memset((char *)x->loveboat[i],0,(x->N+2)*sizeof(float));
		}
	} else if(initialized == 1) {
		//free and allocate
		oldsize = (oldN+2)*sizeof(float);
		for(i = 0; i < last_framecount; i++){
			freebytes(x->loveboat[i],oldsize) ;
		}
		oldsize = last_framecount*sizeof(float *);
		freebytes(x->loveboat,oldsize);
		x->loveboat = (float **) getbytes(x->framecount*sizeof(float *));  
		for(i=0;i<x->framecount;i++){
			x->loveboat[i] = (float *) getbytes((x->N+2)*sizeof(float));
			if(x->loveboat[i] == NULL){
				error("memory error");
				return;
			}
			memset((char *)x->loveboat[i],0,(x->N+2)*sizeof(float));
		}
	}  
	memset((char *)x->input,0,x->Nw * sizeof(float));
	memset((char *)x->output,0,x->Nw * sizeof(float));
	memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float));
	memset((char *)x->lastamp,0,(x->N+1)*sizeof(float));
	memset((char *)x->lastfreq,0,(x->N+1)*sizeof(float));
	memset((char *)x->bindex,0,(x->N+1)*sizeof(float));
	memset((char *)x->buffer,0,x->N * sizeof(float));
	if(!x->vector_size){
		post("zero vector size - something is really screwed up here!");
		return;
	}
	for ( i = 0; i < x->table_length; i++ ) {
		x->table[i] = (float) x->N * cos((float)i * TWOPI / (float)x->table_length);
	}	
	x->c_fundamental =  (float) x->R/(float)x->N ;
	x->c_factor_in =  (float) x->R/((float)x->vector_size * TWOPI);
	
	if( x->hi_freq < x->c_fundamental ) {
		x->hi_freq = x->topfreq ;
	}
	x->hi_bin = 1;  
	x->curfreq = 0;
	while( x->curfreq < x->hi_freq ) {
		++(x->hi_bin);
		x->curfreq += x->c_fundamental ;
	}
	
	x->lo_bin = 0;  
	x->curfreq = 0;
	while( x->curfreq < x->lo_freq ) {
		++(x->lo_bin);
		x->curfreq += x->c_fundamental ;
	}
	
	if( x->hi_bin > x->N2)
		x->hi_bin = x->N2 ;
	if(x->lo_bin > x->hi_bin)
		x->lo_bin = x->hi_bin;
	
	x->i_vector_size = 1.0/x->vector_size;
	x->pitch_increment = x->P*x->table_length/x->R;
	
	makewindows( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D);
	init_rdft( x->N, x->bitshuffle, x->trigland);

		  
	x->lock = 0;
}
Example #7
0
void pvtuner_init(t_pvtuner *x,short initialized)
{
    int i, j;
    int mem;
    float curfreq;

    if(!x->R)//temp init if MSP functions returned zero
        x->R = 44100;
    if(!x->D)
        x->D = 256;

    if(!power_of_two(x->overlap))
        x->overlap = 4;
    if(!power_of_two(x->winfac))
        x->winfac = 2;

    x->Iinv = 1./x->D;
    x->N = x->D * x->overlap;
    x->Nw = x->N * x->winfac;
    limit_fftsize(&x->N,&x->Nw,OBJECT_NAME);
    x->N2 = (x->N)>>1;
    x->Nw2 = (x->Nw)>>1;

    x->inCount = -(x->Nw);
    x->mult = 1. / (float) x->N;
    x->c_fundamental =  (float) x->R/(float)( (x->N2)<<1 );
    x->c_factor_in =  (float) x->R/((float)x->D * TWOPI);
    x->c_factor_out = TWOPI * (float)  x->D / (float) x->R;

    if(!initialized) {
        x->P = 1.0 ; // default
        x->bypass_state = 0;
        x->mute = 0;
        x->L = 8192;
        x->synt = .000001;
        mem = (MAX_Nw)*sizeof(float);
        x->Wanal = (float *) getbytes(mem);
        x->Wsyn = (float *) getbytes(mem);
        x->Hwin = (float *) getbytes(mem);
        x->input = (float *) getbytes(mem);
        x->output = (float *) getbytes(mem);
        mem = (MAX_N)*sizeof(float);
        x->buffer = (float *) getbytes(mem);
        mem = (MAX_N+2)*sizeof(float);
        x->channel = (float *) getbytes(mem);
        mem = (MAX_N*2)*sizeof(int);
        x->bitshuffle = (int *) getbytes(mem);
        mem = (MAX_N*2)*sizeof(float);
        x->trigland = (float *) getbytes(mem);
        mem = (MAXTONES+1)*sizeof(float);
        x->pitchgrid = (float *) getbytes(mem);
        mem = (MAX_N+1)*sizeof(float);
        x->lastamp = (float *) getbytes(mem);
        x->lastfreq = (float *) getbytes(mem);
        x->bindex = (float *) getbytes(mem);
        mem = (x->L)*sizeof(float);
        x->table = (float *) getbytes(mem);
        mem = (MAX_N2+1)*sizeof(float);
        x->c_lastphase_in = (float *) getbytes(mem);
        x->c_lastphase_out = (float *)getbytes(mem);

        x->pbase = BASE_FREQ;
        pvtuner_diatonic(x);// default scale
    }
    memset((char *)x->input,0,x->Nw * sizeof(float));
    memset((char *)x->output,0,x->Nw * sizeof(float));
    memset((char *)x->lastamp,0,(x->N+1) * sizeof(float));
    memset((char *)x->lastfreq,0,(x->N+1) * sizeof(float));
    memset((char *)x->bindex,0,(x->N+1) * sizeof(float));
    memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float));
    memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float));

    for ( i = 0; i < x->L; i++ ) {
        x->table[i] = (float) x->N * cos((float)i * TWOPI / (float)x->L);
    }

    if( x->hifreq < x->c_fundamental ) {
        x->hifreq = 3000.0 ;
    }

    x->hi_bin = 1;
    x->curfreq = 0;

    while( x->curfreq < x->hifreq ) {
        ++(x->hi_bin);
        x->curfreq += x->c_fundamental ;
    }

    x->lo_bin = 0;
    x->curfreq = 0;
    while( x->curfreq < x->lofreq ) {
        ++(x->lo_bin);
        x->curfreq += x->c_fundamental ;
    }

    if( x->hi_bin >= x->N2 )
        x->hi_bin = x->N2 - 1;

    x->hi_tune_bin = x->hi_bin;
    x->myPInc = x->P*x->L/x->R;
    x->ffac = x->P * PI/x->N;

    init_rdft( x->N, x->bitshuffle, x->trigland);
    makehanning( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0);

}
Example #8
0
//-----------------------------------------------------------------------------
// Purpose: Draws text to the screen inside the given rectangular region, using the given font
//-----------------------------------------------------------------------------
bool CGameEngineGL::BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText )
{
	if ( !hFont )
	{
		OutputDebugString( "Someone is calling BDrawString with a null font handle\n" );
		return false;
	}

	if ( !pchText || !*pchText )
	{
		return true;
	}

	// Very simple cache of complete strings as whole textures.
	// There are much better ways of doing efficient text rendering.
	// If nothing else we should expire the strings not being used.
	HGAMETEXTURE hTexture;
	char szFontPrefix[32];
	sprintf( szFontPrefix, "%d:", hFont );
	std::map< std::string, HGAMETEXTURE >::iterator iter;
	iter = m_MapStrings.find( std::string(szFontPrefix) + std::string(pchText) );
	if ( iter == m_MapStrings.end() )
	{
		static SDL_Color white = { 0xff, 0xff, 0xff, 0xff };

		// Calculate the text block size
		int nWrapLength = 0;
		int w, h;
		char *s = (char *)pchText;
		for ( char *p = strchr( s, '\n' ); p; p = strchr( s, '\n' ) )
		{
			*p = '\0';
			if ( TTF_SizeUTF8( m_MapGameFonts[ hFont ], s, &w, &h ) == 0 )
			{
				nWrapLength = std::max( w, nWrapLength );
			}
			*p = '\n';
			s = p + 1;
		}
		if ( TTF_SizeUTF8( m_MapGameFonts[ hFont ], s, &w, &h ) == 0 )
		{
			nWrapLength = std::max( w, nWrapLength );
		}
			
		SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped( m_MapGameFonts[ hFont ], pchText, white, nWrapLength );
		if ( !surface )
		{
			OutputDebugString( "Out of memory\n" );
			return false;
		}

		uint32 uWidth = power_of_two( surface->w );
		uint32 uHeight = power_of_two( surface->h );
		byte *pRGBAData = (byte *)malloc( uWidth*uHeight*4 );
		if ( !pRGBAData )
		{
			OutputDebugString( "Out of memory\n" );
			return false;
		}
		memset( pRGBAData, 0, uWidth*uHeight*4 );

		byte *src = (byte*)surface->pixels;
		byte *dst = pRGBAData;
		memset(dst, 0xff, uWidth*4);
		for ( uint32 row = 0; row < surface->h; ++row )
		{
			memcpy( dst, src, surface->w * 4 );
			src += surface->pitch;
			dst += uWidth * 4;
		}

		hTexture = HCreateTexture( pRGBAData, uWidth, uHeight );
		free( pRGBAData );

		// Record the actual text width and height
		m_MapTextures[ hTexture ].m_uWidth = surface->w;
		m_MapTextures[ hTexture ].m_uHeight = surface->h;

		SDL_FreeSurface( surface );

		m_MapStrings[ std::string(szFontPrefix) + std::string(pchText) ] = hTexture;
	}
	else
	{
		hTexture = iter->second;
	}

	int nWidth = m_MapTextures[ hTexture ].m_uWidth;
	int nHeight = m_MapTextures[ hTexture ].m_uHeight;
	float u = (float)nWidth / power_of_two(nWidth);
	float v = (float)nHeight / power_of_two(nHeight);

	// Get text position
	int nLeft = rect.left, nTop = rect.top;
	if ( dwFormat & TEXTPOS_TOP )
	{
		nTop = rect.top;
	}
	else if ( dwFormat & TEXTPOS_VCENTER )
	{
		nTop = rect.top + ((rect.bottom - rect.top) - nHeight) / 2;
	}
	else if ( dwFormat & TEXTPOS_BOTTOM )
	{
		nTop = rect.bottom - nHeight;
	}
	if ( dwFormat & TEXTPOS_LEFT )
	{
		nLeft = rect.left;
	}
	else if ( dwFormat & TEXTPOS_CENTER )
	{
		nLeft = rect.left + ((rect.right - rect.left) - nWidth) / 2;
	}
	else if ( dwFormat & TEXTPOS_RIGHT )
	{
		nLeft = rect.right - nWidth;
	}

//printf("Drawing text '%s' at %d,%d %dx%d {%d,%d %d,%d}\n", pchText, nLeft, nTop, nWidth, nHeight, rect.left, rect.top, rect.right, rect.bottom);
	return BDrawTexturedQuad( nLeft, nTop, nLeft + nWidth, nTop + nHeight, 0.0f, 0.0f, u, v, dwColor, hTexture );
}
Example #9
0
void resent_init(t_resent *x,short initialized)
{
  int i;
  int last_framecount = x->framecount;

  x->lock = 1;
  
  if(!x->D)
    x->D = 256;
  if(!x->R)
    x->R = 44100;
  if(!power_of_two(x->winfac))
    x->winfac = 1;
  if(!power_of_two(x->overlap))
    x->overlap = 1;

  x->verbose = 0; // testing only
  
  x->N = x->D * x->overlap;
  x->Nw = x->N * x->winfac;
  limit_fftsize(&x->N,&x->Nw,OBJECT_NAME);
  x->N2 = (x->N)>>1;
  x->Nw2 = (x->Nw)>>1;
  x->inCount = -(x->Nw);
  x->current_frame = x->framecount = 0;
  x->fpos = x->last_fpos = 0;
  x->tadv = (float)x->D/(float)x->R;
  x->mult = 1. / (float) x->N;
  x->c_fundamental =  (float) x->R/( (x->N2)<<1 );
  x->c_factor_in =  (float) x->R/((float)x->D * TWOPI);
  x->c_factor_out = TWOPI * (float)  x->D / (float) x->R;
  if(x->duration < .005){
    x->duration = 1.0;
  }
  x->framecount =  x->duration/x->tadv ;
  x->read_me = 0;

  if(!initialized){
    x->frame_increment = 1.0 ;  
    x->mute = 0;
    x->playthrough = 0;
    x->sync = 0;
    x->frames_read = 0;

    x->Wanal = (float *) getbytes( (MAX_Nw) * sizeof(float));	
    x->Wsyn = (float *) getbytes( (MAX_Nw) * sizeof(float));	
    x->Hwin = (float *) getbytes( (MAX_Nw) * sizeof(float));	
    x->input = (float *) getbytes( MAX_Nw * sizeof(float) );	
    x->output = (float *) getbytes( MAX_Nw * sizeof(float) );
	x->buffer = (float *) getbytes( MAX_N * sizeof(float) );
    x->channel = (float *) getbytes( (MAX_N+2) * sizeof(float) );
    x->bitshuffle = (int *) getbytes( MAX_N * 2 * sizeof( int ) );
    x->trigland = (float *) getbytes( MAX_N * 2 * sizeof( float ) );
    x->c_lastphase_in = (float *) getbytes( (MAX_N2+1) * sizeof(float) );
    x->c_lastphase_out = (float *) getbytes( (MAX_N2+1) * sizeof(float) );
    x->composite_frame = (float *) getbytes( (MAX_N+2) * sizeof(float) );
    x->frame_incr = (float *) getbytes( MAX_N2 * sizeof(float) );
    x->store_incr = (float *) getbytes( MAX_N2 * sizeof(float) );
    x->frame_phase = (float *) getbytes( MAX_N2 * sizeof(float) );
    x->loveboat = (float **) getbytes(x->framecount * sizeof(float *));

    for(i=0;i<x->framecount;i++){
      x->loveboat[i] = (float *) getbytes((x->N+2) * sizeof(float));
      if(x->loveboat[i] == NULL){
				error("Insufficient Memory!");
				return;
      }
      memset((char *)x->loveboat[i],0,(x->N+2) * sizeof(float));
    }
  } else if(initialized == 1){
    for(i = 0; i < last_framecount; i++){
      freebytes(x->loveboat[i],0) ;
    }
    freebytes(x->loveboat,0);
    x->loveboat = (float **) getbytes(x->framecount * sizeof(float *));
    for(i=0;i<x->framecount;i++){
      x->loveboat[i] = (float *) getbytes((x->N+2) *sizeof(float));
      if(x->loveboat[i] == NULL){
				error("Insufficient Memory!");
				return;
      }
      memset((char *)x->loveboat[i],0,(x->N+2) * sizeof(float));
    }
  }
	memset((char *)x->input,0,x->Nw * sizeof(float));
	memset((char *)x->output,0,x->Nw * sizeof(float));
	memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float));
	memset((char *)x->c_lastphase_out,0,(x->N2+1)* sizeof(float));
	memset((char *)x->frame_incr,0,(x->N2)* sizeof(float));
	memset((char *)x->store_incr,0,(x->N2) * sizeof(float));
	memset((char *)x->frame_phase,0,(x->N2) * sizeof(float));

	
  init_rdft( x->N, x->bitshuffle, x->trigland);
  x->hopsize = x->N / x->overlap;	
  makewindows( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D);

  
  x->lock = 0;
}
Example #10
0
void MovieTexture_Generic::CreateTexture()
{
	if( m_uTexHandle || m_pRenderTarget != nullptr )
		return;

	CHECKPOINT_M("About to create a generic texture.");

	m_iSourceWidth  = m_pDecoder->GetWidth();
	m_iSourceHeight = m_pDecoder->GetHeight();

	/* Adjust m_iSourceWidth to support different source aspect ratios. */
	float fSourceAspectRatio = m_pDecoder->GetSourceAspectRatio();
	if( fSourceAspectRatio < 1 )
		m_iSourceHeight = std::lrint( m_iSourceHeight / fSourceAspectRatio );
	else if( fSourceAspectRatio > 1 )
		m_iSourceWidth = std::lrint( m_iSourceWidth * fSourceAspectRatio );

	/* HACK: Don't cap movie textures to the max texture size, since we
	 * render them onto the texture at the source dimensions.  If we find a
	 * fast way to resize movies, we can change this back. */
	m_iImageWidth = m_iSourceWidth;
	m_iImageHeight = m_iSourceHeight;

	/* Texture dimensions need to be a power of two; jump to the next. */
	m_iTextureWidth = power_of_two( m_iImageWidth );
	m_iTextureHeight = power_of_two( m_iImageHeight );
	MovieDecoderPixelFormatYCbCr fmt = PixelFormatYCbCr_Invalid;
	if( m_pSurface == nullptr )
	{
		ASSERT( m_pTextureLock == nullptr );
		if( g_bMovieTextureDirectUpdates )
			m_pTextureLock = DISPLAY->CreateTextureLock();

		m_pSurface = m_pDecoder->CreateCompatibleSurface( m_iImageWidth, m_iImageHeight,
			TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32, fmt );
		if( m_pTextureLock != nullptr )
		{
			delete [] m_pSurface->pixels;
			m_pSurface->pixels = nullptr;
		}

	}

	RagePixelFormat pixfmt = DISPLAY->FindPixelFormat( m_pSurface->format->BitsPerPixel,
			m_pSurface->format->Mask[0],
			m_pSurface->format->Mask[1],
			m_pSurface->format->Mask[2],
			m_pSurface->format->Mask[3] );

	if( pixfmt == RagePixelFormat_Invalid )
	{
		/* We weren't given a natively-supported pixel format.  Pick a supported
		 * one.  This is a fallback case, and implies a second conversion. */
		int depth = TEXTUREMAN->GetPrefs().m_iMovieColorDepth;
		switch( depth )
		{
		default:
			FAIL_M(fmt::sprintf("Unsupported movie color depth: %i", depth));
		case 16:
			if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) )
				pixfmt = RagePixelFormat_RGB5;
			else
				pixfmt = RagePixelFormat_RGBA4;

			break;

		case 32:
			if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB8) )
				pixfmt = RagePixelFormat_RGB8;
			else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGBA8) )
				pixfmt = RagePixelFormat_RGBA8;
			else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) )
				pixfmt = RagePixelFormat_RGB5;
			else
				pixfmt = RagePixelFormat_RGBA4;
			break;
		}
	}

	if( fmt != PixelFormatYCbCr_Invalid )
	{
		Rage::safe_delete( m_pTextureIntermediate );
		m_pSprite->UnloadTexture();

		/* Create the render target.  This will receive the final, converted texture. */
		RenderTargetParam param;
		param.iWidth = m_iImageWidth;
		param.iHeight = m_iImageHeight;

		RageTextureID TargetID( GetID() );
		TargetID.filename += " target";
		m_pRenderTarget = new RageTextureRenderTarget( TargetID, param );

		/* Create the intermediate texture.  This receives the YUV image. */
		RageTextureID IntermedID( GetID() );
		IntermedID.filename += " intermediate";

		m_pTextureIntermediate = new RageMovieTexture_Generic_Intermediate( IntermedID,
			m_pDecoder->GetWidth(), m_pDecoder->GetHeight(),
			m_pSurface->w, m_pSurface->h,
			power_of_two(m_pSurface->w), power_of_two(m_pSurface->h),
			*m_pSurface->format, pixfmt );

		/* Configure the sprite.  This blits the intermediate onto the ifnal render target. */
		m_pSprite->SetHorizAlign( align_left );
		m_pSprite->SetVertAlign( align_top );

		/* Hack: Sprite wants to take ownership of the texture, and will decrement the refcount
		 * when it unloads the texture.  Normally we'd make a "copy", but we can't access
		 * RageTextureManager from here.  Just increment the refcount. */
		++m_pTextureIntermediate->m_iRefCount;
		m_pSprite->SetTexture( m_pTextureIntermediate );
		m_pSprite->SetEffectMode( GetEffectMode(fmt) );

		return;
	}

	m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_pSurface, false );
}
Example #11
0
/*
 * Each dwMaxSize, dwTextureColorDepth and iAlphaBits are maximums; we may
 * use less.  iAlphaBits must be 0, 1 or 4.
 *
 * XXX: change iAlphaBits == 4 to iAlphaBits == 8 to indicate "as much alpha
 * as needed", since that's what it really is; still only use 4 in 16-bit textures.
 *
 * Dither forces dithering when loading 16-bit textures.
 * Stretch forces the loaded image to fill the texture completely.
 */
void RageBitmapTexture::Create()
{
	RageTextureID actualID = GetID();

	ASSERT( actualID.filename != "" );

	/* Create (and return) a surface ready to be loaded to OpenGL */
	/* Load the image into a RageSurface. */
	CString error;
	RageSurface *img = RageSurfaceUtils::LoadFile( actualID.filename, error );

	/* Tolerate corrupt/unknown images. */
	if( img == NULL )
	{
		CString sWarning = ssprintf( "RageBitmapTexture: Couldn't load %s: %s", actualID.filename.c_str(), error.c_str() );
		Dialog::OK( sWarning );
		img = RageSurfaceUtils::MakeDummySurface( 64, 64 );
		ASSERT( img != NULL );
	}

	if( actualID.bHotPinkColorKey )
		RageSurfaceUtils::ApplyHotPinkColorKey( img );

	{
		/* Do this after setting the color key for paletted images; it'll also return
		 * TRAIT_NO_TRANSPARENCY if the color key is never used. */
		int traits = RageSurfaceUtils::FindSurfaceTraits(img);
		if( traits & RageSurfaceUtils::TRAIT_NO_TRANSPARENCY )
			actualID.iAlphaBits = 0;
		else if( traits & RageSurfaceUtils::TRAIT_BOOL_TRANSPARENCY )
			actualID.iAlphaBits = 1;
	}

	// look in the file name for a format hints
	CString HintString = GetID().filename + actualID.AdditionalTextureHints;
	HintString.MakeLower();

	if( HintString.find("32bpp") != CString::npos )			actualID.iColorDepth = 32;
	else if( HintString.find("16bpp") != CString::npos )		actualID.iColorDepth = 16;
	if( HintString.find("dither") != CString::npos )		actualID.bDither = true;
	if( HintString.find("stretch") != CString::npos )		actualID.bStretch = true;
	if( HintString.find("mipmaps") != CString::npos )		actualID.bMipMaps = true;
	if( HintString.find("nomipmaps") != CString::npos )		actualID.bMipMaps = false;	// check for "nomipmaps" after "mipmaps"

	/* If the image is marked grayscale, then use all bits not used for alpha
	 * for the intensity.  This way, if an image has no alpha, you get an 8-bit
	 * grayscale; if it only has boolean transparency, you get a 7-bit grayscale. */
	if( HintString.find("grayscale") != CString::npos )		actualID.iGrayscaleBits = 8-actualID.iAlphaBits;

	/* This indicates that the only component in the texture is alpha; assume all
	 * color is white. */
	if( HintString.find("alphamap") != CString::npos )		actualID.iGrayscaleBits = 0;

	/* No iGrayscaleBits for images that are already paletted.  We don't support
	 * that; and that hint is intended for use on images that are already grayscale,
	 * it's not intended to change a color image into a grayscale image. */
	if( actualID.iGrayscaleBits != -1 && img->format->BitsPerPixel == 8 )
		actualID.iGrayscaleBits = -1;

	/* Cap the max texture size to the hardware max. */
	actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() );

	/* Save information about the source. */
	m_iSourceWidth = img->w;
	m_iSourceHeight = img->h;

	/* image size cannot exceed max size */
	m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize );
	m_iImageHeight = min( m_iSourceHeight, actualID.iMaxSize );

	/* Texture dimensions need to be a power of two; jump to the next. */
	m_iTextureWidth = power_of_two(m_iImageWidth);
	m_iTextureHeight = power_of_two(m_iImageHeight);

	/* If we're under 8x8, increase it, to avoid filtering problems on odd hardware. */
	if(m_iTextureWidth < 8 || m_iTextureHeight < 8)
	{
		actualID.bStretch = true;
		m_iTextureWidth = max(8, m_iTextureWidth);
		m_iTextureHeight = max(8, m_iTextureHeight);
	}

	ASSERT( m_iTextureWidth <= actualID.iMaxSize );
	ASSERT( m_iTextureHeight <= actualID.iMaxSize );

	if(actualID.bStretch)
	{
		/* The hints asked for the image to be stretched to the texture size,
		 * probably for tiling. */
		m_iImageWidth = m_iTextureWidth;
		m_iImageHeight = m_iTextureHeight;
	}

	if( img->w != m_iImageWidth || img->h != m_iImageHeight ) 
		RageSurfaceUtils::Zoom( img, m_iImageWidth, m_iImageHeight );

	// Format of the image that we will pass to OpenGL and that we want OpenGL to use
	RageDisplay::PixelFormat pixfmt;

	if( actualID.iGrayscaleBits != -1 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL) )
	{
		RageSurface *dst = RageSurfaceUtils::PalettizeToGrayscale( img, actualID.iGrayscaleBits, actualID.iAlphaBits );

		delete img;
		img = dst;
	}

	/* Figure out which texture format to use. */
	// if the source is palleted, load palleted no matter what the prefs
	if(img->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL))
	{
		pixfmt = RageDisplay::FMT_PAL;
	}
	else
	{
		// not paletted
		switch( actualID.iColorDepth )
		{
		case 16:
			{
				/* Bits of alpha in the source: */
				int src_alpha_bits = 8 - img->format->Loss[3];

				/* Don't use more than we were hinted to. */
				src_alpha_bits = min( actualID.iAlphaBits, src_alpha_bits );

				switch( src_alpha_bits ) {
				case 0:
				case 1:
					pixfmt = RageDisplay::FMT_RGB5A1;
					break;
				default:	
					pixfmt = RageDisplay::FMT_RGBA4;
					break;
				}
			}
			break;
		case 32:
			pixfmt = RageDisplay::FMT_RGBA8;
			break;
		default:
			RageException::Throw( "Invalid color depth: %d bits", actualID.iColorDepth );
		}
	}

	/* Make we're using a supported format. Every card supports either RGBA8 or RGBA4. */
	if( !DISPLAY->SupportsTextureFormat(pixfmt) )
	{
		pixfmt = RageDisplay::FMT_RGBA8;
		if( !DISPLAY->SupportsTextureFormat(pixfmt) )
			pixfmt = RageDisplay::FMT_RGBA4;
	}

	/* Dither if appropriate. XXX: This is a special case: don't bother dithering to
	 * RGBA8888.  We actually want to dither only if the destination has greater color
	 * depth on at least one color channel than the source.  For example, it doesn't
	 * make sense to do this when pixfmt is RGBA5551 if the image is only RGBA555. */
	if( actualID.bDither && 
		(pixfmt==RageDisplay::FMT_RGBA4 || pixfmt==RageDisplay::FMT_RGB5A1) )
	{
		/* Dither down to the destination format. */
		const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
		RageSurface *dst = CreateSurface( img->w, img->h, pfd->bpp,
			pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );

		RageSurfaceUtils::ErrorDiffusionDither( img, dst );
		delete img;
		img = dst;
	}

	/* This needs to be done *after* the final resize, since that resize
	 * may introduce new alpha bits that need to be set.  It needs to be
	 * done *before* we set up the palette, since it might change it. */
	RageSurfaceUtils::FixHiddenAlpha(img);

	/* Convert the data to the destination format and dimensions 
	 * required by OpenGL if it's not in it already.  */
	/* We no longer need to do this; pixfmt and the format of img no longer have
	 * to match.  This means that if we have a paletted image, but the hardware
	 * doesn't support it, we can leave the data in the smaller paletted format
	 * and let OpenGL dereference it, as long as nothing else (such as dithering)
	 * ends up depalettizing it first.  We only have to scale it up to the texture
	 * size, which we won't have to do either if the image size is already a power
	 * of two. */
	// const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
	RageSurfaceUtils::ConvertSurface( img, m_iTextureWidth, m_iTextureHeight,
		img->fmt.BitsPerPixel, img->fmt.Mask[0], img->fmt.Mask[1], img->fmt.Mask[2], img->fmt.Mask[3] );
	//	pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );
	
	m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img, actualID.bMipMaps );

	CreateFrameRects();


	//
	// Enforce frames in the image have even dimensions.  Otherwise, 
	// pixel/texel alignment will be off.
	//
	bool bRunCheck = true;
	
	 // Don't check if the artist intentionally blanked the image by making it very tiny.
	if( this->GetSourceWidth()<=2 || this->GetSourceHeight()<=2 )
		 bRunCheck = false;
	
	// HACK: Don't check song graphics.  Many of them are weird dimensions.
	if( !TEXTUREMAN->GetOddDimensionWarning() )
		 bRunCheck = false;

	if( bRunCheck  )
	{
		float fFrameWidth = this->GetSourceWidth() / (float)this->GetFramesWide();
		float fFrameHeight = this->GetSourceHeight() / (float)this->GetFramesHigh();
		float fBetterFrameWidth = roundf((fFrameWidth+0.99f)/2)*2;
		float fBetterFrameHeight = roundf((fFrameHeight+0.99f)/2)*2;
		float fBetterSourceWidth = this->GetFramesWide() * fBetterFrameWidth;
		float fBetterSourceHeight = this->GetFramesHigh() * fBetterFrameHeight;
		if( fFrameWidth!=fBetterFrameWidth || fFrameHeight!=fBetterFrameHeight )
		{
			CString sWarning = ssprintf(
				"The graphic '%s' has frame dimensions that aren't even numbers.\n\n"
				"The entire image is %dx%d and frame size is %.1fx%.1f.\n\n"
				"Image quality will be much improved if you resize the graphic to %.0fx%.0f, which is a frame size of %.0fx%.0f.", 
				actualID.filename.c_str(), 
				this->GetSourceWidth(), this->GetSourceHeight(), 
				fFrameWidth, fFrameHeight,
				fBetterSourceWidth, fBetterSourceHeight,
				fBetterFrameWidth, fBetterFrameHeight );
			LOG->Warn( sWarning );
			Dialog::OK( sWarning, "FRAME_DIMENSIONS_WARNING" );
		}
	}



	delete img;

	/* See if the apparent "size" is being overridden. */
	GetResolutionFromFileName(actualID.filename, m_iSourceWidth, m_iSourceHeight);


	CString props;
	props += RageDisplay::PixelFormatToString( pixfmt ) + " ";
	if(actualID.iAlphaBits == 0) props += "opaque ";
	if(actualID.iAlphaBits == 1) props += "matte ";
	if(actualID.bStretch) props += "stretch ";
	if(actualID.bDither) props += "dither ";
	props.erase(props.size()-1);
	LOG->Trace( "RageBitmapTexture: Loaded '%s' (%ux%u); %s, source %d,%d;  image %d,%d.", 
		actualID.filename.c_str(), GetTextureWidth(), GetTextureHeight(),
		props.c_str(), m_iSourceWidth, m_iSourceHeight,
		m_iImageWidth,	m_iImageHeight);
}
Example #12
0
File: font.c Project: shiver/vectir
// creates the texture for the font
// TODO (robertva#1#): Handle glyph sizes better. Each glyph has a unique width
// + height...
int _createFontTexture() {

  SDL_Surface *surface;
  SDL_Surface *surface_texture;
  SDL_Rect srcrect, dstrect;
  int start = 32;
  int count = 94;
  int x, y;
  float xval, yval;
  char c[2];

  int tw, th;
	Glyph *first, *current, *row;
	int per_row;
	int width, height;
	SDL_Color color_fg, color_bg;

	// set vars
	memset(c, '\0', sizeof(c));
	per_row = 0;
  width = 0;
  height = 0;
	debug_print("Getting glyph info.");
	first = font_getGlyphInfo(start, count);
	first->x = 0;
	first->y = 0;
	current = first;
	row = current;

	// todo: make colour settable
  color_fg.r = 255;
  color_fg.g = 255;
  color_fg.b = 255;
  color_bg.r = 0;
  color_bg.g = 0;
  color_bg.b = 0;

  if (!font) {
    error_print("_createFontTexture: Font not open.");
    return 0;
  }

  // determine the dimensions required to fit all glyphs and
	// number of characters in a row
	debug_print("Getting font texture dimensions.");
	per_row = round(sqrt(count)); // rounds up. remember to cater for fewer characters
	font_determineDimensions(start, count, &tw, &th, &per_row);
	// set texture width and height to nearest power of two
	tw = power_of_two(tw);
	th = power_of_two(th);
	printf("dims: %d %d\n", tw, th);

  // generate a place for the final surface
	debug_print("Creating new surface for font texture.");
  surface_texture = SDL_CreateRGBSurface(SDL_SWSURFACE, tw, th, 32, 0, 0, 0, 0);
  if (!surface_texture) {
    error_print("Failed to create new surface for font.");
    return 0;
  }

  for (y = 0; y < per_row; y++) {
		// store the glyph at the beginning of the row
		row = current;
		height = 0;

		// need to first get the max height out of the glyphs in this row
		for (x = 0; x < per_row; x++) {
			if (current) {
				if (current->h + (GLYPH_PADDING * 2) > height) {
					height = current->h + (GLYPH_PADDING * 2);
				}
			}
			current = current->next;
		}

		// go back to the beginning of the row
		current = row;

		// now do the actual rendering and applying to the finial surface
    for (x = 0; x < per_row; x++) {
			if (x + (y * per_row) < count) { // correction for rounding of per_row
				if (current) {
					// render next character
		      c[0] = start + x + (y * per_row);
		      surface = TTF_RenderText_Shaded(font, c, color_fg, color_bg);

					current->w = surface->w;
					current->h = surface->h;

					// set the src dimensions
					srcrect.x = 0;
					srcrect.y = 0;
					srcrect.w = surface->w;
					srcrect.h = surface->h;

					// set the destination location for the new char
			    dstrect.x = current->x + GLYPH_PADDING;
				  dstrect.y = current->y + GLYPH_PADDING;
					dstrect.w = surface->w;
					dstrect.h = current->h;

				  // copy the row to the final surface
					SDL_BlitSurface(surface, &srcrect, surface_texture, &dstrect);

					SDL_FreeSurface(surface);

					// set the top left corner of the next glyph
					if (current->next) {
						if (x + 1 < per_row) { // if we're still on the same row
							((Glyph*)current->next)->x = current->x + current->w + (GLYPH_PADDING * 2);
							((Glyph*)current->next)->y = current->y;
						}
						else { // on the next row
							((Glyph*)current->next)->x = 0;
							((Glyph*)current->next)->y = current->y + current->h + (GLYPH_PADDING * 2);
						}
					}
					current = current->next;
				}
			}
    }
  }

  // create an opengl texture from the surface
  font_texture = graphics_createTextureFromSurface(surface_texture);
  //SDL_SaveBMP(surface_texture, "font.bmp"); // used for debugging
  SDL_FreeSurface(surface_texture);

  // reset the glyph info list
  current = first;

  debug_print("Generating font display lists...");
  font_base = glGenLists(count); // create opengl display list

  for (y = 0; y < per_row; y++ ) {
    for (x = 0; x < per_row; x++ ) {
      if (x + (y * per_row) < count) {
        if (current) {
          glNewList(font_base + x + (y * per_row), GL_COMPILE); // new char
            glBegin(GL_QUADS);
              // texture 0, 0
              xval = current->x / (float)tw;
              yval = current->y / (float)th;
              glTexCoord2f(xval, yval);
              glVertex2i(0, 0);

              // texture 1, 0
              xval = ((current->x + current->w + (GLYPH_PADDING * 2)) / (float)tw);
              yval = current->y / (float)th;
              glTexCoord2f(xval, yval);
              glVertex2i(current->w + (GLYPH_PADDING * 2), 0);

              // texture 1, 1
              xval = ((current->x + current->w + (GLYPH_PADDING * 2)) / (float)tw);
              yval = (current->y / (float)th) + (current->h / (float)th);
              glTexCoord2f(xval, yval);
              glVertex2i(current->w + (GLYPH_PADDING * 2), current->h);

              // texture 0, 1

              xval = current->x / (float)tw;
              yval = (current->y / (float)th) + (current->h / (float)th);
              glTexCoord2f(xval, yval);
              glVertex2i(0, current->h);
            glEnd();
            glTranslatef(current->w + (GLYPH_PADDING), 0, 0.0f); // move to next place
          glEndList();

          current = current->next;
        }
      }
    }
  }

	font_destroyGlyphInfo(first);
	return 1;
}
Example #13
0
//---------------------------------------------------------------------------
GLuint uv_image::SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
{
   GLuint texture;
   int w, h;
   SDL_Surface *image;
   SDL_Rect area;
   Uint32 saved_flags;
   Uint8  saved_alpha;

   // Use the surface width and height expanded to powers of 2
   w = power_of_two(surface->w);
   h = power_of_two(surface->h);
   texcoord[0] = 0.0f;			   // Min X
   texcoord[1] = 0.0f;			   // Min Y
   texcoord[2] = (GLfloat)surface->w / w;  // Max X
   texcoord[3] = (GLfloat)surface->h / h;  // Max Y

   image = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                w, h,
                                32,
                                // OpenGL RGBA masks
                                #if SDL_BYTEORDER == SDL_LIL_ENDIAN
                                   0x000000FF,
                                   0x0000FF00,
                                   0x00FF0000,
                                   0xFF000000
                                #else
                                   0xFF000000,
                                   0x00FF0000,
                                   0x0000FF00,
                                   0x000000FF
                                #endif
                                );
   if(image == NULL)
   {
      cout << "Error occured while creating SDL Surface for Image loading."<<endl;
      return false;
   }

   // Save the alpha blending attributes
   saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
   saved_alpha = surface->format->alpha;
   if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
   {
      SDL_SetAlpha(surface, 0, 0);
   }

   // Copy the surface into the GL texture image
   area.x = 0;
   area.y = 0;
   area.w = surface->w;
   area.h = surface->h;
   SDL_BlitSurface(surface, &area, image, &area);

   // Restore the alpha blending attributes
   if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
   {
      SDL_SetAlpha(surface, saved_flags, saved_alpha);
   }

   // Create an OpenGL texture for the image
   glGenTextures(1, &texture);
   glBindTexture(GL_TEXTURE_2D, texture);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexImage2D(GL_TEXTURE_2D,
                0,
                GL_RGBA,
                w, h,
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
                image->pixels);
   SDL_FreeSurface(image); // No longer needed
   return texture;
};
Example #14
0
void Image::_load(string sFilename)
{
	errlog << "Load " << sFilename << endl;
	//image format
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	//pointer to the image, once loaded
	FIBITMAP *dib(0);
	//pointer to the image data
	BYTE* bits(0);
	//image width and height
	unsigned int width(0), height(0);
	
	//check the file signature and deduce its format
	fif = FreeImage_GetFileType(sFilename.c_str(), 0);
	//if still unknown, try to guess the file format from the file extension
	if(fif == FIF_UNKNOWN) 
		fif = FreeImage_GetFIFFromFilename(sFilename.c_str());
	//if still unkown, return failure
	if(fif == FIF_UNKNOWN)
	{
		errlog << "Unknown image type for file " << sFilename << endl;
		return;
	}
  
	//check that the plugin has reading capabilities and load the file
	if(FreeImage_FIFSupportsReading(fif))
		dib = FreeImage_Load(fif, sFilename.c_str());
	else
		errlog << "File " << sFilename << " doesn't support reading." << endl;
	//if the image failed to load, return failure
	if(!dib)
	{
		errlog << "Error loading image " << sFilename.c_str() << endl;
		return;
	}  
	//retrieve the image data
  
	//get the image width and height
	width = FreeImage_GetWidth(dib);
	height = FreeImage_GetHeight(dib);
 
	int mode, modeflip;
	if(FreeImage_GetBPP(dib) == 24) // RGB 24bit
	{
#ifdef __BIG_ENDIAN__
		mode = GL_RGB;
		modeflip = GL_RGB;
#else
		mode = GL_RGB;
		modeflip = GL_BGR;
#endif
	}
	else if(FreeImage_GetBPP(dib) == 32)  // RGBA 32bit
	{
#ifdef __BIG_ENDIAN__
		mode = GL_RGBA;
		modeflip = GL_RGBA;
#else
		mode = GL_RGBA;
		modeflip = GL_BGRA;
#endif
	}
  
	bits = FreeImage_GetBits(dib);	//if this somehow one of these failed (they shouldn't), return failure
	if((bits == 0) || (width == 0) || (height == 0))
	{
		errlog << "Something went terribly horribly wrong with getting image bits; just sit and wait for the singularity" << endl;
		return;
	}
  
	//generate an OpenGL texture ID for this texture
	m_iWidth = width;
	m_iHeight = height;
	glGenTextures(1, &m_hTex);
	//bind to the new texture ID
	glBindTexture(GL_TEXTURE_2D, m_hTex);
	//store the texture data for OpenGL use
#ifdef __BIG_ENDIAN__
	m_iRealWidth = power_of_two(width);
	m_iRealHeight = power_of_two(height);
	FIBITMAP *bitmap2 = FreeImage_Allocate(m_iRealWidth, m_iRealHeight, FreeImage_GetBPP(dib));
	FreeImage_FlipVertical(dib);
	FreeImage_Paste(bitmap2, dib, 0, 0, 255);
	FreeImage_FlipVertical(bitmap2);
	bits = FreeImage_GetBits(bitmap2);
	glTexImage2D(GL_TEXTURE_2D, 0, mode, m_iRealWidth, m_iRealHeight, 0, modeflip, GL_UNSIGNED_BYTE, bits);
	FreeImage_Unload(bitmap2);
#else
	glTexImage2D(GL_TEXTURE_2D, 0, mode, width, height, 0, modeflip, GL_UNSIGNED_BYTE, bits);
#endif
  
	if(g_imageBlur)
	{
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	}
	else //If you want things pixellated
	{
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	}
	
	//Free FreeImage's copy of the data
	FreeImage_Unload(dib);
}
Example #15
0
GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
{
	GLuint texture;
	int w, h;
	SDL_Surface *image;
	SDL_Rect area;
	Uint32 saved_flags;
	Uint8  saved_alpha;

	/* Use the surface width and height expanded to powers of 2 */
	w = power_of_two(surface->w);
	h = power_of_two(surface->h);
	texcoord[0] = 0.0f;			/* Min X */
	texcoord[1] = 0.0f;			/* Min Y */
	texcoord[2] = (GLfloat)surface->w / w;	/* Max X */
	texcoord[3] = (GLfloat)surface->h / h;	/* Max Y */

	image = SDL_CreateRGBSurface(
			SDL_SWSURFACE,
			w, h,
			32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
			0x000000FF, 
			0x0000FF00, 
			0x00FF0000, 
			0xFF000000
#else
			0xFF000000,
			0x00FF0000, 
			0x0000FF00, 
			0x000000FF
#endif
		       );
	if ( image == NULL ) {
		return 0;
	}

	/* Save the alpha blending attributes */
	saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
#if SDL_VERSION_ATLEAST(1, 3, 0)
	SDL_GetSurfaceAlphaMod(surface, &saved_alpha);
	SDL_SetSurfaceAlphaMod(surface, 0xFF);
#else
	saved_alpha = surface->format->alpha;
	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
		SDL_SetAlpha(surface, 0, 0);
	}
#endif

	/* Copy the surface into the GL texture image */
	area.x = 0;
	area.y = 0;
	area.w = surface->w;
	area.h = surface->h;
	SDL_BlitSurface(surface, &area, image, &area);

	/* Restore the alpha blending attributes */
#if SDL_VERSION_ATLEAST(1, 3, 0)
	SDL_SetSurfaceAlphaMod(surface, saved_alpha);
#else
	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
		SDL_SetAlpha(surface, saved_flags, saved_alpha);
	}
#endif

	/* Create an OpenGL texture for the image */
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGBA,
		     w, h,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_BYTE,
		     image->pixels);
	SDL_FreeSurface(image); /* No longer needed */

	return texture;
}
Example #16
0
void cavoc_init(t_cavoc *x,short initialized)
{
int i;

  if(!x->D)
    x->D = 256;
  if(!x->R)
    x->R = 44100;
  if(!power_of_two(x->overlap))
    x->overlap = 4;
  if(!power_of_two(x->winfac))
    x->winfac = 1;
  x->N = x->D * x->overlap;
  x->Nw = x->N * x->winfac;
limit_fftsize(&x->N,&x->Nw,OBJECT_NAME);
  x->mult = 1. / (float) x->N;
  x->N2 = (x->N)>>1;
  x->Nw2 = (x->Nw)>>1;
  x->in_count = -(x->Nw);
  x->c_fundamental =  (float) x->R/(float)((x->N2)<<1);
  x->frame_duration = (float)x->D/(float) x->R;
  if(x->hold_time <= 100) /* in milliseconds */
  	x->hold_time = 100;


  cavoc_hold_time(x, x->hold_time);  	

	if(!initialized){
	  
	  srand(time(0));
	  x->mute = 0;
	  x->set_count = 0;
	  x->external_trigger = 0;
	  if( x->density < 0.0 ){
	    x->density = 0;
	  } else if( x->density > 1.0 ){
	    x->density = 1.0;
	  }
	  x->start_breakpoint = 1.0 - x->density;
	  
	  x->Wanal = (float *) calloc( MAX_Nw, sizeof(float) );	
	  x->Wsyn = (float *) calloc( MAX_Nw, sizeof(float) );	
	  x->input = (float *) calloc( MAX_Nw, sizeof(float) );	
	  x->Hwin = (float *) calloc( MAX_Nw, sizeof(float) );
	  x->buffer = (float *) calloc( MAX_N, sizeof(float) );
	  x->channel = (float *) calloc( MAX_N+2, sizeof(float) );
	  x->last_frame = (float *) calloc(MAX_N+2, sizeof(float));
	  x->output = (float *) calloc( MAX_Nw, sizeof(float) );
	  x->bitshuffle = (int *) calloc( MAX_N * 2, sizeof( int ) );
	  x->trigland = (float *) calloc( MAX_N * 2, sizeof( float ) );
	  x->c_lastphase_out = (float *) calloc( MAX_N2+1, sizeof(float) );
	  
	  x->c_factor_out = TWOPI * (float)  x->D / (float) x->R;
	  x->rule = (short *)  calloc(8, sizeof(short));

	  x->rule[2] = x->rule[3] = x->rule[5] = x->rule[6] = 1;
	  x->rule[0] = x->rule[1] = x->rule[4] = x->rule[7] = 0;

	} 
		memset((char *)x->input,0,x->Nw * sizeof(float));
		memset((char *)x->output,0,x->Nw * sizeof(float));
		memset((char *)x->buffer,0,x->N * sizeof(float));
		memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float));
		memset((char *)x->last_frame,0,(x->N+2) * sizeof(float));

  init_rdft( x->N, x->bitshuffle, x->trigland);
  makehanning( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0);

  for(i = 0; i < x->N2 + 1; i++){
    if(cavoc_randf(0.0, 1.0) > x->start_breakpoint){
      x->channel[ i * 2 ] = 1;
      ++(x->set_count);
    } else {
      x->channel[i * 2] = 0;
    }
    x->channel[i * 2 + 1] = x->c_fundamental * (float) (i / 2) * cavoc_randf(.9,1.1);
  }

//  post("turned on %d of a possible %d bins", x->set_count, x->N2+1 );
  
  for( i = 0; i < x->N+2; i++ ){
    x->last_frame[i] = x->channel[i];
  }
//  post("cavoc~ FFT size: %d",x->N);
}
Example #17
0
void BannerCache::CacheBannerInternal( CString BannerPath )
{
	CString error;
	RageSurface *img = RageSurfaceUtils::LoadFile( BannerPath, error );
	if( img == NULL )
	{
		LOG->Warn( "BannerCache::CacheBanner: Couldn't load %s: %s", BannerPath.c_str(), error.c_str() );
		return;
	}

	bool WasRotatedBanner = false;

	if( Sprite::IsDiagonalBanner(img->w , img->h) )
	{
		/* Ack.  It's a diagonal banner.  Problem: if we resize a diagonal banner, we
		 * get ugly checker patterns.  We need to un-rotate it.
		 *
		 * If we spin the banner by hand, we need to do a linear filter, or the
		 * fade to the full resolution banner is misaligned, which looks strange.
		 *
		 * To do a linear filter, we need to lose the palette.  Oh well.
		 *
		 * This also makes the banner take less memory, though that could also be
		 * done by RLEing the surface.
		 */
		RageSurfaceUtils::ApplyHotPinkColorKey( img );

		RageSurfaceUtils::ConvertSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
		
		RageSurface *dst = CreateSurface(
            256, 64, img->format->BitsPerPixel, 
			img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask );

		if( img->format->BitsPerPixel == 8 ) 
		{
			ASSERT( img->format->palette );
			dst->fmt.palette = img->fmt.palette;
		}

		const float fCustomImageCoords[8] = {
			0.02f,	0.78f,	// top left
			0.22f,	0.98f,	// bottom left
			0.98f,	0.22f,	// bottom right
			0.78f,	0.02f,	// top right
		};

		RageSurfaceUtils::BlitTransform( img, dst, fCustomImageCoords );

//		SDL_SaveBMP( dst, BannerPath + "-test.bmp" );
		delete img;
		img = dst;

		WasRotatedBanner = true;
	}



	const int src_width = img->w, src_height = img->h;

	int width = img->w / 2, height = img->h / 2;
//	int width = img->w, height = img->h;

	/* Round to the nearest power of two.  This simplifies the actual texture load. */
	width = closest(width, power_of_two(width), power_of_two(width) / 2);
	height = closest(height, power_of_two(height), power_of_two(height) / 2);

	/* Don't resize the image to less than 32 pixels in either dimension or the next
	 * power of two of the source (whichever is smaller); it's already very low res. */
	width = max( width, min(32, power_of_two(src_width)) );
	height = max( height, min(32, power_of_two(src_height)) );

	RageSurfaceUtils::ApplyHotPinkColorKey( img );

	RageSurfaceUtils::Zoom( img, width, height );

	/*
	 * When paletted banner cache is enabled, cached banners are paletted.  Cached
	 * 32-bit banners take 1/16 as much memory, 16-bit banners take 1/8, and paletted
	 * banners take 1/4.
	 *
	 * When paletted banner cache is disabled, cached banners are stored in 16-bit
	 * RGBA.  Cached 32-bit banners take 1/8 as much memory, cached 16-bit banners
	 * take 1/4, and cached paletted banners take 1/2.
	 *
	 * Paletted cache is disabled by default because palettization takes time, causing
	 * the initial cache run to take longer.  Also, newer ATI hardware doesn't supported
	 * paletted textures, which would slow down runtime, because we have to depalettize
	 * on use.  They'd still have the same memory benefits, though, since we only load
	 * one cached banner into a texture at once, and the speed hit may not matter on
	 * newer ATI cards.  RGBA is safer, though.
	 */
	if( PREFSMAN->m_bPalettedBannerCache )
	{
		if( img->fmt.BytesPerPixel != 1 )
			RageSurfaceUtils::Palettize( img );
	} else {
		/* Dither to the final format.  We use A1RGB5, since that's usually supported
		 * natively by both OpenGL and D3D. */
		RageSurface *dst = CreateSurface( img->w, img->h, 16,
			0x7C00, 0x03E0, 0x001F, 0x8000 );

		/* OrderedDither is still faster than ErrorDiffusionDither, and
		 * these images are very small and only displayed briefly. */
		RageSurfaceUtils::OrderedDither( img, dst );
		delete img;
		img = dst;
	}

	const CString CachePath = GetBannerCachePath(BannerPath);
	RageSurfaceUtils::SaveSurface( img, CachePath );

	if( PREFSMAN->m_BannerCache == PrefsManager::BNCACHE_LOW_RES )
	{
		/* If an old image is loaded, free it. */
		if( g_BannerPathToImage.find(BannerPath) != g_BannerPathToImage.end() )
		{
			RageSurface *oldimg = g_BannerPathToImage[BannerPath];
			delete oldimg;
			g_BannerPathToImage.erase(BannerPath);
		}

		/* Keep it; we're just going to load it anyway. */
		g_BannerPathToImage[BannerPath] = img;
	}
	else
		delete img;

	/* Remember the original size. */
	BannerData.SetValue( BannerPath, "Path", CachePath );
	BannerData.SetValue( BannerPath, "Width", src_width );
	BannerData.SetValue( BannerPath, "Height", src_height );
	BannerData.SetValue( BannerPath, "FullHash", GetHashForFile( BannerPath ) );
	/* Remember this, so we can hint Sprite. */
	BannerData.SetValue( BannerPath, "Rotated", WasRotatedBanner );
	BannerData.WriteFile( BANNER_CACHE_INDEX );
}
Example #18
0
//读取一个BMP文件作为纹理.如果失败,返回0;如果成功,返回纹理编号
GLuint load_texture(const char* file_name)
{
	/*如果这里报错:'fopen': This function or variable may be unsafe 
	* 解决办法:
	* 项目 =》属性 =》c/c++  =》预处理器=》点击预处理器定义,编辑,加入_CRT_SECURE_NO_WARNINGS
	*/

	// 打开文件,如果失败,返回
	FILE* pFile = fopen(file_name, "rb");
	if (pFile == 0)
		return 0;

	// 读取文件中图象的宽度和高度
	GLint width, height;
	fseek(pFile, 0x0012, SEEK_SET);
	fread(&width, 4, 1, pFile);//读取出的值赋给传入的变量
	fread(&height, 4, 1, pFile);
	fseek(pFile, BMP_Header_Length, SEEK_SET);

	// 计算每行像素所占字节数,并根据此数据计算总像素字节数
	GLint total_bytes;
	{
		GLint line_bytes = width * 3;
		while (line_bytes % 4 != 0)
			++line_bytes;
		total_bytes = line_bytes * height;
	}

	// 根据总像素字节数分配内存
	GLubyte* pixels = 0;//像素数据
	pixels = (GLubyte*)malloc(total_bytes);
	if (pixels == 0)
	{
		fclose(pFile);
		return 0;
	}

	// 读取像素数据
	if (fread(pixels, total_bytes, 1, pFile) <= 0)
	{
		free(pixels);
		fclose(pFile);
		return 0;
	}

	// 在旧版本的OpenGL中
	// 如果图象的宽度和高度不是的整数次方,则需要进行缩放
	// 这里并没有检查OpenGL版本,出于对版本兼容性的考虑,按旧版本处理
	// 另外,无论是旧版本还是新版本,
	// 当图象的宽度和高度超过当前OpenGL实现所支持的最大值时,也要进行缩放
	{
		GLint max;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
		if (!power_of_two(width)
			|| !power_of_two(height)
			|| width > max
			|| height > max)
		{
			const GLint new_width = 256;
			const GLint new_height = 256; // 规定缩放后新的大小为边长的正方形
			GLint new_line_bytes, new_total_bytes;
			GLubyte* new_pixels = 0;

			// 计算每行需要的字节数和总字节数
			new_line_bytes = new_width * 3;
			while (new_line_bytes % 4 != 0)
				++new_line_bytes;
			new_total_bytes = new_line_bytes * new_height;

			// 分配内存
			new_pixels = (GLubyte*)malloc(new_total_bytes);
			if (new_pixels == 0)
			{
				free(pixels);
				fclose(pFile);
				return 0;
			}

			// 进行像素缩放
			gluScaleImage(GL_RGB,
				width, height, GL_UNSIGNED_BYTE, pixels,
				new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);

			// 释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height
			free(pixels);
			pixels = new_pixels;
			width = new_width;
			height = new_height;
		}
	}

	// 分配一个新的纹理编号
	GLuint texture_ID = 0;
	glGenTextures(1, &texture_ID);//(个数,给谁)
	if (texture_ID == 0)
	{
		free(pixels);
		fclose(pFile);
		return 0;
	}

	// 在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复
	GLint last_texture_ID;
	glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);

	// 绑定新的纹理,载入纹理并设置纹理参数
	glBindTexture(GL_TEXTURE_2D, texture_ID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//纹理图象被使用到一个等于它的形状上时
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//纹理图象被使用到一个大于它的形状上时
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//纹理坐标的第一维坐标值大于1.0或小于0.0时
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//纹理坐标的第二维坐标值大于1.0或小于0.0时

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);//像素级别,指定纹理贴图和材质混合的方式
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);//载入二维纹理

	glBindTexture(GL_TEXTURE_2D, last_texture_ID);

	// 之前为pixels分配的内存可在使用glTexImage2D以后释放.因为此时像素数据已经被OpenGL另行保存了一份(可能被保存到专门的图形硬件中)
	free(pixels);
	return texture_ID;
}