Ejemplo n.º 1
0
// ------------------------------------------------------------------------------------------------
void Buffer::Request(SzType n)
{
    // NOTE: Function assumes (n > 0)
    // Is there a memory manager available?
    if (!m_Mem)
    {
        // Round up the size to a power of two number
        n = (n & (n - 1)) ? NextPow2(n) : n;
        // Allocate the memory directly
        m_Ptr = AllocMem(n);
    }
    // Find out in which category does this buffer reside
    else if (n <= 1024)
    {
        m_Mem->m_Small.Grab(m_Ptr, n);
    }
    else if (n <= 4096)
    {
        m_Mem->m_Medium.Grab(m_Ptr, n);
    }
    else
    {
        m_Mem->m_Large.Grab(m_Ptr, n);
    }
    // If no errors occurred then we can set the size
    m_Cap = n;
}
Ejemplo n.º 2
0
/**
 * Driver routine to compute the spin-aligned, inspiral-merger-ringdown
 * phenomenological waveform IMRPhenomD in the frequency domain.
 *
 * Reference:
 * - Waveform: Eq.
 * - Coefficients: Eq. and Table xyz
 *
 *  All input parameters should be in SI units. Angles should be in radians.
 */
int XLALSimIMRPhenomDGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< Orbital phase at peak (rad) */
    const REAL8 deltaF,                /**< Sampling frequency (Hz) */
    const REAL8 m1_SI,                 /**< Mass of companion 1 (kg) */
    const REAL8 m2_SI,                 /**< Mass of companion 2 (kg) */
    const REAL8 chi1,                  /**< Aligned-spin of companion 1 */
    const REAL8 chi2,                  /**< Aligned-spin of companion 2 */
    const REAL8 f_min,                 /**< Starting GW frequency (Hz) */
    const REAL8 f_max,                 /**< End frequency; 0 defaults to ringdown cutoff freq */
    const REAL8 distance               /**< Distance of source (m) */
) {
  /* external: SI; internal: solar masses */
  const REAL8 m1 = m1_SI / LAL_MSUN_SI;
  const REAL8 m2 = m2_SI / LAL_MSUN_SI;
  const REAL8 q = (m1 > m2) ? (m1 / m2) : (m2 / m1);

  /* check inputs for sanity */
  if (*htilde) XLAL_ERROR(XLAL_EFAULT);
  if (deltaF <= 0) XLAL_ERROR(XLAL_EDOM);
  if (m1 <= 0) XLAL_ERROR(XLAL_EDOM);
  if (m2 <= 0) XLAL_ERROR(XLAL_EDOM);
  if (fabs(chi1) > 1 || fabs(chi2) > 1) XLAL_ERROR(XLAL_EDOM);
  if (f_min <= 0) XLAL_ERROR(XLAL_EDOM);
  if (f_max < 0) XLAL_ERROR(XLAL_EDOM);
  if (distance <= 0) XLAL_ERROR(XLAL_EDOM);

  if (chi1 > 0.99 || chi1 < -1.0 || chi2 > 0.99 || chi2 < -1.0)
    XLAL_ERROR(XLAL_EDOM, "Spins outside the range [-1,0.99] are not supported\n");

  if (q > 18.0)
    XLAL_PRINT_WARNING("Warning: The model is calibrated up to m1/m2 <= 18.\n");

  const REAL8 M_sec = (m1+m2) * LAL_MTSUN_SI;
  const REAL8 fCut = 0.3/M_sec;
  if (fCut <= f_min)
    XLAL_ERROR(XLAL_EDOM, "(fCut = %gM) <= f_min = %g\n", fCut, f_min);

  /* default f_max to params->fCut */
  REAL8 f_max_prime = f_max;
  f_max_prime = f_max ? f_max : fCut;
  f_max_prime = (f_max_prime > fCut) ? fCut : f_max_prime;
  if (f_max_prime <= f_min)
    XLAL_ERROR(XLAL_EDOM, "f_max <= f_min\n");

  REAL8 status = IMRPhenomDGenerateFD(htilde, phi0, deltaF,
                                      m1, m2, chi1, chi2,
                                      f_min, f_max_prime, distance);

  if (f_max_prime < f_max) {
    // The user has requested a higher f_max than Mf=params->fCut.
    // Resize the frequency series to fill with zeros to fill with zeros beyond the cutoff frequency.
    size_t n_full = NextPow2(f_max / deltaF) + 1; // we actually want to have the length be a power of 2 + 1
    *htilde = XLALResizeCOMPLEX16FrequencySeries(*htilde, 0, n_full);
  }

  return status;
}
Ejemplo n.º 3
0
/**
 * Find a lower value for f_min (using the definition of Newtonian chirp
 * time) such that the waveform has a minimum length of tau0. This is
 * necessary to avoid FFT artifacts.
 */
static REAL8 EstimateSafeFMinForTD(const REAL8 m1, const REAL8 m2, const REAL8 f_min, const REAL8 deltaT) {
	const REAL8 totalMass = m1 + m2;
	const REAL8 eta = m1 * m2 / (totalMass * totalMass);
	const REAL8 fISCO = 0.022 / (totalMass * LAL_MTSUN_SI);
	REAL8 tau0 = deltaT * NextPow2(1.5 * EstimateIMRLength(m1, m2, f_min, deltaT));
	REAL8 temp_f_min = pow((tau0 * 256. * eta * pow(totalMass * LAL_MTSUN_SI, 5./3.) / 5.), -3./8.) / LAL_PI;
	if (temp_f_min > f_min) temp_f_min = f_min;
	if (temp_f_min < 0.5) temp_f_min = 0.5;
	if (temp_f_min > fISCO/2.) temp_f_min = fISCO/2.;
	return temp_f_min;
}
Ejemplo n.º 4
0
/**
 * Private function to generate time-domain waveforms given coefficients
 */
static int IMRPhenomCGenerateTD(
	REAL8TimeSeries **h,
    const REAL8 phi0,
    size_t *ind_t0,
	const REAL8 deltaT,
	const REAL8 m1,
	const REAL8 m2,
	//const REAL8 chi,
	const REAL8 f_min,
	const REAL8 f_max,
	const REAL8 distance,
	const BBHPhenomCParams *params
) {
	REAL8 deltaF;
	COMPLEX16FrequencySeries *htilde=NULL;
	/* We will generate the waveform from a frequency which is lower than the
	 * f_min chosen. Also the cutoff frequency is higher than the f_max. We
	 * will later apply a window function, and truncate the time-domain waveform
	 * below an instantaneous frequency f_min. */
	REAL8 f_min_wide = EstimateSafeFMinForTD(m1, m2, f_min, deltaT);
	const REAL8 f_max_wide = params->fCut; //0.5 / deltaT;
	if (EstimateSafeFMaxForTD(f_max, deltaT) > f_max_wide)
		XLAL_PRINT_WARNING("Warning: sampling rate (%" LAL_REAL8_FORMAT " Hz) too low for expected spectral content (%" LAL_REAL8_FORMAT " Hz) \n", deltaT, EstimateSafeFMaxForTD(f_max, deltaT));

    const size_t nt = NextPow2(EstimateIMRLength(m1, m2, f_min_wide, deltaT));
    const size_t ne = EstimateIMRLength(m1, m2, params->fRingDown, deltaT);
    *ind_t0 = ((nt - EstimateIMRLength(m1, m2, f_min_wide, deltaT)) > (4 * ne)) ? (nt -(2* ne)) : (nt - (1 * ne));
	deltaF = 1. / (deltaT * (REAL8) nt);


	/* Get the length in time for the entire IMR waveform, so the coalesence
	 * can be positioned (in time) accordingly, to avoid wrap-around */
	REAL8 t0 = deltaT * ((REAL8) *ind_t0);


	/* generate in frequency domain */
	if (IMRPhenomCGenerateFDForTD(&htilde, t0, phi0, deltaF, m1, m2, //chi,
	    f_min_wide, f_max_wide, distance, params, nt/2 + 1)) XLAL_ERROR(XLAL_EFUNC);


	/* convert to time domain */
	FDToTD(h, htilde, m1 + m2, deltaT, f_min, f_max, f_min_wide, f_max_wide);

	XLALDestroyCOMPLEX16FrequencySeries(htilde);
	if (!*h) XLAL_ERROR(XLAL_EFUNC);

	return XLAL_SUCCESS;
}
Ejemplo n.º 5
0
 /* --------------------------------------------------------------------------------------------
  * Grab a memory buffer from the pool.
 */
 void Grab(Pointer & ptr, SzType & size)
 {
     // NOTE: Function assumes (size > 0)
     // Find a buffer large enough to satisfy the requested size
     for (Node * node = m_Head, * prev = nullptr; node; prev = node, node = node->mNext)
     {
         // Is this buffer large enough?
         if (node->mCap >= size)
         {
             // Was there a previous node?
             if (prev)
             {
                 prev->mNext = node->mNext;
             }
             // Probably this was the head
             else
             {
                 m_Head = node->mNext;
             }
             // Assign the memory
             ptr = node->mPtr;
             // Assign the size
             size = node->mCap;
             // Release the node instance
             Push(node);
             // Exit the function
             return;
         }
     }
     // Round up the size to a power of two number
     size = (size & (size - 1)) ? NextPow2(size) : size;
     // Allocate the memory directly
     ptr = AllocMem(size);
     // See if the memory could be allocated
     // (shouldn't reach this point if allocation failed)
     if (!ptr)
     {
         // Revert the size
         size = 0;
         // Throw the exception
         ThrowMemExcept("Unable to allocate (%u) bytes of memory", size);
     }
 }
