переменная bool ведет себя странно в фрагментном шейдере opengl - PullRequest
0 голосов
/ 03 июня 2019

Я использую OpenGL версии 4.2.Я вызываю функцию внутри другой функции в фрагментном шейдере OpenGL, где внутренняя функция (pix2loc) возвращает переменную bool в качестве аргумента функции, а затем внешняя функция (pix2ang) использует эту переменную bool для принятия решения.Точнее, у меня есть:

void pix2ang (int order_, bool is_nest, int pix, out double theta, out double phi)
{
  double z, sth;
  bool have_sth;
  pix2loc (order_, is_nest, pix, z, phi, sth, have_sth);

  if(have_sth)
    theta = atan(float(sth),float(z));
  else
    theta = acos(float(z));
}

, где функция pix2loc возвращает логическую переменную have_sth в качестве аргумента функции следующим образом:

void pix2loc (int order_, bool is_nest, int pix, out double z, out double phi, out double sth, out bool have_sth)
{
    .....
    if <condition true>
       have_sth = true;
    else
       have_sth = false;
}

Я заметил, что внутри pix2ang have_sth не работает должным образом,но если я переверну операторы if и изменит его на

if(!have_sth)
    theta = acos(float(z));
else
   theta = atan(float(sth),float(z));

, тогда он будет работать как положено.Это делает код ненадежным, и я не совсем понимаю, в чем проблема.

Хорошо.Я решил написать всю функцию pix2loc так, чтобы она могла помочь понять проблему.

void pix2loc (int order_, bool is_nest, int pix, out double z, out double phi, out double sth, out bool have_sth)
{
  int nside_  = int(1)<<order_;
  int npface_ = nside_<<order_;
  int ncap_   = (npface_-nside_)<<1;
  int npix_   = 12*npface_;
  double fact2_  = 4./npix_;
  double fact1_  = (nside_<<1)*fact2_;

  have_sth=false;

  if (!is_nest)
  {
    if (pix<ncap_) // North Polar cap
    {
      int iring = (1+int(isqrt(1+2*pix)))>>1; // counted from North pole
      int iphi  = (pix+1) - 2*iring*(iring-1);

      double tmp=(iring*iring)*fact2_;
      z = 1.0 - tmp;
      if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
      phi = (iphi-0.5) * halfpi/iring;
    }
    else if (pix<(npix_-ncap_)) // Equatorial region
    {
      int nl4 = 4*nside_;
      int ip  = pix - ncap_;
      int tmp = (order_>=0) ? ip>>(order_+2) : ip/nl4;
      int iring = tmp + nside_;
      int iphi = ip-nl4*tmp+1;
      // 1 if iring+nside is odd, 1/2 otherwise
      double fodd = bool((iring+nside_)&1) ? 1. : 0.5;

      z = (2*nside_-iring)*fact1_;
      phi = (iphi-fodd) * pi*0.75*fact1_;
    }
    else // South Polar cap
    {
      int ip = npix_ - pix;
      int iring = (1+int(isqrt(2*ip-1)))>>1; // counted from South pole
      int iphi  = 4*iring + 1 - (ip - 2*iring*(iring-1));

      double tmp=(iring*iring)*fact2_;
      z = tmp - 1.0;
      if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
      phi = (iphi-0.5) * halfpi/iring;
    }
  }
  else
  {
    int face_num, ix, iy;
    nest2xyf(order_, pix,ix,iy,face_num);

    int jr = (int(jrll[face_num])<<order_) - ix - iy - 1;

    int nr;
    if (jr<nside_)
    {
      nr = jr;
      double tmp=(nr*nr)*fact2_;
      z = 1 - tmp;
      if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
    }
    else if (jr > 3*nside_)
    {
      nr = nside_*4-jr;
      double tmp=(nr*nr)*fact2_;
      z = tmp - 1;
      if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=true; }
    }
    else
    {
      nr = nside_;
      z = (2*nside_-jr)*fact1_;
    }

    int tmp=int(jpll[face_num])*nr+ix-iy;
    if (tmp<0) tmp+=8*nr;
    phi = (nr==nside_) ? 0.75*halfpi*tmp*fact1_ : (0.5*halfpi*tmp)/nr;
  }
}

где pi, halfpi, jrll и jpll - постоянная переменная, определенная в начале фрагментного шейдера как

#version 420 core
const double pi = 3.141592653589793;
const double halfpi = 0.5 * pi;
const int jrll[] = { 2,2,2,2,3,3,3,3,4,4,4,4 };
const int jpll[] = { 1,3,5,7,0,2,4,6,1,3,5,7 };
...