Beispiel #1
0
	ShaderPtr Shader::createSimpleConstantShader( float r, float g, float b )
	{
		ShaderPtr shader = Shader::create().attachPS( base::path( "base" ) + "/data/glsl/constant.ps.glsl").attachVS( base::path( "base" ) + "/data/glsl/constant.vs.glsl");
		shader->setUniform( "color", math::Vec3f(r, g, b) );
		return shader;
	}
void GL::Program::initFromSource(const char * data)
{
	if (!m_Manager)
		throw std::runtime_error("resource manager is not available.");

	std::vector<std::string> lines;

	for (const char * p = data; ; )
	{
		const char * end = strchr(p, '\n');
		if (end)
		{
			size_t length = end - p;
			while (length > 0 && iswhite(p[length - 1]))
				--length;
			lines.push_back(std::string(p, length) + "\n");
			p = end + 1;
		}
		else
		{
			size_t length = strlen(p);
			while (length > 0 && iswhite(p[length - 1]))
				--length;
			lines.push_back(std::string(p, length) + "\n");
			break;
		}
	}

	std::vector<const char *> vertex;
	std::vector<const char *> fragment;

	vertex.reserve(lines.size());
	fragment.reserve(lines.size());

	bool hasVertex = false, hasFragment = 0;
	Enum type = GL::NONE;
	for (std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
	{
		if (it->c_str()[0] != '%')
		{
			vertex.push_back(type == GL::NONE || type == GL::VERTEX_SHADER ? it->c_str() : "");
			fragment.push_back(type == GL::NONE || type == GL::FRAGMENT_SHADER ? it->c_str() : "");
		}
		else
		{
			const std::string & str = *it;
			const char * file = nullptr;

			vertex.push_back("");
			fragment.push_back("");

			if (str.length() >= 7 && !memcmp(str.c_str(), "%vertex", 7))
			{
				type = GL::VERTEX_SHADER;
				file = str.c_str() + 7;
			}
			else if (str.length() >= 9 && !memcmp(str.c_str(), "%fragment", 9))
			{
				type = GL::FRAGMENT_SHADER;
				file = str.c_str() + 9;
			}
			else
			{
				std::stringstream ss;
				ss << "invalid directive '" << str << "' in the vertex program.";
				throw std::runtime_error(ss.str());
			}

			if (file)
			{
				while (iswhite(*file))
					++file;
				if (!*file)
					file = nullptr;
			}

			if (!file)
			{
				if (type == GL::VERTEX_SHADER)
					hasVertex = true;
				else if (type == GL::FRAGMENT_SHADER)
					hasFragment = true;
			}
			else
			{
				std::string filename(file);
				if (filename.length() > 0 && filename[filename.length() - 1] == '\n')
					filename.resize(filename.length() - 1);
				attachShader(m_Manager->getShader(type, filename));
			}
		}
	}

	if (hasVertex)
	{
		ShaderPtr shader = m_Manager->createShader(GL::VERTEX_SHADER);
		shader->initFromSource(vertex);
		attachShader(shader);
	}

	if (hasFragment)
	{
		ShaderPtr shader = m_Manager->createShader(GL::FRAGMENT_SHADER);
		shader->initFromSource(fragment);
		attachShader(shader);
	}

	link();
}
Beispiel #3
0
bool ShaderProgram::addShader(const ShaderPtr& shader) {
    glAttachShader(m_programId, shader->getShaderId());
    m_linked = false;
    m_shaders.push_back(shader);
    return true;
}
ShaderPtr ShaderLibrary::CreateShader (const ShaderDesc& desc, const LogFunction& error_log)
{
  try
  {
      //проверка корректности аргументов

    if (!desc.name)
      throw xtl::make_null_argument_exception ("", "desc.name");

    if (!desc.source_code)
      throw xtl::make_null_argument_exception ("", "desc.source_code");

    if (!desc.source_code_size)
      throw xtl::make_null_argument_exception ("", "desc.source_code_size");

    if (!desc.profile)
      throw xtl::make_null_argument_exception ("", "desc.profile");

    const char* options = desc.options ? desc.options : "";

    ShaderType type = (ShaderType)-1;

    struct Profile2ShaderType
    {
      const char* profile;
      ShaderType  type;
      const char* dx_profile;
    };

    static const Profile2ShaderType type_map [] = {
      {"hlsl.vs", ShaderType_Vertex,   "vs_4_0"},
      {"hlsl.ps", ShaderType_Pixel,    "ps_4_0"},
      {"hlsl.gs", ShaderType_Geometry, "gs_4_0"},
      {"hlsl.hs", ShaderType_Hull,     "hs_4_0"},
      {"hlsl.ds", ShaderType_Domain,   "ds_4_0"},
      {"hlsl.cs", ShaderType_Compute,  "cs_4_0"},
    };

    static const size_t type_map_size = sizeof (type_map) / sizeof (*type_map);

    const char* dx_profile = "";

    for (size_t i=0; i<type_map_size; i++)
      if (!strcmp (type_map [i].profile, desc.profile))
      {
        type       = type_map [i].type;
        dx_profile = type_map [i].dx_profile;
        break;
      }

    if (type == (ShaderType)-1)
      throw xtl::make_argument_exception ("", "desc.profile", desc.profile, "Unknown shader profile");

      //формирование хэша для поиска в библиотеке

    size_t source_code_size = desc.source_code_size == (size_t)-1 ? strlen (desc.source_code) : desc.source_code_size,
           hash             = common::crc32 (desc.source_code, source_code_size, common::strhash (options));

      //поиск уже существующего шейдера

    ShaderMap::iterator iter = shaders.find (hash);

    if (iter != shaders.end ())
      return iter->second;

      //создание нового шейдера

    ShaderCodePtr code (new ShaderCode (GetDeviceManager (), desc.name, dx_profile, desc.source_code, source_code_size, options, error_log), false);
    ShaderPtr     shader (new Shader (type, code, *this), false);

     //регистрация шейдера в библиотеке

    shader->RegisterDestroyHandler (xtl::bind (&ShaderLibrary::RemoveShaderByHash, this, hash), GetTrackable ());

    shaders.insert_pair (hash, shader.get ());

    return shader;    
  }
  catch (xtl::exception& e)
  {
    e.touch ("render::low_level::dx11::ShaderLibrary::CreateShader");
    throw;
  }
}
Beispiel #5
0
ShaderPtr
Shader::from_file(GLenum type, std::string const& filename,
                  std::vector<std::string> const& defines)
{
  std::ifstream in(filename);
  if (!in)
  {
    throw std::runtime_error((boost::format("%s: failed to open file") % filename).str());
  }
  else
  {
    std::vector<std::string> sources;

    // add version declaration
#ifdef HAVE_OPENGLES2
    sources.emplace_back("#version 100\n");
#else
    sources.emplace_back("#version 330 core\n");
#endif

    { // add custom defines
      std::ostringstream os;
      for(auto const& def : defines)
      {
        auto equal_pos = def.find('=');
        if (equal_pos == std::string::npos)
        {
          os << "#define " << def << '\n';
        }
        else
        {
          os << "#define " << def.substr(0, equal_pos) << ' ' << def.substr(equal_pos+1) << '\n';
        }
      }
      sources.emplace_back(os.str());
    }

    { // add the actual source file
      std::regex include_rx("^#\\s*include\\s+\"([^\"]*)\".*$");
      int line_count = 0;
      std::ostringstream os;
      std::string line;
      while(std::getline(in, line))
      {
        std::smatch rx_results;
        if (std::regex_match(line, rx_results, include_rx))
        {
          boost::filesystem::path include_filename(rx_results[1]);
          if (include_filename.is_absolute())
          {
            include_file(include_filename.string(), os);
          }
          else
          {
            include_file((boost::filesystem::path(filename).parent_path() / include_filename).string(),
                         os);
          }
          os << "#line " << line_count << '\n';
        }
        else
        {
          os << line << '\n';
        }

        line_count += 1;
      }
      sources.emplace_back(os.str());
    }

    ShaderPtr shader = std::make_shared<Shader>(type);

    shader->source(sources);
    shader->compile();

    if (!shader->get_compile_status())
    {
      throw std::runtime_error((boost::format("%s: error:\n %s") % filename % shader->get_info_log()).str());
    }

    //log_debug("%s: shader compile successful", filename);

    return shader;
  }
}
Beispiel #6
0
bool GLSprite::DrawShaped(
	const math::Vector2 &v2Pos,
	const math::Vector2 &v2Size,
	const Color& color0,
	const Color& color1,
	const Color& color2,
	const Color& color3,
	const float angle)
{
	if (v2Size == math::Vector2(0,0))
	{
		return true;
	}

	// compute flip parameters that will be sent to the VS
	math::Vector2 flipMul, flipAdd;
	GetFlipShaderParameters(flipAdd, flipMul);

	// centralizes the sprite according to the origin
	math::Vector2 v2Center = m_normalizedOrigin * v2Size;

	GLVideo* video = m_video.lock().get();
	ShaderPtr pCurrentVS = video->GetVertexShader();

	math::Matrix4x4 mRot;
	if (angle != 0.0f)
		mRot = math::RotateZ(math::DegreeToRadian(angle));
	pCurrentVS->SetMatrixConstant("rotationMatrix", mRot);

	// rounds up the final position to avoid alpha distortion
	math::Vector2 v2FinalPos;
	if (video->IsRoundingUpPosition())
	{
		v2FinalPos.x = floor(v2Pos.x);
		v2FinalPos.y = floor(v2Pos.y);
	}
	else
	{
		v2FinalPos = v2Pos;
	}

	pCurrentVS->SetConstant("size", v2Size);
	pCurrentVS->SetConstant("entityPos", v2FinalPos);
	pCurrentVS->SetConstant("center", v2Center);
	pCurrentVS->SetConstant("flipMul", flipMul);
	pCurrentVS->SetConstant("flipAdd", flipAdd);
	pCurrentVS->SetConstant("bitmapSize", GetBitmapSizeF());
	pCurrentVS->SetConstant("scroll", GetScroll());
	pCurrentVS->SetConstant("multiply", GetMultiply());

	const bool setCameraPos = pCurrentVS->ConstantExist("cameraPos");
	if (setCameraPos)
		pCurrentVS->SetConstant("cameraPos", video->GetCameraPos());

	if (m_rect.size.x == 0 || m_rect.size.y == 0)
	{
		pCurrentVS->SetConstant("rectSize", GetBitmapSizeF());
		pCurrentVS->SetConstant("rectPos", 0, 0);
	}
	else
	{
		pCurrentVS->SetConstant("rectSize", m_rect.size);
		pCurrentVS->SetConstant("rectPos", m_rect.pos);
	}

	pCurrentVS->SetConstant("color0", color0);
	pCurrentVS->SetConstant("color1", color1);
	pCurrentVS->SetConstant("color2", color2);
	pCurrentVS->SetConstant("color3", color3);

	if (pCurrentVS->ConstantExist("depth"))
		pCurrentVS->SetConstant("depth", video->GetSpriteDepth());

	// apply textures according to the rendering mode (pixel shaded or not)
	ShaderPtr pCurrentPS = video->GetPixelShader();
	SetDiffuseTexture(pCurrentPS);

	pCurrentVS->SetShader();

	// draw the one-pixel-quad applying the vertex shader
	video->GetRectRenderer().Draw(m_rectMode);

	return true;
}