Ejemplo n.º 6
0
void Raycaster::createSHTexcoords( Scene * scene )
{
  // 1024 means 1M vectors, 2048 means 4M vectors, 4096 means 16M vectors, 8192 means 67M vectors
  // I need (bands*bands) coefficients per vertex
  int verts = scene->countVertices() ;

  // r,g,b   *   #verts  *  bands^2
  int shCoeffsReqd = 3 * verts * window->shSamps->bands*window->shSamps->bands ;
  int shTexSize = NextPow2( sqrt(shCoeffsReqd) ) ;

  info( "SH DIFFUSE requires %d coeffs total, allocating texture of size %dx%d", shCoeffsReqd, shTexSize,shTexSize ) ;

  Texcoording ctex( shTexSize ) ; 

  shTex = new D3D11Surface( window, 0,0, ctex.n,ctex.n, 0,1,
    0, SurfaceType::ColorBuffer, 3,// SLOT 3 because that one is the correct format (read as float3's)
    DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, 12 ) ;

  shTex->open() ;

  for( int i = 0 ; i < scene->shapes.size() ; i++ )
  {
    for( int j = 0 ; j < scene->shapes[i]->meshGroup->meshes.size() ; j++ )
    {
      // Now enqueue jobs
      Mesh *mesh = scene->shapes[i]->meshGroup->meshes[ j ];
      
      for( int k = 0 ; k < mesh->verts.size() ; k++ )
      {
        writeSHTexcoords( ctex, mesh->verts[k] ) ;
      }

      mesh->updateVertexBuffer() ;
    } // foreach mesh in meshgroup
  }

  shTex->close() ;
}
Ejemplo n.º 7
0
// build a texture to hold minimum sized rectangles and icons used to render the chart bar
// this texture is only updated if the color scheme or chart bar height change
void Piano::BuildGLTexture()
{
    int h = GetHeight();

    wxBrush tbackBrush; // transparent back brush
    ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
    if(style->chartStatusWindowTransparent)
        tbackBrush = wxColour(1,1,1);
    else
        tbackBrush = m_backBrush;

    wxBrush brushes[] = { m_scBrush, m_cBrush, m_svBrush, m_vBrush, m_slBrush, m_tBrush, m_uvBrush };

    m_tex_piano_height = h;
    m_texw = 64;
    m_texh = ((sizeof brushes) / (sizeof *brushes)) * h;
    m_texh += 4*16; // for icons;

    m_texh = NextPow2(m_texh);

    if(!m_tex)
        glGenTextures( 1, &m_tex );

    glBindTexture(GL_TEXTURE_2D, m_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    wxBitmap bmp(m_texw, m_texh);
    wxMemoryDC dc(bmp);

    dc.SetPen( *wxTRANSPARENT_PEN );
    dc.SetBrush(tbackBrush);
    dc.DrawRectangle(0, 0, m_texw, m_texh);

    // draw the needed rectangles with minimal width
    wxPen ppPen( GetGlobalColor( _T("CHBLK") ), 1, wxPENSTYLE_SOLID );
    dc.SetPen( ppPen );
    for(unsigned int b = 0; b < (sizeof brushes) / (sizeof *brushes); b++) {
        unsigned int x = 0, y = h * b;

        dc.SetBrush(brushes[b]);

        int u = 3, v = 2;
        dc.DrawRectangle(x+u, y+v, 3, h-2*v);
        x+=3+2*u;
        
        dc.DrawRoundedRectangle(x+u, y+v, 9, h-2*v, 4);
        x+=9+2*u;

        int w = 3;
        dc.DrawRoundedRectangle(x+u, y+v, 12, h-2*v, 4);
        dc.SetBrush( m_backBrush );
        dc.DrawRoundedRectangle(x+u+w, y+v+w, 12-2*w, h-2*v-2*w, 3);
        x+=12+2*u;

        if(x >= m_texw)
            printf("texture too small\n");
    }
    dc.SelectObject( wxNullBitmap );

    wxImage image = bmp.ConvertToImage();

    unsigned char *data = new unsigned char[4*m_texw*m_texh], *d = data, *e = image.GetData(), *a = image.GetAlpha();
    for(unsigned int i=0; i<m_texw*m_texh; i++) {
        if(style->chartStatusWindowTransparent &&
           e[0] == 1 && e[1] == 1 && e[2] == 1)
            d[3] = 0;
        else
            d[3] = 255;

        memcpy(d, e, 3), d+=4, e+=3;
    }

    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_texw, m_texh, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
    delete [] data;

    // put the bitmaps in below
    wxBitmap *bitmaps[] = {m_pInVizIconBmp, m_pTmercIconBmp, m_pSkewIconBmp, m_pPolyIconBmp};

    for(unsigned int i = 0; i < (sizeof bitmaps) / (sizeof *bitmaps); i++) {
        int iw = bitmaps[i]->GetWidth(), ih = bitmaps[i]->GetHeight();
        wxASSERT(ih <= 16);

        wxImage im = bitmaps[i]->ConvertToImage();
        unsigned char *data = new unsigned char[4*iw*ih], *d = data, *e = im.GetData(), *a = im.GetAlpha();
        for(int j = 0; j<iw*ih; j++) {
            memcpy(d, e, 3), d+=3, e+=3;
            *d = *a, d++, a++;
        }

        int off = ((sizeof brushes) / (sizeof *brushes))*h + 16*i;
        glTexSubImage2D( GL_TEXTURE_2D, 0, 0, off, iw, ih, GL_RGBA, GL_UNSIGNED_BYTE, data );
        delete [] data;
    }
}
Ejemplo n.º 8
0
static int IMRPhenomCGenerateFDForTD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 t0,					   /**< time of coalescence */
    const REAL8 phi0,                  /**< phase at peak */
    const REAL8 deltaF,                /**< frequency resolution */
    const REAL8 m1,                    /**< mass of companion 1 [solar masses] */
    const REAL8 m2,                    /**< mass of companion 2 [solar masses] */
    //const REAL8 chi,                   /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,                 /**< start frequency */
    const REAL8 f_max,                 /**< end frequency */
    const REAL8 distance,              /**< distance to source (m) */
    const BBHPhenomCParams *params,    /**< from ComputeIMRPhenomCParams */
    const size_t nf                    /**< Length of frequency vector required */
) {
  static LIGOTimeGPS ligotimegps_zero = {0, 0};
  size_t i;
  INT4 errcode;

  const REAL8 M = m1 + m2;
  const REAL8 eta = m1 * m2 / (M * M);

  /* Memory to temporarily store components of amplitude and phase */
  /*
  REAL8 phSPA, phPM, phRD, aPM, aRD;
  REAL8 wPlusf1, wPlusf2, wMinusf1, wMinusf2, wPlusf0, wMinusf0;
  */
  REAL8 phPhenomC = 0.0;
  REAL8 aPhenomC = 0.0;

  /* compute the amplitude pre-factor */
  REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance;

  /* allocate htilde */
  size_t n = NextPow2(f_max / deltaF) + 1;
  if ( n > nf )
    XLAL_ERROR(XLAL_EDOM, "The required length passed as input wont fit the FD waveform\n");
  else
    n = nf;
  *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0,
      deltaF, &lalStrainUnit, n);
  memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
  XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);
  if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);

  /* now generate the waveform */
  size_t ind_max = (size_t) (f_max / deltaF);
  for (i = (size_t) (f_min / deltaF); i < ind_max; i++)
  {
    REAL8 f = i * deltaF;

    errcode = IMRPhenomCGenerateAmpPhase( &aPhenomC, &phPhenomC, f, eta, params );
    if( errcode != XLAL_SUCCESS )
      XLAL_ERROR(XLAL_EFUNC);
    phPhenomC -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase
    phPhenomC += 2.*LAL_PI*f*t0; //shifting the coalescence to t=t0

    /* generate the waveform */
    ((*htilde)->data->data)[i] = amp0 * aPhenomC * cos(phPhenomC);
    ((*htilde)->data->data)[i] += -I * amp0 * aPhenomC * sin(phPhenomC);
  }

  return XLAL_SUCCESS;
}
Ejemplo n.º 9
0
static int IMRPhenomCGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< phase at peak */
    const REAL8 deltaF,                /**< frequency resolution */
    const REAL8 m1,                    /**< mass of companion 1 [solar masses] */
    const REAL8 m2,                    /**< mass of companion 2 [solar masses] */
    //const REAL8 chi,                   /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,                 /**< start frequency */
    const REAL8 f_max,                 /**< end frequency */
    const REAL8 distance,              /**< distance to source (m) */
    const BBHPhenomCParams *params      /**< from ComputeIMRPhenomCParams */
) {
  LIGOTimeGPS ligotimegps_zero = LIGOTIMEGPSZERO; // = {0, 0}

  int errcode = XLAL_SUCCESS;
  /*
   We can't call XLAL_ERROR() directly with OpenMP on.
   Keep track of return codes for each thread and in addition use flush to get out of
   the parallel for loop as soon as possible if something went wrong in any thread.
  */

  const REAL8 M = m1 + m2;
  const REAL8 eta = m1 * m2 / (M * M);

  /* Memory to temporarily store components of amplitude and phase */
  /*
  REAL8 phSPA, phPM, phRD, aPM, aRD;
  REAL8 wPlusf1, wPlusf2, wMinusf1, wMinusf2, wPlusf0, wMinusf0;
  */

  /* compute the amplitude pre-factor */
  REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance;

  /* allocate htilde */
  size_t n = NextPow2(f_max / deltaF) + 1;
  /* coalesce at t=0 */
  XLALGPSAdd(&ligotimegps_zero, -1. / deltaF); // shift by overall length in time
  *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0,
      deltaF, &lalStrainUnit, n);
  memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
  XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);
  if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);

  size_t ind_min = (size_t) (f_min / deltaF);
  size_t ind_max = (size_t) (f_max / deltaF);

  /* Set up spline for phase */
  gsl_interp_accel *acc = gsl_interp_accel_alloc();
  size_t L =  ind_max - ind_min;
  gsl_spline *phiI = gsl_spline_alloc(gsl_interp_cspline, L);
  REAL8 *freqs = XLALMalloc(L*sizeof(REAL8));
  REAL8 *phis = XLALMalloc(L*sizeof(REAL8));

  /* now generate the waveform */
  #pragma omp parallel for
  for (size_t i = ind_min; i < ind_max; i++)
  {

    REAL8 phPhenomC = 0.0;
    REAL8 aPhenomC = 0.0;
    REAL8 f = i * deltaF;

    int per_thread_errcode;
    #pragma omp flush(errcode)
    if (errcode != XLAL_SUCCESS)
      goto skip;

    per_thread_errcode = IMRPhenomCGenerateAmpPhase( &aPhenomC, &phPhenomC, f, eta, params );
    if (per_thread_errcode != XLAL_SUCCESS) {
      errcode = per_thread_errcode;
      #pragma omp flush(errcode)
    }

    phPhenomC -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase

    freqs[i-ind_min] = f;
    phis[i-ind_min] = -phPhenomC; // PhenomP uses cexp(-I*phPhenomC); want to use same phase adjustment code, so we will flip the sign of the phase

    /* generate the waveform */
    ((*htilde)->data->data)[i] = amp0 * aPhenomC * cos(phPhenomC);
    ((*htilde)->data->data)[i] += -I * amp0 * aPhenomC * sin(phPhenomC);

  skip: /* this statement intentionally left blank */;

  }

  if( errcode != XLAL_SUCCESS )
    XLAL_ERROR(errcode);

  /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */
  gsl_spline_init(phiI, freqs, phis, L);

  REAL8 f_final = params->fRingDown;
  XLAL_PRINT_INFO("f_ringdown = %g\n", f_final);

  // Prevent gsl interpolation errors
  if (f_final > freqs[L-1])
    f_final = freqs[L-1];
  if (f_final < freqs[0])
    XLAL_ERROR(XLAL_EDOM, "f_ringdown <= f_min\n");

  /* Time correction is t(f_final) = 1/(2pi) dphi/df (f_final) */
  REAL8 t_corr = gsl_spline_eval_deriv(phiI, f_final, acc) / (2*LAL_PI);
  XLAL_PRINT_INFO("t_corr = %g\n", t_corr);
  /* Now correct phase */
  for (size_t i = ind_min; i < ind_max; i++) {
    REAL8 f = i * deltaF;
    ((*htilde)->data->data)[i] *= cexp(-2*LAL_PI * I * f * t_corr);
  }

  gsl_spline_free(phiI);
  gsl_interp_accel_free(acc);
  XLALFree(freqs);
  XLALFree(phis);

  return XLAL_SUCCESS;
}
/**
 * Core function for computing the ROM waveform.
 * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi).
 * Construct 1D splines for amplitude and phase.
 * Compute strain waveform from amplitude and phase.
*/
static int SEOBNRv1ROMEffectiveSpinCore(
  COMPLEX16FrequencySeries **hptilde,
  COMPLEX16FrequencySeries **hctilde,
  double phiRef,
  double fRef,
  double distance,
  double inclination,
  double Mtot_sec,
  double q,
  double chi,
  const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */
  double deltaF
  /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with
   * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly.
   * Then we will use deltaF = 0 to create the frequency series we return. */
  )
{
  /* Check output arrays */
  if(!hptilde || !hctilde)
    XLAL_ERROR(XLAL_EFAULT);
  SEOBNRROMdata *romdata=&__lalsim_SEOBNRv1ROMSS_data;
  if(*hptilde || *hctilde) {
    XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde));
    XLAL_ERROR(XLAL_EFAULT);
  }
  int retcode=0;

  // 'Nudge' parameter values to allowed boundary values if close by
  if (q < 1.0)    nudge(&q, 1.0, 1e-6);
  if (q > 100.0)  nudge(&q, 100.0, 1e-6);
  if (chi < -1.0) nudge(&chi, -1.0, 1e-6);
  if (chi > 0.6)  nudge(&chi, 0.6, 1e-6);

  /* If either spin > 0.6, model not available, exit */
  if ( chi < -1.0 || chi > 0.6 ) {
    XLALPrintError( "XLAL Error - %s: chi smaller than -1 or larger than 0.6!\nSEOBNRv1ROMEffectiveSpin is only available for spins in the range -1 <= a/M <= 0.6.\n", __func__);
    XLAL_ERROR( XLAL_EDOM );
  }

  if (q > 100) {
    XLALPrintError( "XLAL Error - %s: q=%lf larger than 100!\nSEOBNRv1ROMEffectiveSpin is only available for q in the range 1 <= q <= 100.\n", __func__,q);
    XLAL_ERROR( XLAL_EDOM );
  }

  if (q >= 20 && q <= 40 && chi < -0.75 && chi > -0.9) {
    XLALPrintWarning( "XLAL Warning - %s: q in [20,40] and chi in [-0.8]. The SEOBNRv1 model is not trustworthy in this region!\nSee Fig 15 in CQG 31 195010, 2014 for details.", __func__);
    XLAL_ERROR( XLAL_EDOM );
  }

  /* Find frequency bounds */
  if (!freqs_in) XLAL_ERROR(XLAL_EFAULT);
  double fLow  = freqs_in->data[0];
  double fHigh = freqs_in->data[freqs_in->length - 1];

  if(fRef==0.0)
    fRef=fLow;

  /* Convert to geometric units for frequency */
  double Mf_ROM_min = fmax(gA[0], gPhi[0]);               // lowest allowed geometric frequency for ROM
  double Mf_ROM_max = fmin(gA[nk_amp-1], gPhi[nk_phi-1]); // highest allowed geometric frequency for ROM
  double fLow_geom = fLow * Mtot_sec;
  double fHigh_geom = fHigh * Mtot_sec;
  double fRef_geom = fRef * Mtot_sec;
  double deltaF_geom = deltaF * Mtot_sec;

  // Enforce allowed geometric frequency range
  if (fLow_geom < Mf_ROM_min)
    XLAL_ERROR(XLAL_EDOM, "Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
  if (fHigh_geom == 0)
    fHigh_geom = Mf_ROM_max;
  else if (fHigh_geom > Mf_ROM_max) {
	  XLALPrintWarning("Maximal frequency Mf_high=%g is greater than highest ROM frequency Mf_ROM_Max=%g. Using Mf_high=Mf_ROM_Max.", fHigh_geom, Mf_ROM_max);
	  fHigh_geom = Mf_ROM_max;
  }
  else if (fHigh_geom < Mf_ROM_min)
    XLAL_ERROR(XLAL_EDOM, "End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom);
  if (fRef_geom > Mf_ROM_max) {
	  XLALPrintWarning("Reference frequency Mf_ref=%g is greater than maximal frequency in ROM Mf=%g. Starting at maximal frequency in ROM.\n", fRef_geom, Mf_ROM_max);
    fRef_geom = Mf_ROM_max; // If fref > fhigh we reset fref to default value of cutoff frequency.
  }
  if (fRef_geom < Mf_ROM_min) {
    XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
    fRef_geom = Mf_ROM_min;
  }

  /* Internal storage for w.f. coefficiencts */
  SEOBNRROMdata_coeff *romdata_coeff=NULL;
  SEOBNRROMdata_coeff_Init(&romdata_coeff);
  REAL8 amp_pre;

  /* Interpolate projection coefficients and evaluate them at (q,chi) */
  retcode=TP_Spline_interpolation_2d(
    q,                         // Input: q-value for which projection coefficients should be evaluated
    chi,                       // Input: chi-value for which projection coefficients should be evaluated
    romdata->cvec_amp,         // Input: data for spline coefficients for amplitude
    romdata->cvec_phi,         // Input: data for spline coefficients for phase
    romdata->cvec_amp_pre,     // Input: data for spline coefficients for amplitude prefactor
    romdata_coeff->c_amp,      // Output: interpolated projection coefficients for amplitude
    romdata_coeff->c_phi,      // Output: interpolated projection coefficients for phase
    &amp_pre                   // Output: interpolated amplitude prefactor
  );

  if(retcode!=0) {
    SEOBNRROMdata_coeff_Cleanup(romdata_coeff);
    XLAL_ERROR(retcode, "Parameter-space interpolation failed.");
  }

  // Compute function values of amplitude an phase on sparse frequency points by evaluating matrix vector products
  // amp_pts = B_A^T . c_A
  // phi_pts = B_phi^T . c_phi
  gsl_vector* amp_f = gsl_vector_alloc(nk_amp);
  gsl_vector* phi_f = gsl_vector_alloc(nk_phi);
  gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bamp, romdata_coeff->c_amp, 0.0, amp_f);
  gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bphi, romdata_coeff->c_phi, 0.0, phi_f);

  // Setup 1d splines in frequency
  gsl_interp_accel *acc_amp = gsl_interp_accel_alloc();
  gsl_spline *spline_amp = gsl_spline_alloc(gsl_interp_cspline, nk_amp);
  gsl_spline_init(spline_amp, gA, gsl_vector_const_ptr(amp_f,0), nk_amp);

  gsl_interp_accel *acc_phi = gsl_interp_accel_alloc();
  gsl_spline *spline_phi = gsl_spline_alloc(gsl_interp_cspline, nk_phi);
  gsl_spline_init(spline_phi, gPhi, gsl_vector_const_ptr(phi_f,0), nk_phi);


  size_t npts = 0;
  LIGOTimeGPS tC = {0, 0};
  UINT4 offset = 0; // Index shift between freqs and the frequency series
  REAL8Sequence *freqs = NULL;
  if (deltaF > 0)  { // freqs contains uniform frequency grid with spacing deltaF; we start at frequency 0
    /* Set up output array with size closest power of 2 */
    npts = NextPow2(fHigh_geom / deltaF_geom) + 1;
    if (fHigh_geom < fHigh * Mtot_sec) /* Resize waveform if user wants f_max larger than cutoff frequency */
      npts = NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;

    XLALGPSAdd(&tC, -1. / deltaF);  /* coalesce at t=0 */
    *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);
    *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);

    // Recreate freqs using only the lower and upper bounds
    UINT4 iStart = (UINT4) ceil(fLow_geom / deltaF_geom);
    UINT4 iStop = (UINT4) ceil(fHigh_geom / deltaF_geom);
    freqs = XLALCreateREAL8Sequence(iStop - iStart);
    if (!freqs) {
      XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
    }
    for (UINT4 i=iStart; i<iStop; i++)
      freqs->data[i-iStart] = i*deltaF_geom;

    offset = iStart;
  } else { // freqs contains frequencies with non-uniform spacing; we start at lowest given frequency
    npts = freqs_in->length;
    *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
    *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
    offset = 0;

    freqs = XLALCreateREAL8Sequence(freqs_in->length);
    if (!freqs) {
      XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
    }
    for (UINT4 i=0; i<freqs_in->length; i++)
      freqs->data[i] = freqs_in->data[i] * Mtot_sec;
  }


  if (!(*hptilde) || !(*hctilde))
  {
      XLALDestroyREAL8Sequence(freqs);
      gsl_spline_free(spline_amp);
      gsl_spline_free(spline_phi);
      gsl_interp_accel_free(acc_amp);
      gsl_interp_accel_free(acc_phi);
      gsl_vector_free(amp_f);
      gsl_vector_free(phi_f);
      SEOBNRROMdata_coeff_Cleanup(romdata_coeff);
      XLAL_ERROR(XLAL_EFUNC, "Waveform allocation failed.");
  }
  memset((*hptilde)->data->data, 0, npts * sizeof(COMPLEX16));
  memset((*hctilde)->data->data, 0, npts * sizeof(COMPLEX16));

  XLALUnitMultiply(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit);
  XLALUnitMultiply(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit);

  COMPLEX16 *pdata=(*hptilde)->data->data;
  COMPLEX16 *cdata=(*hctilde)->data->data;

  REAL8 cosi = cos(inclination);
  REAL8 pcoef = 0.5*(1.0 + cosi*cosi);
  REAL8 ccoef = cosi;

  REAL8 s = 1.0/sqrt(2.0); // Scale polarization amplitude so that strain agrees with FFT of SEOBNRv1
  double Mtot = Mtot_sec / LAL_MTSUN_SI;
  double amp0 = Mtot * amp_pre * Mtot_sec * LAL_MRSUN_SI / (distance); // Correct overall amplitude to undo mass-dependent scaling used in single-spin ROM

  // Evaluate reference phase for setting phiRef correctly
  double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef;

  // Assemble waveform from aplitude and phase
  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
    double f = freqs->data[i];
    if (f > Mf_ROM_max) continue; // We're beyond the highest allowed frequency; since freqs may not be ordered, we'll just skip the current frequency and leave zero in the buffer
    int j = i + offset; // shift index for frequency series if needed
    double A = gsl_spline_eval(spline_amp, f, acc_amp);
    double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change;
    COMPLEX16 htilde = s*amp0*A * cexp(I*phase);
    pdata[j] =      pcoef * htilde;
    cdata[j] = -I * ccoef * htilde;
  }

  /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */

  // Get SEOBNRv1 ringdown frequency for 22 mode
  double Mf_final = SEOBNRROM_Ringdown_Mf_From_Mtot_q(Mtot_sec, q, chi, chi, SEOBNRv1);

  UINT4 L = freqs->length;
  // prevent gsl interpolation errors
  if (Mf_final > freqs->data[L-1])
    Mf_final = freqs->data[L-1];
  if (Mf_final < freqs->data[0])
  {
      XLALDestroyREAL8Sequence(freqs);
      gsl_spline_free(spline_amp);
      gsl_spline_free(spline_phi);
      gsl_interp_accel_free(acc_amp);
      gsl_interp_accel_free(acc_phi);
      gsl_vector_free(amp_f);
      gsl_vector_free(phi_f);
      SEOBNRROMdata_coeff_Cleanup(romdata_coeff);
      XLAL_ERROR(XLAL_EDOM, "f_ringdown < f_min");
  }

  // Time correction is t(f_final) = 1/(2pi) dphi/df (f_final)
  // We compute the dimensionless time correction t/M since we use geometric units.
  REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*LAL_PI);

  // Now correct phase
  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
    double f = freqs->data[i] - fRef_geom;
    int j = i + offset; // shift index for frequency series if needed
    pdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
    cdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
  }

  XLALDestroyREAL8Sequence(freqs);

  gsl_spline_free(spline_amp);
  gsl_spline_free(spline_phi);
  gsl_interp_accel_free(acc_amp);
  gsl_interp_accel_free(acc_phi);
  gsl_vector_free(amp_f);
  gsl_vector_free(phi_f);
  SEOBNRROMdata_coeff_Cleanup(romdata_coeff);

  return(XLAL_SUCCESS);
}
Ejemplo n.º 11
0
Atlas::Atlas(int width,int height)
{
	mSrcWidth = width;
	mSrcHeight = height;
	
	if(width > height)
	{
		mAtlasWidth = NextPow2(width);
		mAtlasHeight = NextPow2(width * height) / mAtlasWidth;
	}
	else
	{
		mAtlasHeight = NextPow2(height);
		mAtlasWidth = NextPow2(width * height) / mAtlasHeight;
	}
		
	int remSrcWidth = width;
	int remSrcHeight = height;
	int remAtlasWidth = mAtlasWidth;
	int remAtlasHeight = mAtlasHeight;
	int curSrcX = 0;
	int curSrcY = 0;
	int curAtlasX = 0;
	int curAtlasY = 0;
	
	while(true)
	{	
		bool srcWide = remSrcWidth > remSrcHeight;
		bool atlasWide = remAtlasWidth > remAtlasHeight;
		if(srcWide == atlasWide)
		{
			Chart chart;
			chart.mSrcX = curSrcX;
			chart.mSrcY = curSrcY;
			chart.mAtlasX = curAtlasX;
			chart.mAtlasY = curAtlasY;
			chart.mFlip = false;
			if(remSrcWidth > remAtlasWidth)
			{
				assert(remSrcHeight <= remAtlasHeight);
				
				chart.mWidth = remAtlasWidth;
				chart.mHeight = remSrcHeight;
				
				curSrcX += remAtlasWidth;
				curAtlasY += remSrcHeight;
			
				remSrcWidth -= remAtlasWidth;
				remAtlasHeight -= remSrcHeight;
				mCharts.push_back(chart);
			}
			else if(remSrcHeight > remAtlasHeight)
			{
				assert(remSrcWidth <= remAtlasWidth);
				
				chart.mWidth = remSrcWidth;
				chart.mHeight = remAtlasHeight;
				
				curAtlasX += remSrcWidth;
				curSrcY += remAtlasHeight;
				
				remAtlasWidth -= remSrcWidth;
				remSrcHeight -= remAtlasHeight;
				mCharts.push_back(chart);
			}
			else
			{
				chart.mWidth = remSrcWidth;
				chart.mHeight = remSrcHeight;
				mCharts.push_back(chart);
				break;
			}
		}
		else
		{	
			Chart chart;
			chart.mSrcX = curSrcX;
			chart.mSrcY = curSrcY;
			
			chart.mAtlasX = curAtlasX;
			chart.mAtlasY = curAtlasY;
			chart.mFlip = true;
			if(remSrcHeight > remAtlasWidth)
			{			
				assert(remSrcWidth <= remAtlasHeight);
				
				chart.mWidth = remSrcWidth;
				chart.mHeight = remAtlasWidth;
				
				curSrcY += remAtlasWidth;
				curAtlasY += remSrcWidth;
				
				remSrcHeight -= remAtlasWidth;
				remAtlasHeight -= remSrcWidth;
				mCharts.push_back(chart);
			}
			else if(remSrcWidth > remAtlasHeight)
			{			
				assert(remSrcHeight <= remAtlasWidth);
				
				chart.mWidth = remAtlasHeight;
				chart.mHeight = remSrcHeight;
				
				curAtlasX += remSrcHeight;
				curSrcX += remAtlasHeight;
				
				remAtlasWidth -= remSrcHeight;
				remSrcWidth -= remAtlasHeight;
				mCharts.push_back(chart);
			}
			else
			{			
				chart.mWidth = remSrcWidth;
				chart.mHeight = remSrcHeight;
				mCharts.push_back(chart);
				break;
			}
		}
	}
}
Ejemplo n.º 12
0
std::shared_ptr<Texture> LoadPNG(const char *filename)
{
	std::shared_ptr<Texture> retval;

	FILE *fp;
	png_structp png_ptr  = NULL;
	png_infop   info_ptr = NULL;

	{
		std::vector<unsigned char> data;
		std::shared_ptr<RawTexture> rt;

		const int SIG_SIZE = 8;

		fp = fopen(filename, "rb");
		if (!fp)
		{
			retval = nullptr;
			goto RELEASE;
		}

		png_byte sig[SIG_SIZE];
		fread(sig, sizeof(png_byte), 8, fp);
		if (png_sig_cmp(sig, 0, 8))
		{
			retval = nullptr;
			goto RELEASE;
		}

		png_ptr = png_create_read_struct(
				PNG_LIBPNG_VER_STRING,
				NULL,
				NULL,
				NULL);
		if (!png_ptr)
		{
			retval = nullptr;
			goto RELEASE;
		}

		info_ptr = png_create_info_struct(png_ptr);
		if (!info_ptr)
		{
			retval = nullptr;
			goto RELEASE;
		}

		if (setjmp(png_jmpbuf(png_ptr)))
		{
			retval = nullptr;
			goto RELEASE;
		}

		png_init_io(png_ptr, fp);
		png_set_sig_bytes(png_ptr, SIG_SIZE);

		png_read_png(
			png_ptr,
			info_ptr,
			PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND,
			NULL);

		unsigned int  width    = png_get_image_width(png_ptr, info_ptr);
		unsigned int  height   = png_get_image_height(png_ptr, info_ptr);
		unsigned int  rowbytes = png_get_rowbytes(png_ptr, info_ptr);
		unsigned char depth    = png_get_bit_depth(png_ptr, info_ptr) / 8;
		unsigned char channels;
		switch (png_get_color_type(png_ptr, info_ptr))
		{
			case PNG_COLOR_TYPE_GRAY:
				channels = 1;
				break;
			case PNG_COLOR_TYPE_GRAY_ALPHA:
				channels = 2;
				break;
			case PNG_COLOR_TYPE_RGB:
				channels = 3;
				break;
			case PNG_COLOR_TYPE_RGB_ALPHA:
				channels = 4;
				break;
			default:
				fprintf(stderr, "Huh!?\n");
				exit(1);
		}

		unsigned int tex_width    = NextPow2(width);
		unsigned int tex_height   = NextPow2(height);
		unsigned int tex_rowbytes = tex_width * depth * channels;
		data.resize(tex_rowbytes * tex_height);

		png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);
		for (unsigned int i = 0; i < height; ++i)
		{
			unsigned char *tex_row = &data[tex_rowbytes * (height - 1 - i)];

			memcpy(tex_row, row_pointers[i], rowbytes);
			memset(tex_row + rowbytes, 0, tex_rowbytes - rowbytes);
		}

		GLenum tex_format;
		GLenum tex_type = (depth == 1)? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
		switch (channels)
		{
			case 1:
				tex_format = GL_LUMINANCE;
				break;
			case 2:
				tex_format = GL_LUMINANCE_ALPHA;
				break;
			case 3:
				tex_format = GL_RGB;
				break;
			case 4:
				tex_format = GL_RGBA;
				break;
		}

		rt = std::make_shared<RawTexture>();
		rt->Initialize(
			tex_width,
			tex_height,
			tex_format,
			tex_type,
			&data[0]);

		retval = std::make_shared<Texture>(
			rt,
			0,
			0,
			width,
			height);
	}
