예제 #1
0
TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename)
{
  OSLTextureHandleMap::iterator it = textures.find(filename);

  /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
  if (it != textures.end()) {
    if (it->second->type != OSLTextureHandle::OIIO) {
      return (TextureSystem::TextureHandle *)it->second.get();
    }
  }

  /* Get handle from OpenImageIO. */
  OSL::TextureSystem *ts = texture_system;
  TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
  if (handle == NULL) {
    return NULL;
  }

  /* Insert new OSLTextureHandle if needed. */
  if (it == textures.end()) {
    textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
    it = textures.find(filename);
  }

  /* Assign OIIO texture handle and return. */
  it->second->oiio_handle = handle;
  return (TextureSystem::TextureHandle *)it->second.get();
}
예제 #2
0
bool OSLRenderServices::get_texture_info(ustring filename, int subimage,
        ustring dataname,
        TypeDesc datatype, void *data)
{
    OSL::TextureSystem *ts = kernel_globals->osl->ts;
    return ts->get_texture_info(filename, subimage, dataname, datatype, data);
}
예제 #3
0
bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
                                    OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
                                    const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
{
	OSL::TextureSystem *ts = osl_ts;
	ShaderData *sd = (ShaderData *)(sg->renderstate);
	KernelGlobals *kg = sd->osl_globals;
	OSLThreadData *tdata = kg->osl_tdata;
	OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;

	OIIO::TextureSystem::TextureHandle *th =  ts->get_texture_handle(filename, thread_info);
	bool status = ts->environment(th, thread_info,
	                              options, R, dRdx, dRdy, result);

	if(!status) {
		if(options.nchannels == 3 || options.nchannels == 4) {
			result[0] = 1.0f;
			result[1] = 0.0f;
			result[2] = 1.0f;

			if(options.nchannels == 4)
				result[3] = 1.0f;
		}
	}

	return status;
}
예제 #4
0
bool OSLRenderServices::environment(ustring filename,
                                    TextureHandle *texture_handle,
                                    TexturePerthread *thread_info,
                                    TextureOpt &options,
                                    OSL::ShaderGlobals *sg,
                                    const OSL::Vec3 &R,
                                    const OSL::Vec3 &dRdx,
                                    const OSL::Vec3 &dRdy,
                                    int nchannels,
                                    float *result,
                                    float *dresultds,
                                    float *dresultdt,
                                    ustring *errormessage)
{
  OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  OSL::TextureSystem *ts = texture_system;
  bool status = false;

  if (handle && handle->oiio_handle) {
    if (thread_info == NULL) {
      ShaderData *sd = (ShaderData *)(sg->renderstate);
      KernelGlobals *kernel_globals = sd->osl_globals;
      OSLThreadData *tdata = kernel_globals->osl_tdata;
      thread_info = tdata->oiio_thread_info;
    }

    status = ts->environment(handle->oiio_handle,
                             thread_info,
                             options,
                             R,
                             dRdx,
                             dRdy,
                             nchannels,
                             result,
                             dresultds,
                             dresultdt);
  }
  else {
    status = ts->environment(
        filename, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
  }

  if (!status) {
    if (nchannels == 3 || nchannels == 4) {
      result[0] = 1.0f;
      result[1] = 0.0f;
      result[2] = 1.0f;

      if (nchannels == 4)
        result[3] = 1.0f;
    }
  }
  else if (handle && handle->processor) {
    ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
  }

  return status;
}
예제 #5
0
bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
{
  OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;

  if (handle->oiio_handle) {
    OSL::TextureSystem *ts = texture_system;
    return ts->good(handle->oiio_handle);
  }
  else {
    return true;
  }
}
예제 #6
0
bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
                                         ustring filename,
                                         TextureHandle *texture_handle,
                                         int subimage,
                                         ustring dataname,
                                         TypeDesc datatype,
                                         void *data)
{
  OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;

  /* No texture info for other texture types. */
  if (handle && handle->type != OSLTextureHandle::OIIO) {
    return false;
  }

  /* Get texture info from OpenImageIO. */
  OSL::TextureSystem *ts = texture_system;
  return ts->get_texture_info(filename, subimage, dataname, datatype, data);
}
예제 #7
0
bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
                                    OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
                                    const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
{
    OSL::TextureSystem *ts = kernel_globals->osl->ts;
    bool status = ts->environment(filename, options, R, dRdx, dRdy, result);

    if(!status) {
        if(options.nchannels == 3 || options.nchannels == 4) {
            result[0] = 1.0f;
            result[1] = 0.0f;
            result[2] = 1.0f;

            if(options.nchannels == 4)
                result[3] = 1.0f;
        }
    }

    return status;
}
예제 #8
0
bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
                                OSL::ShaderGlobals *sg,
                                float s, float t, float dsdx, float dtdx,
                                float dsdy, float dtdy, float *result)
{
    OSL::TextureSystem *ts = kernel_globals->osl->ts;
    bool status = ts->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, result);

    if(!status) {
        if(options.nchannels == 3 || options.nchannels == 4) {
            result[0] = 1.0f;
            result[1] = 0.0f;
            result[2] = 1.0f;

            if(options.nchannels == 4)
                result[3] = 1.0f;
        }
    }

    return status;
}
예제 #9
0
bool OSLRenderServices::texture(ustring filename,
                                TextureHandle *texture_handle,
                                TexturePerthread *texture_thread_info,
                                TextureOpt &options,
                                OSL::ShaderGlobals *sg,
                                float s,
                                float t,
                                float dsdx,
                                float dtdx,
                                float dsdy,
                                float dtdy,
                                int nchannels,
                                float *result,
                                float *dresultds,
                                float *dresultdt,
                                ustring *errormessage)
{
  OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
  ShaderData *sd = (ShaderData *)(sg->renderstate);
  KernelGlobals *kernel_globals = sd->osl_globals;
  bool status = false;

  switch (texture_type) {
    case OSLTextureHandle::BEVEL: {
      /* Bevel shader hack. */
      if (nchannels >= 3) {
        PathState *state = sd->osl_path_state;
        int num_samples = (int)s;
        float radius = t;
        float3 N = svm_bevel(kernel_globals, sd, state, radius, num_samples);
        result[0] = N.x;
        result[1] = N.y;
        result[2] = N.z;
        status = true;
      }
      break;
    }
    case OSLTextureHandle::AO: {
      /* AO shader hack. */
      PathState *state = sd->osl_path_state;
      int num_samples = (int)s;
      float radius = t;
      float3 N = make_float3(dsdx, dtdx, dsdy);
      int flags = 0;
      if ((int)dtdy) {
        flags |= NODE_AO_INSIDE;
      }
      if ((int)options.sblur) {
        flags |= NODE_AO_ONLY_LOCAL;
      }
      if ((int)options.tblur) {
        flags |= NODE_AO_GLOBAL_RADIUS;
      }
      result[0] = svm_ao(kernel_globals, sd, N, state, radius, num_samples, flags);
      status = true;
      break;
    }
    case OSLTextureHandle::SVM: {
      /* Packed texture. */
      float4 rgba = kernel_tex_image_interp(kernel_globals, handle->svm_slot, s, 1.0f - t);

      result[0] = rgba[0];
      if (nchannels > 1)
        result[1] = rgba[1];
      if (nchannels > 2)
        result[2] = rgba[2];
      if (nchannels > 3)
        result[3] = rgba[3];
      status = true;
      break;
    }
    case OSLTextureHandle::IES: {
      /* IES light. */
      result[0] = kernel_ies_interp(kernel_globals, handle->svm_slot, s, t);
      status = true;
      break;
    }
    case OSLTextureHandle::OIIO: {
      /* OpenImageIO texture cache. */
      OSL::TextureSystem *ts = texture_system;

      if (handle && handle->oiio_handle) {
        if (texture_thread_info == NULL) {
          OSLThreadData *tdata = kernel_globals->osl_tdata;
          texture_thread_info = tdata->oiio_thread_info;
        }

        status = ts->texture(handle->oiio_handle,
                             texture_thread_info,
                             options,
                             s,
                             t,
                             dsdx,
                             dtdx,
                             dsdy,
                             dtdy,
                             nchannels,
                             result,
                             dresultds,
                             dresultdt);
      }
      else {
        status = ts->texture(filename,
                             options,
                             s,
                             t,
                             dsdx,
                             dtdx,
                             dsdy,
                             dtdy,
                             nchannels,
                             result,
                             dresultds,
                             dresultdt);
      }

      if (!status) {
        /* This might be slow, but prevents error messages leak and
         * other nasty stuff happening. */
        ts->geterror();
      }
      else if (handle && handle->processor) {
        ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
      }
      break;
    }
  }

  if (!status) {
    if (nchannels == 3 || nchannels == 4) {
      result[0] = 1.0f;
      result[1] = 0.0f;
      result[2] = 1.0f;

      if (nchannels == 4)
        result[3] = 1.0f;
    }
  }

  return status;
}
예제 #10
0
bool OSLRenderServices::texture3d(ustring filename,
                                  TextureHandle *texture_handle,
                                  TexturePerthread *texture_thread_info,
                                  TextureOpt &options,
                                  OSL::ShaderGlobals *sg,
                                  const OSL::Vec3 &P,
                                  const OSL::Vec3 &dPdx,
                                  const OSL::Vec3 &dPdy,
                                  const OSL::Vec3 &dPdz,
                                  int nchannels,
                                  float *result,
                                  float *dresultds,
                                  float *dresultdt,
                                  float *dresultdr,
                                  ustring *errormessage)
{
  OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
  bool status = false;

  switch (texture_type) {
    case OSLTextureHandle::SVM: {
      /* Packed texture. */
      ShaderData *sd = (ShaderData *)(sg->renderstate);
      KernelGlobals *kernel_globals = sd->osl_globals;
      int slot = handle->svm_slot;
      float4 rgba = kernel_tex_image_interp_3d(
          kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);

      result[0] = rgba[0];
      if (nchannels > 1)
        result[1] = rgba[1];
      if (nchannels > 2)
        result[2] = rgba[2];
      if (nchannels > 3)
        result[3] = rgba[3];
      status = true;
      break;
    }
    case OSLTextureHandle::OIIO: {
      /* OpenImageIO texture cache. */
      OSL::TextureSystem *ts = texture_system;

      if (handle && handle->oiio_handle) {
        if (texture_thread_info == NULL) {
          ShaderData *sd = (ShaderData *)(sg->renderstate);
          KernelGlobals *kernel_globals = sd->osl_globals;
          OSLThreadData *tdata = kernel_globals->osl_tdata;
          texture_thread_info = tdata->oiio_thread_info;
        }

        status = ts->texture3d(handle->oiio_handle,
                               texture_thread_info,
                               options,
                               P,
                               dPdx,
                               dPdy,
                               dPdz,
                               nchannels,
                               result,
                               dresultds,
                               dresultdt,
                               dresultdr);
      }
      else {
        status = ts->texture3d(filename,
                               options,
                               P,
                               dPdx,
                               dPdy,
                               dPdz,
                               nchannels,
                               result,
                               dresultds,
                               dresultdt,
                               dresultdr);
      }

      if (!status) {
        /* This might be slow, but prevents error messages leak and
         * other nasty stuff happening. */
        ts->geterror();
      }
      else if (handle && handle->processor) {
        ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
      }
      break;
    }
    case OSLTextureHandle::IES:
    case OSLTextureHandle::AO:
    case OSLTextureHandle::BEVEL: {
      status = false;
      break;
    }
  }

  if (!status) {
    if (nchannels == 3 || nchannels == 4) {
      result[0] = 1.0f;
      result[1] = 0.0f;
      result[2] = 1.0f;

      if (nchannels == 4)
        result[3] = 1.0f;
    }
  }

  return status;
}
예제 #11
0
bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
                                OSL::ShaderGlobals *sg,
                                float s, float t, float dsdx, float dtdx,
                                float dsdy, float dtdy, float *result)
{
	OSL::TextureSystem *ts = osl_ts;
	ShaderData *sd = (ShaderData *)(sg->renderstate);
	KernelGlobals *kg = sd->osl_globals;

#ifdef WITH_PTEX
	/* todo: this is just a quick hack, only works with particular files and options */
	if(string_endswith(filename.string(), ".ptx")) {
		float2 uv;
		int faceid;

		if(!primitive_ptex(kg, sd, &uv, &faceid))
			return false;

		float u = uv.x;
		float v = uv.y;
		float dudx = 0.0f;
		float dvdx = 0.0f;
		float dudy = 0.0f;
		float dvdy = 0.0f;

		Ptex::String error;
		PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error));

		if(!r) {
			//std::cerr << error.c_str() << std::endl;
			return false;
		}

		bool mipmaplerp = false;
		float sharpness = 1.0f;
		PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
		PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));

		f->eval(result, options.firstchannel, options.nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);

		for(int c = r->numChannels(); c < options.nchannels; c++)
			result[c] = result[0];

		return true;
	}
#endif

	OSLThreadData *tdata = kg->osl_tdata;
	OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;

	OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);

	bool status = ts->texture(th, thread_info,
	                          options, s, t, dsdx, dtdx, dsdy, dtdy, result);

	if(!status) {
		if(options.nchannels == 3 || options.nchannels == 4) {
			result[0] = 1.0f;
			result[1] = 0.0f;
			result[2] = 1.0f;

			if(options.nchannels == 4)
				result[3] = 1.0f;
		}
	}

	return status;
}