RELEASE:
	if (png_ptr)
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	}

	if (fp)
	{
		fclose(fp);
	}

	return retval;
}
Ejemplo n.º 13
0
void RoutePoint::EnableDragHandle(bool bEnable)
{
    m_bDrawDragHandle = bEnable;
    if(bEnable){
        if(!m_dragIcon.IsOk()){    
            // Get the icon
            // What size?
            int bm_size = g_Platform->GetDisplayDPmm() * 9;     //9 mm nominal
        
            // What icon?
            wxString UserIconPath = g_Platform->GetSharedDataDir() + _T("uidata") + wxFileName::GetPathSeparator();
            
            wxImage iconSVG = LoadSVGIcon( UserIconPath  + _T("DragHandle.svg"), bm_size, bm_size );
            if(iconSVG.IsOk())
                m_dragIcon = wxBitmap(iconSVG);
            else
                m_dragIcon = *m_pbmIcon;                // Drag handle icon not found
                
            // build a texture
#ifdef ocpnUSE_GL
        /* make rgba texture */
            if(m_dragIconTexture == 0){
                glGenTextures(1, &m_dragIconTexture);
                glBindTexture(GL_TEXTURE_2D, m_dragIconTexture);
                    
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
            
            
                wxImage image = iconSVG;
                int w = image.GetWidth(), h = image.GetHeight();
            
                m_dragIconTextureWidth = NextPow2(w);
                m_dragIconTextureHeight = NextPow2(h);
            
                unsigned char *d = image.GetData();
                unsigned char *a = image.GetAlpha();
                
                unsigned char mr, mg, mb;
                image.GetOrFindMaskColour( &mr, &mg, &mb );
        
                unsigned char *e = new unsigned char[4 * w * h];
                if(d && e){
                    for( int y = 0; y < h; y++ )
                        for( int x = 0; x < w; x++ ) {
                            unsigned char r, g, b;
                            int off = ( y * image.GetWidth() + x );
                            r = d[off * 3 + 0];
                            g = d[off * 3 + 1];
                            b = d[off * 3 + 2];
                            e[off * 4 + 0] = r;
                            e[off * 4 + 1] = g;
                            e[off * 4 + 2] = b;
                        
                            e[off * 4 + 3] =  a ? a[off] : ( ( r == mr ) && ( g == mg ) && ( b == mb ) ? 0 : 255 );
                        }
                }
        
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_dragIconTextureWidth, m_dragIconTextureHeight,
                        0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
                            GL_RGBA, GL_UNSIGNED_BYTE, e);

                delete [] e;
            }
#endif

            // set the drawing metrics
            if(iconSVG.IsOk()){
                m_drag_line_length_man = bm_size;
                m_drag_icon_offset = bm_size;
            }
            else{
                m_drag_line_length_man = 64;
                m_drag_icon_offset = 64;
            }
        }
    }
}
Ejemplo n.º 14
0
void CFreeTypeFont::CreateChar(int index)
{
    FT_Load_Glyph(ft_face_, FT_Get_Char_Index(ft_face_, index), FT_LOAD_DEFAULT);
    FT_Render_Glyph(ft_face_->glyph, FT_RENDER_MODE_NORMAL);
    FT_Bitmap* bitmap = &ft_face_->glyph->bitmap;
    
    auto iw = bitmap->width;
    auto ih = bitmap->rows;
    auto tw = static_cast<unsigned int>(NextPow2(iw));
    auto th = static_cast<unsigned int>(NextPow2(ih));
    
    GLubyte* data = new GLubyte[tw * th];
    
    for(auto ch = (unsigned int) {0}; ch < th; ch++)
    {
        for(auto cw = (unsigned int) {0}; cw < tw; cw++)
        {
            data[ch * tw + cw] = (ch >= ih || cw >= iw) ? 0 : bitmap->buffer[(ih - ch - 1) * iw + cw];
        }
    }
    
    char_textures[index].CreateFromData(data, tw, th, 8, GL_DEPTH_COMPONENT, false);
    char_textures[index].SetFiltering(TEXTURE_FILTER_MAG_BILINEAR, TEXTURE_FILTER_MIN_BILINEAR);
    
    char_textures[index].SetSamplerParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    char_textures[index].SetSamplerParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//        char_textures[index].SetSamplerParameter(GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE_A);
    
    adv_x[index] = ft_face_->glyph->advance.x >> 6;
    bearing_x[index] = ft_face_->glyph->metrics.horiBearingX >> 6;
    char_width[index] = ft_face_->glyph->metrics.width >> 6;
    
    adv_y[index] = (ft_face_->glyph->metrics.height - ft_face_->glyph->metrics.horiBearingY) >> 6;
    bearing_y[index] = ft_face_->glyph->metrics.horiBearingY>>6;
    char_width[index] = ft_face_->glyph->metrics.height>>6;
    
    new_line = std::max(new_line, (int)(ft_face_->glyph->metrics.height >> 6));
    
    //memory waste!
    glm::vec2 quad[] =
    {
        glm::vec2(0.f,(float)(-adv_y[index]+th)),
        glm::vec2(0.f,(float)(-adv_y[index])),
        glm::vec2((float)tw, (float)(-adv_y[index]+th)),
        glm::vec2((float)tw, (float)(-adv_y[index]))
    };
    
    glm::vec2 tex_quad[] =
    {
        glm::vec2(0.f, 1.f),
        glm::vec2(0.f, 0.f),
        glm::vec2(1.f, 1.f),
        glm::vec2(1.f, 0.f)
    };
    
    for(auto i = 0; i < 4; i++)
    {
        vbo_data_.AddData(&quad[i], sizeof(glm::vec2));
        vbo_data_.AddData(&tex_quad[i], sizeof(glm::vec2));
    }
    
    delete[] data;
}

void CFreeTypeFont::Print(const std::string& text, int x, int y, int px_size)
{
    if(!bLoaded_) return;
    
    glBindVertexArray(vao_);
    
    sp_->SetUniform("gSampler", 0);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    auto cur_x = x;
    auto cur_y = y;
    
    if(px_size == -1)
    {
        px_size = loaded_pixel_size;
    }
    
    auto scale = (float)px_size / (float)loaded_pixel_size;
    
    for(auto i = 0lu; i < text.size(); i++)
    {
        if(text[i] == '\n')
        {
            cur_x = x;
            cur_y -= new_line * px_size / loaded_pixel_size;
        }
        else
        {
            auto index = int{text[i]};
            cur_x += bearing_x[index] * px_size / loaded_pixel_size;
            
            if(text[i] != ' ')
            {
                char_textures[index].BindTexture();
                glm::mat4 model_view = glm::translate(glm::mat4(1.f), glm::vec3((float) cur_x, (float) cur_y, 0.f));
                model_view = glm::scale(model_view, glm::vec3(scale));
                sp_->SetUniform("modelViewMatrix", model_view);
                
                glDrawArrays(GL_TRIANGLE_STRIP, index * 4, 4);
            }
            
            cur_x += (adv_x[index] - bearing_x[index]) * px_size / loaded_pixel_size;
        }
    }
    
    glDisable(GL_BLEND);
}

void CFreeTypeFont::SetShaderProgram(ShaderProgram* sh)
{
    sp_ = sh;
}
Ejemplo n.º 15
0
TEST(mylibrary, pow2)
{
	unsigned int powTest = NextPow2(999);
	EXPECT_EQ(1024, powTest);
	
}
Ejemplo n.º 16
0
// but requires updating the texture if the piano changes which is slower (although still quite fast)
// the other problem is the code is difficult to follow and maintain
// can remove this when we know we aren't going to ever be using it
void Piano::UpdateGLTexture()
{
    extern GLenum       g_texture_rectangle_format;
    int w = cc1->GetClientSize().x, h = GetHeight(), tex_w, tex_h;
    if(g_texture_rectangle_format == GL_TEXTURE_2D)
        tex_w = w, tex_h = h;
    else
        tex_w = NextPow2(w), tex_h = NextPow2(h);
    m_texcoords[0] = (float)w / tex_w;
    m_texcoords[1] = (float)h / tex_h;

    // this isn't very pretty but should at least be fast enough
    unsigned char bgcolor[4], tbgcolor[4];
    SetColor(bgcolor, m_backBrush);
    SetColor(tbgcolor, m_backBrush);

    wxColour b = GetGlobalColor( _T("CHBLK") );
    unsigned char bcolor[4] = {b.Red(), b.Green(), b.Blue(), 255};

    ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
    if(style->chartStatusWindowTransparent)
        tbgcolor[3] = 0;

    unsigned char *data = new unsigned char[4*w*h];

    // fill to background color
    for(int x = 0; x < w; x++) {
        unsigned char *pos = data + 4*x;
        memcpy(pos, tbgcolor, 4);
    }

    for(int y = 1; y < 8; y++) {
        unsigned char *pos = data + 4*(y*w);
        memcpy(pos, data, 4*w);
    }

    int nKeys = m_key_array.GetCount();
    // draw the keys
    for( int i = 0; i < nKeys; i++ ) {
        int key_db_index = m_key_array.Item( i );

        if( -1 == key_db_index ) continue;

        bool selected = InArray(m_active_index_array, key_db_index);
        unsigned char color[4];
        if( ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93 ||
            ChartData->GetDBChartType( key_db_index ) == CHART_TYPE_CM93COMP ) {
            if(selected)
                SetColor(color, m_scBrush );
            else
                SetColor(color, m_cBrush );
        } else if( ChartData->GetDBChartFamily( key_db_index ) == CHART_FAMILY_VECTOR ) {
            if(selected)
                SetColor(color, m_svBrush );
            else
                SetColor(color, m_vBrush );
        } else { // Raster Chart
            if(selected)
                SetColor(color, m_slBrush );
            else
                SetColor(color, m_tBrush );
        }

#if 0
        // Check to see if this box appears in the sub_light array
        // If so, add a crosshatch pattern to the brush
        if(InArray(m_eclipsed_index_array, key_db_index)) {
            wxBrush ebrush( dc.GetBrush().GetColour(), wxCROSSDIAG_HATCH );
            dc.SetBrush(ebrush);
        }
#endif
        if(m_bBusy)
            SetColor(color, m_uvBrush );
            
        wxRect box = KeyRect.Item( i );

        bool eclipsed = InArray(m_eclipsed_index_array, key_db_index);

        int sympoint =  m_brounded ? (eclipsed ? 5 : 3) : 1;
        for(int y = 0; y < 6; y++) {
            unsigned char *pos = data + 4*((box.y+y)*w + box.x);
            if(y > sympoint) {
                int line;
                if(y < box.height - sympoint)
                    line = sympoint;
                else
                    line = box.height-y-1; // shouldn't hit
                memcpy(pos, data + 4*((box.y+line)*w + box.x), 4*box.width);
                continue;
            }
            
            for(int x = 0; x < box.width; x++, pos+=4) {
                if(y == 0) {
                    if( m_brounded && (x <= 2 || x >= box.width - 3) )
                        memcpy(pos, tbgcolor, 4);
                    else
                        memcpy(pos, bcolor, 4);
                } else if(m_brounded) {
                    if(y == 1) {
                        if(x == 0 || x == box.width - 1)
                            memcpy(pos, tbgcolor, 4);
                        else if(x == 1 || x == 2 || x == box.width - 3 || x == box.width - 2)
                            memcpy(pos, bcolor, 4);
                        else
                            memcpy(pos, color, 4);
                    } else if(y == 2) {
                        if(x == 0 || x == box.width - 1)
                            memcpy(pos, tbgcolor, 4);
                        else if(x == 1 || x == box.width - 2)
                            memcpy(pos, bcolor, 4);
                        else
                            memcpy(pos, color, 4);
                    } else if(eclipsed) {
                        if(x == 0 || x == box.width - 1)
                            memcpy(pos, bcolor, 4);
                        else {
                            if(y == 3) {
                                if(x <= 4 || x >= box.width - 5)
                                    memcpy(pos, color, 4);
                                else
                                    memcpy(pos, bcolor, 4);
                            } else if(y == 4) {
                                if(x <= 3 || x >= box.width - 4)
                                    memcpy(pos, color, 4);
                                else if(x == 4 || x == box.width - 5)
                                    memcpy(pos, bcolor, 4);
                                else
                                    memcpy(pos, bgcolor, 4);
                            } else {
                                if(x <= 2 || x >= box.width - 3)
                                    memcpy(pos, color, 4);
                                else if(x == 3 || x == box.width - 4)
                                    memcpy(pos, bcolor, 4);
                                else
                                    memcpy(pos, bgcolor, 4);
                            }
                        }
                    } else
                        goto def;
                } else {
                def:
                    if(x == 0 || x == box.width - 1)
                        memcpy(pos, bcolor, 4);
                    else
                        memcpy(pos, color, 4);
                }
            }
        }
    }

    // quickly fill the rest via symmetry
    for(int y = 8; y < h; y++) {
        int line;
        if(y < h - 7)
            line = 7;
        else
            line = h-y-1;
        memcpy(data + 4*(y*w), data + 4*(line*w), 4*w);
    }

    if(!m_tex)
        glGenTextures( 1, &m_tex );

    glBindTexture(GL_TEXTURE_2D, m_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    if(g_texture_rectangle_format == GL_TEXTURE_2D)
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
    else {
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
        glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data );
    }

    delete [] data;
}
/*
 * Core function for computing the ROM waveform.
 * Evaluates projection coefficients and shifts in time and phase at desired q.
 * Construct 1D splines for amplitude and phase.
 * Compute strain waveform from amplitude and phase.
*/
static INT4 EOBNRv2HMROMCore(
  COMPLEX16FrequencySeries **hptilde,
  COMPLEX16FrequencySeries **hctilde,
  REAL8 phiRef,
  REAL8 deltaF,
  REAL8 fLow,
  REAL8 fHigh,
  REAL8 fRef,
  REAL8 distance,
  REAL8 inclination,
  REAL8 Mtot_sec,
  REAL8 q)
{
  INT4 ret = XLAL_SUCCESS;
  INT4 i;
  INT4 j;
  double tpeak22estimate = 0.;
  /* Check output arrays */
  if(!hptilde || !hctilde) XLAL_ERROR(XLAL_EFAULT);
  if(*hptilde || *hctilde)
  {
    XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p\n",(*hptilde),(*hctilde));
    XLAL_ERROR(XLAL_EFAULT);
  }

  /* Check if the data has been set up */
  if(__lalsim_EOBNRv2HMROM_setup) {
    XLALPrintError("Error: the ROM data has not been set up\n");
    XLAL_ERROR(XLAL_EFAULT);
  }
  /* Set the global pointers to data */
  ListmodesEOBNRHMROMdata* listdata = *__lalsim_EOBNRv2HMROM_data;
  ListmodesEOBNRHMROMdata_interp* listdata_interp = *__lalsim_EOBNRv2HMROM_interp;

  /* Global amplitude prefactor - includes total mass scaling, Fourier scaling, distance scaling, and undoing an additional arbitrary scaling */
  REAL8 Mtot_msol = Mtot_sec / LAL_MTSUN_SI; /* Mtot_msol and M_ROM in units of solar mass */
  REAL8 amp0 = (Mtot_msol/M_ROM) * Mtot_sec * 1.E-16 * 1.E6 * LAL_PC_SI / distance;

  /* Highest allowed geometric frequency for the first mode of listmode in the ROM - used for fRef
   * by convention, we use the first mode of listmode (presumably the 22) for phiref */
  ListmodesEOBNRHMROMdata* listdata_ref = ListmodesEOBNRHMROMdata_GetMode(listdata, listmode[0][0], listmode[0][1]);
  EOBNRHMROMdata* data_ref = listdata_ref->data;
  REAL8 Mf_ROM_max_ref = gsl_vector_get(data_ref->freq, nbfreq-1);
  /* Convert to geometric units for frequency */
  REAL8 fLow_geom = fLow * Mtot_sec;
  REAL8 fHigh_geom = fHigh * Mtot_sec;
  REAL8 fRef_geom = fRef * Mtot_sec;
  REAL8 deltaF_geom = deltaF * Mtot_sec;

  /* Enforce allowed geometric frequency range */
  if (fLow_geom < Mf_ROM_min) { /* Enforce minimal frequency */
    XLALPrintWarning("Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
    fLow_geom = Mf_ROM_min;
  }
  /* Default highest frequency */
  if (fHigh == 0)
    fHigh_geom = Mf_ROM_max;
  /* In case the user asks for a frequency higher than covered by the ROM, we keep it that way as we will just 0-pad the waveform (and do it anyway for some modes) */
  if (fRef_geom > Mf_ROM_max_ref || fRef_geom == 0)
    fRef_geom = Mf_ROM_max_ref; /* If fRef > fhigh or 0 we reset fRef to default value of cutoff frequency for the first mode of the list (presumably the 22 mode) */
  if (0 < fRef_geom && fRef_geom < Mf_ROM_min) {
    XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Setting it to the lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
    fRef_geom = Mf_ROM_min;
  }
  /* Set up output array with size closest power of 2 - fHigh is the upper frequency specified by the user */
  size_t nbpt = NextPow2(fHigh_geom / deltaF_geom) + 1;

  /* Internal storage for the projection coefficients and shifts in time and phase */
  /* Initialized only once, and reused for the different modes */
  EOBNRHMROMdata_coeff *data_coeff = NULL;
  EOBNRHMROMdata_coeff_Init(&data_coeff);
  /* Create spherical harmonic frequency series that will contain the hlm's */
  SphHarmFrequencySeries** hlmsphharmfreqseries = XLALMalloc(sizeof(SphHarmFrequencySeries));
  *hlmsphharmfreqseries = NULL;

  /* GPS time definition - common to all modes */
  LIGOTimeGPS tC;
  XLALGPSAdd(&tC, -1. / deltaF);  /* coalesce at t=0 */

  /* The phase change imposed by phiref, from the phase of the first mode in the list - to be set in the first step of the loop on the modes */
  REAL8 phase_change_ref = 0;

  /* Main loop over the modes */
  for( i=0; i<nbmode; i++ ){
    UINT4 l = listmode[i][0];
    INT4 m = listmode[i][1];

    /* Getting the relevant modes in the lists of data */
    ListmodesEOBNRHMROMdata* listdata_mode = ListmodesEOBNRHMROMdata_GetMode(listdata, l, m);
    ListmodesEOBNRHMROMdata_interp* listdata_interp_mode = ListmodesEOBNRHMROMdata_interp_GetMode(listdata_interp, l, m);

    /* Evaluating the projection coefficients and shift in time and phase */
    ret |= Evaluate_Spline_Data(q, listdata_interp_mode->data_interp, data_coeff);

    /* Evaluating the unnormalized amplitude and unshifted phase vectors for the mode */
    /* Notice a change in convention: B matrices are transposed with respect to the B matrices in SEOBNRROM */
    /* amp_pts = Bamp . Camp_coeff */
    /* phi_pts = Bphi . Cphi_coeff */
    gsl_vector* amp_f = gsl_vector_alloc(nbfreq);
    gsl_vector* phi_f = gsl_vector_alloc(nbfreq);
    gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bamp, data_coeff->Camp_coeff, 0.0, amp_f);
    gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bphi, data_coeff->Cphi_coeff, 0.0, phi_f);

    /* The downsampled frequencies for the mode - we undo the rescaling of the frequency for the 44 and 55 modes */
    gsl_vector* freq_ds = gsl_vector_alloc(nbfreq);
    gsl_vector_memcpy(freq_ds, listdata_mode->data->freq);
    if ( l==4 && m==4) gsl_vector_scale( freq_ds, 1./Scaling44(q));
    if ( l==5 && m==5) gsl_vector_scale( freq_ds, 1./Scaling55(q));

    /* Evaluating the shifts in time and phase - conditional scaling for the 44 and 55 modes */
    /* Note: the stored values of 'shifttime' correspond actually to 2pi*Deltat */
    SplineList* shifttime_splinelist = listdata_interp_mode->data_interp->shifttime_interp;
    SplineList* shiftphase_splinelist = listdata_interp_mode->data_interp->shiftphase_interp;
    REAL8 twopishifttime;
    if( l==4 && m==4) {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling44(q);
    }
    else if( l==5 && m==5) {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling55(q);
    }
    else {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel);
    }
    REAL8 shiftphase = gsl_spline_eval(shiftphase_splinelist->spline, q, shiftphase_splinelist->accel);

    /* If first mode in the list, assumed to be the 22 mode, set totalshifttime and phase_change_ref */
    if( i==0 ) {
      if(l==2 && m==2) {
      /* Setup 1d cubic spline for the phase of the 22 mode */
      gsl_interp_accel* accel_phi22 = gsl_interp_accel_alloc();
      gsl_spline* spline_phi22 = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
      gsl_spline_init(spline_phi22, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq);
      /* Compute the shift in time needed to set the peak of the 22 mode roughly at t=0 */
      /* We use the SPA formula tf = -(1/2pi)*dPsi/df to estimate the correspondence between frequency and time */
      /* The frequency corresponding to the 22 peak is omega22peak/2pi, with omega22peak taken from the fit to NR in Pan&al 1106 EOBNRv2HM paper */
      double f22peak = fmin(omega22peakOfq(q)/(2*LAL_PI), Mf_ROM_max_ref); /* We ensure we evaluate the spline within its range */
      tpeak22estimate = -1./(2*LAL_PI) * gsl_spline_eval_deriv(spline_phi22, f22peak, accel_phi22);
      /* Determine the change in phase (to be propagated to all modes) required to have phi22(fRef) = 2*phiRef */
      phase_change_ref = 2*phiRef + (gsl_spline_eval(spline_phi22, fRef_geom, accel_phi22) - (twopishifttime - 2*LAL_PI*tpeak22estimate) * fRef_geom - shiftphase);

      gsl_spline_free(spline_phi22);
      gsl_interp_accel_free(accel_phi22);
      }
      else {
	XLALPrintError("Error: the first mode in listmode must be the 22 mode to set the changes in phase and time \n");
	XLAL_ERROR(XLAL_EFAILED);
      }
    }
    /* Total shift in time, and total change in phase for this mode */
    double totaltwopishifttime = twopishifttime - 2*LAL_PI*tpeak22estimate;
    double constphaseshift = (double) m/listmode[0][1] * phase_change_ref + shiftphase;

    /* Initialize the complex series for the mode - notice that metadata used here is useless, only the one for the final output will matter */
    COMPLEX16FrequencySeries* mode = XLALCreateCOMPLEX16FrequencySeries("mode hlm", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);
    memset(mode->data->data, 0, nbpt * sizeof(COMPLEX16));
    /* Setup 1d cubic spline for the phase and amplitude of the mode */
    gsl_interp_accel* accel_phi = gsl_interp_accel_alloc();
    gsl_interp_accel* accel_amp = gsl_interp_accel_alloc();
    gsl_spline* spline_phi = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
    gsl_spline* spline_amp = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
    gsl_spline_init(spline_phi, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq);
    gsl_spline_init(spline_amp, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(amp_f,0), nbfreq);
    /* Interval in frequency covered by the ROM */
    REAL8 fLow_geom_mode = gsl_vector_get(freq_ds, 0);
    REAL8 fHigh_geom_mode = fmin(gsl_vector_get(freq_ds, nbfreq-1), fHigh_geom);
    /* Initialize the loop - values outside this range in j are 0 by default */
    INT4 jStart = (UINT4) ceil(fLow_geom_mode / deltaF_geom);
    INT4 jStop = (UINT4) ceil(fHigh_geom_mode / deltaF_geom);
    COMPLEX16 *modedata = mode->data->data;
    /* Mode-dependent complete amplitude prefactor */
    REAL8 amp_pre = amp0 * ModeAmpFactor( l, m, q);
    /* Loop on the frequency samples chosen to evaluate the waveform */
    /* We set apart the first and last step to avoid falling outside of the range of the splines by numerical errors */
    REAL8 f, A, phase;

    f = fmax(fLow_geom_mode, jStart*deltaF_geom);
    A = gsl_spline_eval(spline_amp, f, accel_amp);
    phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
    modedata[jStart] = amp_pre * A * cexp(I*phase);

    for (j=jStart+1; j<jStop-1; j++) {
      f = j*deltaF_geom;
      A = gsl_spline_eval(spline_amp, f, accel_amp);
      phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
      modedata[j] = amp_pre * A * cexp(I*phase);
    }

    f = fmin(fHigh_geom_mode, (jStop-1)*deltaF_geom);
    A = gsl_spline_eval(spline_amp, f, accel_amp);
    phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
    modedata[jStop-1] = amp_pre * A * cexp(I*phase);

    /* Add the computed mode to the SphHarmFrequencySeries structure */
    *hlmsphharmfreqseries = XLALSphHarmFrequencySeriesAddMode(*hlmsphharmfreqseries, mode, l, m);

    /* Cleanup for the mode */
    gsl_spline_free(spline_amp);
    gsl_spline_free(spline_phi);
    gsl_interp_accel_free(accel_amp);
    gsl_interp_accel_free(accel_phi);
    gsl_vector_free(amp_f);
    gsl_vector_free(phi_f);
    gsl_vector_free(freq_ds);
    XLALDestroyCOMPLEX16FrequencySeries(mode);

  }
  /* Cleanup of the coefficients data structure */
  EOBNRHMROMdata_coeff_Cleanup(data_coeff);

  /* Combining the modes for a hplus, hcross output */
  /* Initialize the complex series hplus, hcross */
  *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);
  *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);

  if (!(hptilde) || !(*hctilde)) XLAL_ERROR(XLAL_EFUNC);
  memset((*hptilde)->data->data, 0, nbpt * sizeof(COMPLEX16));
  memset((*hctilde)->data->data, 0, nbpt * sizeof(COMPLEX16));

  XLALUnitDivide(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit);
  XLALUnitDivide(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit);

  /* Adding the modes to form hplus, hcross
   * - use of a function that copies XLALSimAddMode but for Fourier domain structures */
  INT4 sym; /* sym will decide whether to add the -m mode (when equatorial symmetry is present) */
  for( i=0; i<nbmode; i++){
    INT4 l = listmode[i][0];
    INT4 m = listmode[i][1];
    COMPLEX16FrequencySeries* mode = XLALSphHarmFrequencySeriesGetMode(*hlmsphharmfreqseries, l, m);
    if ( m==0 ) sym = 0; /* We test for hypothetical m=0 modes */
    else sym = 1;
    FDAddMode( *hptilde, *hctilde, mode, inclination, 0., l, m, sym); /* The phase \Phi is set to 0 - assumes phiRef is defined as half the phase of the 22 mode h22 (or the first mode in the list), not for h = hplus-I hcross */
  }

  /* Destroying the list of frequency series for the modes, including the COMPLEX16FrequencySeries that it contains */
  XLALDestroySphHarmFrequencySeries(*hlmsphharmfreqseries);
  XLALFree(hlmsphharmfreqseries);

  /* Additional complex conjugation of hptilde, hctilde - due to the difference in convention for the Fourier transform between LAL and the ROM internals */
  COMPLEX16* datap = (*hptilde)->data->data;
  COMPLEX16* datac = (*hctilde)->data->data;
  for ( j = 0; j < (INT4) (*hptilde)->data->length; ++j ) {
    datap[j] = conj(datap[j]);
  }
  for ( j = 0; j < (INT4) (*hctilde)->data->length; ++j ) {
    datac[j] = conj(datac[j]);
  }

  return(XLAL_SUCCESS);
}
void GPFont::PreparePixMap(int ch, FT_Face face)
{
   // on fait la conversion du caractère en indice de glyphe
   // puis en bitmap antialiasé en une commande:
   FT_Load_Char(face, ch, FT_LOAD_RENDER);
   FT_Bitmap* pgpix = &face->glyph->bitmap;  // raccourci
   int w, h;
   w = NextPow2(pgpix->width);   // on fait une texture alignée
   h = NextPow2(pgpix->rows);
   // on alloue le pixmap (bitmap monochrome-alpha)
   GLubyte* pixmap = new GLubyte[w * h * 2];
   // il faut remplir cet espace et copier la glyphe.
   // attention au padding
   int x, y;
   for (x = 0; x < w; ++x)
   {
      for (y = 0; y < h; ++y)
      {
         if (x < pgpix->width && y < pgpix->rows)
            pixmap[2 * (y * w + x)] = pixmap[2 * (y * w + x) + 1] = pgpix->buffer[y * pgpix->width + x];
         else
            pixmap[2 * (y * w + x)] = pixmap[2 * (y * w + x) + 1] = 0;  // chrome noir et alpha 100%
      }
   }
   glBindTexture(GL_TEXTURE_2D, texNames[ch]);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  // pas pigé pkoi ca devait être là ca
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixmap);

   glNewList(listBase + ch, GL_COMPILE);
   {
      // activer la bonne texture:
      glBindTexture(GL_TEXTURE_2D, texNames[ch]);
      glPushMatrix();
      // déplacer un peu a droite (voir la métrique des glyphes):
      glTranslatef(face->glyph->bitmap_left, 0, 0);
      // déplacer en bas en cas de glyphe dépassant la base-line:
      glTranslatef(0, face->glyph->bitmap_top - pgpix->rows, 0);

      // trouver les coordonnées de texture où s'arreter
      // c'est un contre effet du padding:
      float	u, v;
      u = (float)pgpix->width / w;
      v = (float)pgpix->rows / h;

      // on dessine le sprite:

      glBegin(GL_QUADS);
      {
         glTexCoord2d(0, 0); glVertex3f(0, pgpix->rows, 0);
         glTexCoord2d(0, v); glVertex3f(0, 0, 0);
         glTexCoord2d(u, v); glVertex3f(pgpix->width, 0, 0);
         glTexCoord2d(u, 0); glVertex3f(pgpix->width, pgpix->rows, 0);
      }
      glEnd();
      glPopMatrix();
      // on stocke les avances pour faire la fonction qui donne la largeur d'une chaine
      glyph_advances[ch] = face->glyph->advance.x >> 6;
      // on avance le 'stylo' de ce qu'il faut dans la métrique:
      glTranslatef(face->glyph->advance.x >> 6, 0, 0);
   }
   glEndList();

   delete [] pixmap;
}
Ejemplo n.º 19
0
static int IMRPhenomDGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< phase at peak */
    const REAL8 deltaF,                /**< frequency resolution */
    const REAL8 m1,                    /**< mass of companion 1 [solar masses] */
    const REAL8 m2,                    /**< mass of companion 2 [solar masses] */
    const REAL8 chi1_in,               /**< aligned-spin of companion 1 */
    const REAL8 chi2_in,               /**< aligned-spin of companion 2 */
    const REAL8 f_min,                 /**< start frequency */
    const REAL8 f_max,                 /**< end frequency */
    const REAL8 distance               /**< distance to source (m) */
) {
  LIGOTimeGPS ligotimegps_zero = LIGOTIMEGPSZERO; // = {0, 0}

  const REAL8 M = m1 + m2;
  REAL8 eta = m1 * m2 / (M * M);
  const REAL8 M_sec = M * LAL_MTSUN_SI;

  REAL8 chi1, chi2;
  if (m1>m2) { // swap spins
    chi1 = chi1_in;
    chi2 = chi2_in;
  } else {
    chi1 = chi2_in;
    chi2 = chi1_in;
  }

  /* Compute the amplitude pre-factor */
  REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance;

  /* Allocate htilde */
  size_t n = NextPow2(f_max / deltaF) + 1;
  /* Coalesce at t=0 */
  XLALGPSAdd(&ligotimegps_zero, -1. / deltaF); // shift by overall length in time
  *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0,
      deltaF, &lalStrainUnit, n);
  memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
  XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);
  if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);

  size_t ind_min = (size_t) (f_min / deltaF);
  size_t ind_max = (size_t) (f_max / deltaF);

  // Calculate phenomenological parameters
  IMRPhenomDAmplitudeCoefficients *pAmp = ComputeIMRPhenomDAmplitudeCoefficients(eta, chi1, chi2);
  IMRPhenomDPhaseCoefficients *pPhi = ComputeIMRPhenomDPhaseCoefficients(eta, chi1, chi2);
  if (!pAmp || !pPhi) XLAL_ERROR(XLAL_EFUNC);

  // Compute coefficients to make phase C^1
  ComputeIMRPhenDPhaseConnectionCoefficients(pPhi);

  /* Now generate the waveform */
  #pragma omp parallel for
  for (size_t i = ind_min; i < ind_max; i++) {

    REAL8 Mf = M_sec * i * deltaF; // geometric frequency

    REAL8 amp = IMRPhenDAmplitude(Mf, pAmp);
    REAL8 phi = IMRPhenDPhase(Mf, pPhi);

    phi -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase

    ((*htilde)->data->data)[i] = amp0 * amp * cexp(-I * phi);
  }

  LALFree(pAmp);
  LALFree(pPhi);

  return XLAL_SUCCESS;
}
Ejemplo n.º 20
0
/**
 * Driver routine to compute the spin-aligned, inspiral-merger-ringdown
 * phenomenological waveform IMRPhenomC in the frequency domain.
 *
 * Reference: http://arxiv.org/pdf/1005.3306v3.pdf
 * - Waveform: Eq.(5.3)-(5.13)
 * - Coefficients: Eq.(5.14) and Table II
 *
 * All input parameters should be in SI units. Angles should be in radians.
 */
int XLALSimIMRPhenomCGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< orbital phase at peak (rad) */
    const REAL8 deltaF,                /**< sampling interval (Hz) */
    const REAL8 m1_SI,                 /**< mass of companion 1 (kg) */
    const REAL8 m2_SI,                 /**< mass of companion 2 (kg) */
    const REAL8 chi,                   /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,                 /**< starting GW frequency (Hz) */
    const REAL8 f_max,                 /**< end frequency; 0 defaults to ringdown cutoff freq */
    const REAL8 distance               /**< distance of source (m) */
) {
  BBHPhenomCParams *params;
  int status;
  REAL8 f_max_prime;

  /* external: SI; internal: solar masses */
  const REAL8 m1 = m1_SI / LAL_MSUN_SI;
  const REAL8 m2 = m2_SI / LAL_MSUN_SI;

  /* check inputs for sanity */
  if (*htilde) XLAL_ERROR(XLAL_EFAULT);
  if (deltaF <= 0) XLAL_ERROR(XLAL_EDOM);
  if (m1 <= 0) XLAL_ERROR(XLAL_EDOM);
  if (m2 <= 0) XLAL_ERROR(XLAL_EDOM);
  if (fabs(chi) > 1) XLAL_ERROR(XLAL_EDOM);
  if (f_min <= 0) XLAL_ERROR(XLAL_EDOM);
  if (f_max < 0) XLAL_ERROR(XLAL_EDOM);
  if (distance <= 0) XLAL_ERROR(XLAL_EDOM);

  /* If spins are above 0.9 or below -0.9, throw an error */
  if (chi > 0.9 || chi < -0.9)
      XLAL_ERROR(XLAL_EDOM, "Spins outside the range [-0.9,0.9] are not supported\n");

  /* If mass ratio is above 4 and below 20, give a warning, and if it is above
   * 20, throw an error */
  REAL8 q = (m1 > m2) ? (m1 / m2) : (m2 / m1);

  if (q > 20.0)
      XLAL_ERROR(XLAL_EDOM, "Mass ratio is way outside the calibration range. m1/m2 should be <= 20.\n");
  else if (q > 4.0)
      XLAL_PRINT_WARNING("Warning: The model is only calibrated for m1/m2 <= 4.\n");

  /* phenomenological parameters*/
  params = ComputeIMRPhenomCParams(m1, m2, chi);
  if (!params) XLAL_ERROR(XLAL_EFUNC);
  if (params->fCut <= f_min)
      XLAL_ERROR(XLAL_EDOM, "(fCut = 0.15M) <= f_min\n");

  /* default f_max to params->fCut */
  f_max_prime = f_max ? f_max : params->fCut;
  f_max_prime = (f_max_prime > params->fCut) ? params->fCut : f_max_prime;
  if (f_max_prime <= f_min)
      XLAL_ERROR(XLAL_EDOM, "f_max <= f_min\n");

  status = IMRPhenomCGenerateFD(htilde, phi0, deltaF, m1, m2, f_min, f_max_prime, distance, params);

  if (f_max_prime < f_max) {
    // The user has requested a higher f_max than Mf=params->fCut.
    // Resize the frequency series to fill with zeros to fill with zeros beyond the cutoff frequency.
    size_t n_full = NextPow2(f_max / deltaF) + 1; // we actually want to have the length be a power of 2 + 1
    *htilde = XLALResizeCOMPLEX16FrequencySeries(*htilde, 0, n_full);
  }

  LALFree(params);
  return status;
}
Ejemplo n.º 21
0
void ODPoint::DrawGL( PlugIn_ViewPort &pivp )
{
    if( !m_bIsVisible )
    return;

    //    Optimization, especially apparent on tracks in normal cases
    if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return;

    if(m_wpBBox.GetValid() &&
        pivp.chart_scale == m_wpBBox_chart_scale &&
        pivp.rotation == m_wpBBox_rotation) {
    }

    wxPoint r;
    wxRect hilitebox;
    unsigned char transparency = 150;

    GetCanvasPixLL( &g_VP, &r, m_lat, m_lon );

//    Substitue icon?
    wxBitmap *pbm;
    if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) )
        pbm = g_pODPointMan->GetIconBitmap(  _T ( "activepoint" ) );
    else
        pbm = m_pbmIcon;

    int sx2 = pbm->GetWidth() / 2;
    int sy2 = pbm->GetHeight() / 2;

//    Calculate the mark drawing extents
    wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 );          // the bitmap extents
    
    float  l_fIconScaleFactor = GetOCPNChartScaleFactor_Plugin();
    wxRect r3 = r1;
    if( m_bShowName ) {
        if( !m_pMarkFont ) {
            m_pMarkFont = GetOCPNScaledFont_PlugIn( wxT( "Marks" ) );
            m_FontColor = GetFontColour_PlugIn( wxS( "Marks" ) );
            CalculateNameExtents();
        }

        if( m_pMarkFont ) {
            wxRect r2( r.x + (m_NameLocationOffsetX * l_fIconScaleFactor), r.y + (m_NameLocationOffsetY * l_fIconScaleFactor),
                       m_NameExtents.x, m_NameExtents.y );
            r3.Union( r2 );
        }
    }

    hilitebox = r3;
    hilitebox.x -= r.x;
    hilitebox.y -= r.y;
    float radius;
    if( IsTouchInterface_PlugIn() ){
        hilitebox.Inflate( 20 );
        radius = 20.0f;
    }
    else{
        hilitebox.Inflate( 4 );
        radius = 4.0f;
    }
    
    /* update bounding box */
    if(!m_wpBBox.GetValid() || pivp.chart_scale != m_wpBBox_chart_scale || pivp.rotation != m_wpBBox_rotation) {
        double lat1, lon1, lat2, lon2;
        wxPoint wxpoint;
        wxpoint.x = r.x+hilitebox.x;
        wxpoint.y = r.y + hilitebox.height;
        GetCanvasLLPix( &pivp, wxpoint, &lat1, &lon1 );
        wxpoint.x = r.x + hilitebox.x + hilitebox.width;
        wxpoint.y = r.y + hilitebox.y;
        GetCanvasLLPix( &pivp, wxpoint, &lat2, &lon2 );

        if(lon1 > lon2)
            m_wpBBox.Set(lat1, lon1, lat2, lon2+360);
        else
            m_wpBBox.Set(lat1, lon1, lat2, lon2);
        m_wpBBox_chart_scale = pivp.chart_scale;
        m_wpBBox_rotation = pivp.rotation;
    }

    ODDC dc;

    //  Highlite any selected point
    if( m_bPtIsSelected || m_bIsBeingEdited ) {
        wxColour hi_colour;
        if( m_bPointPropertiesBlink || m_bPathManagerBlink ){
            wxPen *pen = g_pPathMan->GetActiveODPointPen();
            hi_colour = pen->GetColour();
        }
        else{
            GetGlobalColor( wxS( "YELO1" ), &hi_colour );
        }
        
        g_ocpn_draw_pi->AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius,
                       hi_colour, transparency );
    }
    
    bool bDrawHL = false;

    if( (m_bPointPropertiesBlink || m_bPathManagerBlink) && ( g_ocpn_draw_pi->nBlinkerTick & 1 ) ) bDrawHL = true;

    if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) {
        int glw, glh;
        unsigned int IconTexture = g_pODPointMan->GetIconTexture( pbm, glw, glh );
        
        glBindTexture(GL_TEXTURE_2D, IconTexture);
        
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        
        glColor3f(1, 1, 1);
        
        float l_ChartScaleFactorExp = GetOCPNChartScaleFactor_Plugin();
        float w = r1.width * l_ChartScaleFactorExp;
        float h = r1.height * l_ChartScaleFactorExp;
        float x = r.x - w/2; 
        float y = r.y - h/2;
        float u = (float)r1.width/glw, v = (float)r1.height/glh;
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(x, y);
        glTexCoord2f(u, 0); glVertex2f(x+w, y);
        glTexCoord2f(u, v); glVertex2f(x+w, y+h);
        glTexCoord2f(0, v); glVertex2f(x, y+h);
        glEnd();
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
    }

    if( m_bShowName && m_pMarkFont ) {
        int w = m_NameExtents.x, h = m_NameExtents.y;
        if(!m_iTextTexture && w && h) {
            wxBitmap tbm(w, h); /* render text on dc */
            wxMemoryDC dc;
            dc.SelectObject( tbm );               
            dc.SetBackground( wxBrush( *wxBLACK ) );
            dc.Clear();
            dc.SetFont( *m_pMarkFont );
            dc.SetTextForeground( *wxWHITE );
            dc.DrawText( m_ODPointName, 0, 0);
            dc.SelectObject( wxNullBitmap );
            
            /* make alpha texture for text */
            wxImage image = tbm.ConvertToImage();
            unsigned char *d = image.GetData();
            unsigned char *e = new unsigned char[w * h];
            if(d && e){
                for( int p = 0; p < w*h; p++)
                    e[p] = d[3*p + 0];
            }
            
            /* create texture for rendered text */
            glGenTextures(1, &m_iTextTexture);
            glBindTexture(GL_TEXTURE_2D, m_iTextTexture);
            
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

            m_iTextTextureWidth = NextPow2(w);
            m_iTextTextureHeight = NextPow2(h);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_iTextTextureWidth, m_iTextTextureHeight,
                         0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
                            GL_ALPHA, GL_UNSIGNED_BYTE, e);
            delete [] e;
        }

        if(m_iTextTexture) {
            /* draw texture with text */
            glBindTexture(GL_TEXTURE_2D, m_iTextTexture);
            
            glEnable(GL_TEXTURE_2D);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
            glColor3ub(m_FontColor.Red(), m_FontColor.Green(), m_FontColor.Blue());
            
            int x = r.x + (m_NameLocationOffsetX * l_fIconScaleFactor), y = r.y + (m_NameLocationOffsetY * l_fIconScaleFactor);
            float u = (float)w/m_iTextTextureWidth, v = (float)h/m_iTextTextureHeight;
            glBegin(GL_QUADS);
            glTexCoord2f(0, 0); glVertex2f(x, y);
            glTexCoord2f(u, 0); glVertex2f(x+w, y);
            glTexCoord2f(u, v); glVertex2f(x+w, y+h);
            glTexCoord2f(0, v); glVertex2f(x, y+h);
            glEnd();
            glDisable(GL_BLEND);
            glDisable(GL_TEXTURE_2D);
        }
    }
    
    // Draw ODPoint range rings if activated
    if( m_iODPointRangeRingsNumber && m_bShowODPointRangeRings ) {
        double factor = 1.00;
        if( m_iODPointRangeRingsStepUnits == 1 )          // nautical miles
            factor = 1 / 1.852;
        
        factor *= m_fODPointRangeRingsStep;
        
        double tlat, tlon;
        wxPoint r1;
        ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon );
        GetCanvasPixLL( &g_VP, &r1,  tlat, tlon);
        
        double lpp = sqrt( pow( (double) (r.x - r1.x), 2) +
        pow( (double) (r.y - r1.y), 2 ) );
        int pix_radius = (int) lpp;
        
        wxPen ppPen1( m_wxcODPointRangeRingsSchemeColour, m_iRangeRingWidth, m_iRangeRingStyle );
        wxBrush saveBrush = dc.GetBrush();
        wxPen savePen = dc.GetPen();
        dc.SetPen( ppPen1 );
        dc.SetBrush( wxBrush( m_wxcODPointRangeRingsSchemeColour, wxBRUSHSTYLE_TRANSPARENT ) );
        dc.SetGLStipple();
        
        for( int i = 1; i <= m_iODPointRangeRingsNumber; i++ )
            dc.StrokeCircle( r.x, r.y, i * pix_radius );
        
        glDisable( GL_LINE_STIPPLE );
        
        dc.SetPen( savePen );
        dc.SetBrush( saveBrush );
    }
    
    if( m_bPointPropertiesBlink || m_bPathManagerBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker
    
    //    This will be useful for fast icon redraws
    CurrentRect_in_DC.x = r.x + hilitebox.x;
    CurrentRect_in_DC.y = r.y + hilitebox.y;
    CurrentRect_in_DC.width = hilitebox.width;
    CurrentRect_in_DC.height = hilitebox.height;

    if( m_bPointPropertiesBlink || m_bPathManagerBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker
}
Ejemplo n.º 22
0
void TextPoint::DrawGL( PlugIn_ViewPort &pivp )
{
    if( !m_bIsVisible )
        return;
    
    if( m_iDisplayTextWhen == ID_TEXTPOINT_DISPLAY_TEXT_SHOW_ALWAYS || m_iDisplayTextWhen == ID_TEXTPOINT_DISPLAY_TEXT_SHOW_ON_ROLLOVER ) {
        if( m_TextPointText.Len() > 0 ) {
            CalculateTextExtents();
            int teX, teY;
            int scalefactor = round(g_ocpn_draw_pi->m_chart_scale / m_natural_scale);
            
            if(m_natural_scale > (g_ocpn_draw_pi->m_chart_scale / 2) ) {
                teX = m_TextExtents.x;
                teY = m_TextExtents.y;
            } else {
                teX = m_TextExtents.x / scalefactor;
                teY = m_TextExtents.y / scalefactor;
            }
            
            if(teX > 0 && teY > 0 && scalefactor <= 8 ) {
                switch ( m_iTextPosition )
                {
                    case ID_TEXT_TOP:
                        m_TextLocationOffsetX = g_iTextTopOffsetX;
                        m_TextLocationOffsetY = g_iTextTopOffsetY - teY;
                        break;
                    case ID_TEXT_CENTRE_TOP:
                        m_TextLocationOffsetX = g_iTextTopOffsetX - (teX / 2);
                        m_TextLocationOffsetY = g_iTextTopOffsetY - teY;
                        break;
                    case ID_TEXT_BOTTOM:
                        m_TextLocationOffsetX = g_iTextBottomOffsetX;
                        m_TextLocationOffsetY = g_iTextBottomOffsetY;
                        if(m_bShowName) m_TextLocationOffsetY += g_iTextBottomNameExtraOffsetY;
                        break;
                    case ID_TEXT_CENTRE_BOTTOM:
                        m_TextLocationOffsetX = g_iTextBottomOffsetX - (teX / 2);
                        m_TextLocationOffsetY = g_iTextBottomOffsetY;
                        break;
                    case ID_TEXT_CENTRE:
                        m_TextLocationOffsetX = g_iTextCentreOffsetX - (teX / 2);
                        m_TextLocationOffsetY = g_iTextCentreOffsetY - (teY / 2);
                        break;
                    case ID_TEXT_RIGHT:
                        m_TextLocationOffsetX = g_iTextRightOffsetX;
                        m_TextLocationOffsetY = g_iTextRightOffsetY;
                        break;
                    case ID_TEXT_LEFT:
                        m_TextLocationOffsetX = g_iTextLeftOffsetX - teX;
                        m_TextLocationOffsetY = g_iTextLeftOffsetY;
                        break;
                }
                int sx2 = m_pbmIcon->GetWidth() / 2;
                int sy2 = m_pbmIcon->GetHeight() / 2;
                
                //    Calculate the mark drawing extents
                wxPoint r;
                GetCanvasPixLL( g_pivp, &r,  m_lat, m_lon);    
                wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 );           // the bitmap extents
                if( m_DisplayTextFont.IsOk() ) {
                    // Added to help with display of text (stops end clipping)
                    teX += 20;
                    wxRect r2( r.x + m_TextLocationOffsetX, r.y + m_TextLocationOffsetY, teX,
                            teY );
                    r1.Union( r2 );
                    
                    r.x = r.x + m_TextLocationOffsetX;
                    r.y = r.y + m_TextLocationOffsetY;
                    if( scalefactor != m_scale_factor || m_bTextChanged || ( !m_iDisplayTextTexture && teX != 0 && teY != 0 ) ) {
                        m_scale_factor = scalefactor;
                        m_bTextChanged = false;
                        wxBitmap tbm(teX, teY); /* render text on dc */
                        wxMemoryDC dc;
                        dc.SelectObject( tbm );               
                        dc.SetBackground( wxBrush( *wxBLACK ) );
                        dc.Clear();
                        dc.SetFont( m_DisplayTextFont );
                        dc.SetTextForeground(* wxWHITE );
                        if(m_natural_scale > (g_ocpn_draw_pi->m_chart_scale / 2))
                            dc.DrawText( m_TextPointText, 10, 0);
                        //else
                        //    dc.DrawText( wxT(""), 10, 0 );
                        dc.SelectObject( wxNullBitmap );
                        
                        /* make alpha texture for text */
                        wxImage image = tbm.ConvertToImage();
                        unsigned char *d = image.GetData();
                        unsigned char *e = new unsigned char[teX * teY];
                        if(d && e){
                            for( int p = 0; p < teX*teY; p++)
                                e[p] = d[3*p + 0];
                        }
                        /* create texture for rendered text */
                        glGenTextures(1, &m_iDisplayTextTexture);
                        glBindTexture(GL_TEXTURE_2D, m_iDisplayTextTexture);
                        
                        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
                        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
                        
                        m_iDisplayTextTextureWidth = NextPow2(teX);
                        m_iDisplayTextTextureHeight = NextPow2(teY);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_iDisplayTextTextureWidth, m_iDisplayTextTextureHeight,
                                    0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
                        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, teX, teY,
                                        GL_ALPHA, GL_UNSIGNED_BYTE, e);
                        delete [] e;
                    }
                    
                    if(m_iDisplayTextTexture) {
                        // Draw backing box
                        ODDC ocpndc;
                        g_ocpn_draw_pi->AlphaBlending( ocpndc, r.x, r.y, r2.width, r2.height, 6.0, m_colourTextBackgroundColour, m_iBackgroundTransparency );
                                
                        /* draw texture with text */
                        glBindTexture(GL_TEXTURE_2D, m_iDisplayTextTexture);
                        
                        glEnable(GL_TEXTURE_2D);
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                        
                        glColor3ub(m_colourTextColour.Red(), m_colourTextColour.Green(), m_colourTextColour.Blue());
                        
                        int x = r.x, y = r.y;
                        float u = (float)teX/m_iDisplayTextTextureWidth, v = (float)teY/m_iDisplayTextTextureHeight;
                        glBegin(GL_QUADS);
                        glTexCoord2f(0, 0); glVertex2f(x, y);
                        glTexCoord2f(u, 0); glVertex2f(x+teX, y);
                        glTexCoord2f(u, v); glVertex2f(x+teX, y+teY);
                        glTexCoord2f(0, v); glVertex2f(x, y+teY);
                        glEnd();
                        glDisable(GL_BLEND);
                        glDisable(GL_TEXTURE_2D);
                    }

                }
            }
        }
    }
    ODPoint::DrawGL( pivp );
}
Ejemplo n.º 23
0
unsigned int PointMan::GetIconTexture( const wxBitmap *pbm, int &glw, int &glh )
{
#ifdef ocpnUSE_GL 
    int index = GetIconIndex( pbm );
    ODMarkIcon *pmi = (ODMarkIcon *) m_pIconArray->Item( index );
    assert(pmi != 0);

    unsigned int *IconTexture;
    switch (m_ColourScheme) {
        case PI_GLOBAL_COLOR_SCHEME_RGB:
            IconTexture = &pmi->icon_texture_RGB;
            break;
        case PI_GLOBAL_COLOR_SCHEME_DAY:
            IconTexture = &pmi->icon_texture_Day;
            break;
        case PI_GLOBAL_COLOR_SCHEME_DUSK:
            IconTexture = &pmi->icon_texture_Dusk;
            break;
        case PI_GLOBAL_COLOR_SCHEME_NIGHT:
            IconTexture = &pmi->icon_texture_Night;
            break;
        default:
            IconTexture = &pmi->icon_texture_Day;
            break;
    }
    if(*IconTexture == 0) {
        /* make rgba texture */       
        glGenTextures(1, IconTexture);
        glBindTexture(GL_TEXTURE_2D, *IconTexture);
                
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

        wxImage image = pbm->ConvertToImage();
        int w = image.GetWidth(), h = image.GetHeight();
        
        pmi->tex_w = NextPow2(w);
        pmi->tex_h = NextPow2(h);
        
        unsigned char *d = image.GetData();
        unsigned char *a = image.GetAlpha();
            
        unsigned char mr, mg, mb;
        if(!a)
            image.GetOrFindMaskColour( &mr, &mg, &mb );
    
        unsigned char *e = new unsigned char[4 * w * h];
        if(d && e){
            for( int y = 0; y < h; y++ )
                for( int x = 0; x < w; x++ ) {
                    unsigned char r, g, b;
                    int off = ( y * image.GetWidth() + x );
                    r = d[off * 3 + 0];
                    g = d[off * 3 + 1];
                    b = d[off * 3 + 2];
                    
                    e[off * 4 + 0] = r;
                    e[off * 4 + 1] = g;
                    e[off * 4 + 2] = b;
                    
                    e[off * 4 + 3] =  a ? a[off] : ( ( r == mr ) && ( g == mg ) && ( b == mb ) ? 0 : 255 );
                }
        }
    
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pmi->tex_w, pmi->tex_h,
                     0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
                        GL_RGBA, GL_UNSIGNED_BYTE, e);

        delete [] e;
    }

    glw = pmi->tex_w;
    glh = pmi->tex_h;

    return *IconTexture;
#else
    return 0;
#endif
}
Ejemplo n.º 24
0
void RoutePoint::DrawGL( ViewPort &vp, bool use_cached_screen_coords )
{
    if( !m_bIsVisible )
        return;

    //    Optimization, especially apparent on tracks in normal cases
    if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return;

    if(m_wpBBox.GetValid() &&
       vp.view_scale_ppm == m_wpBBox_view_scale_ppm &&
       vp.rotation == m_wpBBox_rotation) {
        /* see if this waypoint can intersect with bounding box */
        LLBBox vpBBox = vp.GetBBox();
        if( vpBBox.IntersectOut( m_wpBBox ) ){
            
            // Are Range Rings enabled?
            if(m_bShowWaypointRangeRings && (m_iWaypointRangeRingsNumber > 0)){
                double factor = 1.00;
                if( m_iWaypointRangeRingsStepUnits == 1 )          // convert kilometers to NMi
                    factor = 1 / 1.852;
            
                double radius = factor * m_iWaypointRangeRingsNumber * m_fWaypointRangeRingsStep  / 60.;

                LLBBox radar_box = m_wpBBox;
                radar_box.EnLarge(radius * 2 );
                if( vpBBox.IntersectOut( radar_box ) ){
                    return;
                }
            }
            else
                return;
        }
    }

    wxPoint r;
    wxRect hilitebox;
    unsigned char transparency = 150;
    double platform_pen_width = wxRound(wxMax(1.0, g_Platform->GetDisplayDPmm() / 2));             // 0.5 mm nominal, but not less than 1 pixel
    
    if(use_cached_screen_coords && m_pos_on_screen)
        r.x = m_screen_pos.m_x, r.y = m_screen_pos.m_y;
    else
        cc1->GetCanvasPointPix( m_lat, m_lon, &r );

    if(r.x == INVALID_COORD)
        return;

//    Substitute icon?
    wxBitmap *pbm;
    if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) )
        pbm = pWayPointMan->GetIconBitmap(  _T ( "activepoint" ) );
    else
        pbm = m_pbmIcon;

    //  If icon is corrupt, there is really nothing else to do...
    if(!pbm->IsOk())
        return;
    
    int sx2 = pbm->GetWidth() / 2;
    int sy2 = pbm->GetHeight() / 2;

//    Calculate the mark drawing extents
    wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 );           // the bitmap extents

    wxRect r3 = r1;
    if( m_bShowName ) {
        if( !m_pMarkFont ) {
            m_pMarkFont = FontMgr::Get().GetFont( _( "Marks" ) );
            m_FontColor = FontMgr::Get().GetFontColor( _( "Marks" ) );
            CalculateNameExtents();
        }

        if( m_pMarkFont ) {
            wxRect r2( r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY,
                       m_NameExtents.x, m_NameExtents.y );
            r3.Union( r2 );
        }
    }

    hilitebox = r3;
    hilitebox.x -= r.x;
    hilitebox.y -= r.y;
    
    hilitebox.x *= g_ChartScaleFactorExp;
    hilitebox.y *= g_ChartScaleFactorExp;
    hilitebox.width  *= g_ChartScaleFactorExp;
    hilitebox.height *= g_ChartScaleFactorExp;
    
    float radius;
    if( g_btouch ){
        hilitebox.Inflate( 20 );
        radius = 20.0f;
    }
    else{
        hilitebox.Inflate( 4 );
        radius = 4.0f;
    }
    
    /* update bounding box */
    if(!m_wpBBox.GetValid() || vp.view_scale_ppm != m_wpBBox_view_scale_ppm || vp.rotation != m_wpBBox_rotation) {
        double lat1, lon1, lat2, lon2;
        cc1->GetCanvasPixPoint(r.x+hilitebox.x, r.y+hilitebox.y+hilitebox.height, lat1, lon1);
        cc1->GetCanvasPixPoint(r.x+hilitebox.x+hilitebox.width, r.y+hilitebox.y, lat2, lon2);

        if(lon1 > lon2)
            m_wpBBox.Set(lat1, lon1, lat2, lon2+360);
        else
            m_wpBBox.Set(lat1, lon1, lat2, lon2);

        m_wpBBox_view_scale_ppm = vp.view_scale_ppm;
        m_wpBBox_rotation = vp.rotation;
    }

//    if(region.Contains(r3) == wxOutRegion)
//        return;
    

    ocpnDC dc;

    //  Highlite any selected point
    if( m_bPtIsSelected ) {
        wxColour hi_colour;
        if( m_bBlink ){
            wxPen *pen = g_pRouteMan->GetActiveRoutePointPen();
            hi_colour = pen->GetColour();
        }
        else{
            hi_colour = GetGlobalColor( _T ( "YELO1" ) );
        }
        
        AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius,
                       hi_colour, transparency );
    }
    
    bool bDrawHL = false;

    if( m_bBlink && ( gFrame->nBlinkerTick & 1 ) ) bDrawHL = true;

    if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) {
        int glw, glh;
        unsigned int IconTexture = pWayPointMan->GetIconTexture( pbm, glw, glh );
        
        glBindTexture(GL_TEXTURE_2D, IconTexture);
        
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        
        glColor3f(1, 1, 1);
        
        int x = r1.x, y = r1.y, w = r1.width, h = r1.height;
        
        float scale = 1.0;
 //       if(g_bresponsive){
            scale =  g_ChartScaleFactorExp;
//        }
            
        float ws = r1.width * scale;
        float hs = r1.height * scale;
        float xs = r.x - ws/2.;
        float ys = r.y - hs/2.;
        float u = (float)w/glw, v = (float)h/glh;
        
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(xs, ys);
        glTexCoord2f(u, 0); glVertex2f(xs+ws, ys);
        glTexCoord2f(u, v); glVertex2f(xs+ws, ys+hs);
        glTexCoord2f(0, v); glVertex2f(xs, ys+hs);
        glEnd();
        
//         glBegin(GL_QUADS);
//         glTexCoord2f(0, 0); glVertex2f(x, y);
//         glTexCoord2f(u, 0); glVertex2f(x+w, y);
//         glTexCoord2f(u, v); glVertex2f(x+w, y+h);
//         glTexCoord2f(0, v); glVertex2f(x, y+h);
//         glEnd();

        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
    }

    if( m_bShowName && m_pMarkFont ) {
        int w = m_NameExtents.x, h = m_NameExtents.y;
        if(!m_iTextTexture && w && h) {
            wxBitmap tbm(w, h); /* render text on dc */
            wxMemoryDC dc;
            dc.SelectObject( tbm );               
            dc.SetBackground( wxBrush( *wxBLACK ) );
            dc.Clear();
            dc.SetFont( *m_pMarkFont );
            dc.SetTextForeground( *wxWHITE );
            dc.DrawText( m_MarkName, 0, 0);
            dc.SelectObject( wxNullBitmap );
            
            /* make alpha texture for text */
            wxImage image = tbm.ConvertToImage();
            unsigned char *d = image.GetData();
            unsigned char *e = new unsigned char[w * h];
            if(d && e){
                for( int p = 0; p < w*h; p++)
                    e[p] = d[3*p + 0];
            }
            
            /* create texture for rendered text */
            glGenTextures(1, &m_iTextTexture);
            glBindTexture(GL_TEXTURE_2D, m_iTextTexture);
            
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

            m_iTextTextureWidth = NextPow2(w);
            m_iTextTextureHeight = NextPow2(h);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_iTextTextureWidth, m_iTextTextureHeight,
                         0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
                            GL_ALPHA, GL_UNSIGNED_BYTE, e);
            delete [] e;
        }

        if(m_iTextTexture) {
            /* draw texture with text */
            glBindTexture(GL_TEXTURE_2D, m_iTextTexture);
            
            glEnable(GL_TEXTURE_2D);
            glEnable(GL_BLEND);
        
            glColor3ub(m_FontColor.Red(), m_FontColor.Green(), m_FontColor.Blue());
            
            int x = r.x + m_NameLocationOffsetX, y = r.y + m_NameLocationOffsetY;
            float u = (float)w/m_iTextTextureWidth, v = (float)h/m_iTextTextureHeight;
            glBegin(GL_QUADS);
            glTexCoord2f(0, 0); glVertex2f(x, y);
            glTexCoord2f(u, 0); glVertex2f(x+w, y);
            glTexCoord2f(u, v); glVertex2f(x+w, y+h);
            glTexCoord2f(0, v); glVertex2f(x, y+h);
            glEnd();

            glDisable(GL_BLEND);
            glDisable(GL_TEXTURE_2D);
        }
    }
    
    // Draw waypoint radar rings if activated
    if( m_iWaypointRangeRingsNumber && m_bShowWaypointRangeRings ) {
        double factor = 1.00;
        if( m_iWaypointRangeRingsStepUnits == 1 )          // nautical miles
            factor = 1 / 1.852;
        
        factor *= m_fWaypointRangeRingsStep;
        
        double tlat, tlon;
        wxPoint r1;
        ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon );
        cc1->GetCanvasPointPix( tlat, tlon, &r1 );
        
        double lpp = sqrt( pow( (double) (r.x - r1.x), 2) +
        pow( (double) (r.y - r1.y), 2 ) );
        int pix_radius = (int) lpp;
        
        wxPen ppPen1( m_wxcWaypointRangeRingsColour, platform_pen_width );
        wxBrush saveBrush = dc.GetBrush();
        wxPen savePen = dc.GetPen();
        dc.SetPen( ppPen1 );
        dc.SetBrush( wxBrush( m_wxcWaypointRangeRingsColour, wxBRUSHSTYLE_TRANSPARENT ) );
        
        for( int i = 1; i <= m_iWaypointRangeRingsNumber; i++ )
            dc.StrokeCircle( r.x, r.y, i * pix_radius );
        dc.SetPen( savePen );
        dc.SetBrush( saveBrush );
    }
    
    if( m_bBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker
    
    //    This will be useful for fast icon redraws
    CurrentRect_in_DC.x = r.x + hilitebox.x;
    CurrentRect_in_DC.y = r.y + hilitebox.y;
    CurrentRect_in_DC.width = hilitebox.width;
    CurrentRect_in_DC.height = hilitebox.height;

    if( m_bBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker
}
Ejemplo n.º 25
0
void ocpnDC::DrawText( const wxString &text, wxCoord x, wxCoord y )
{
    if( dc )
        dc->DrawText( text, x, y );
#ifdef ocpnUSE_GL
    else {
       wxCoord w = 0;
        wxCoord h = 0;

        if(m_buseTex){
        
            m_texfont.Build( m_font );      // make sure the font is ready
            m_texfont.GetTextExtent(text, &w, &h);
            
            if( w && h ) {
                
                glEnable( GL_BLEND );
                glEnable( GL_TEXTURE_2D );
                glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
                glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

                glPushMatrix();
                glTranslatef(x, y, 0);
                
                glColor3ub( m_textforegroundcolour.Red(), m_textforegroundcolour.Green(),
                            m_textforegroundcolour.Blue() );
                

                m_texfont.RenderString(text);
                glPopMatrix();

                glDisable( GL_TEXTURE_2D );
                glDisable( GL_BLEND );

            }
        }
        else{           
            wxScreenDC sdc;
            sdc.SetFont(m_font);
            sdc.GetTextExtent(text, &w, &h, NULL, NULL, &m_font);
            
            /* create bitmap of appropriate size and select it */
            wxBitmap bmp( w, h );
            wxMemoryDC temp_dc;
            temp_dc.SelectObject( bmp );

            /* fill bitmap with black */
            temp_dc.SetBackground( wxBrush( wxColour( 0, 0, 0 ) ) );
            temp_dc.Clear();

            /* draw the text white */
            temp_dc.SetFont( m_font );
            temp_dc.SetTextForeground( wxColour( 255, 255, 255 ) );
            temp_dc.DrawText( text, 0, 0 );
            temp_dc.SelectObject( wxNullBitmap );

            /* use the data in the bitmap for alpha channel,
             and set the color to text foreground */
            wxImage image = bmp.ConvertToImage();
            if( x < 0 || y < 0 ) { // Allow Drawing text which is offset to start off screen
                int dx = ( x < 0 ? -x : 0 );
                int dy = ( y < 0 ? -y : 0 );
                w = bmp.GetWidth() - dx;
                h = bmp.GetHeight() - dy;
                /* picture is out of viewport */
                if( w <= 0 || h <= 0 ) return;
                image = image.GetSubImage( wxRect( dx, dy, w, h ) );
                x += dx;
                y += dy;
            }

            unsigned char *data = new unsigned char[w * h * 4];
            unsigned char *im = image.GetData();
            
            
            if(im){
                unsigned int r = m_textforegroundcolour.Red();
                unsigned int g = m_textforegroundcolour.Green();
                unsigned int b = m_textforegroundcolour.Blue();
                for( int i = 0; i < h; i++ ){
                    for(int j=0 ; j < w ; j++){
                        unsigned int index = ((i*w) + j) * 4;
                        data[index] = r;
                        data[index+1] = g;
                        data[index+2] = b;
                        data[index+3] = im[((i*w) + j) * 3];
                    }
                }
            }
#if 0
            glColor4ub( 255, 255, 255, 255 );
            glEnable( GL_BLEND );
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            glRasterPos2i( x, y );
            glPixelZoom( 1, -1 );
            glDrawPixels( w, h, GL_RGBA, GL_UNSIGNED_BYTE, data );
            glPixelZoom( 1, 1 );
            glDisable( GL_BLEND );
#else
            unsigned int texobj;    
            
            glGenTextures(1, &texobj);
            glBindTexture(GL_TEXTURE_2D, texobj);
            
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
            
            int TextureWidth = NextPow2(w);
            int TextureHeight = NextPow2(h);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TextureWidth, TextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
            
            glEnable(GL_TEXTURE_2D);
            glEnable(GL_BLEND);
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            
            glColor3ub(0,0,0);
            
            float u = (float)w/TextureWidth, v = (float)h/TextureHeight;
            glBegin(GL_QUADS);
            glTexCoord2f(0, 0); glVertex2f(x, y);
            glTexCoord2f(u, 0); glVertex2f(x+w, y);
            glTexCoord2f(u, v); glVertex2f(x+w, y+h);
            glTexCoord2f(0, v); glVertex2f(x, y+h);
            glEnd();
            
            glDisable(GL_BLEND);
            glDisable(GL_TEXTURE_2D);
            
            glDeleteTextures(1, &texobj);
#endif            
            delete[] data;
        }            
    }
#endif    
}