bool ShaderProgram::setTextureSampler(const std::string& name,
                                      const Texture2D& texture)
{
  // Look up sampler location:
  GLint location = static_cast<GLint>(findUniform(name));
  if (location == -1) {
    m_error = "Could not set sampler " + name + ". No uniform with that name.";
    return false;
  }

  // Check if the texture is already bound:
  GLint textureUnitId = 0;
  typedef std::map<const Texture2D*, int>::const_iterator TMapIter;
  TMapIter result = m_textureUnitBindings.find(&texture);
  if (result == m_textureUnitBindings.end()) {
    // Not bound. Attempt to bind the texture to an available texture unit.
    // We'll leave GL_TEXTURE0 unbound, as it is used for manipulating
    // textures.
    std::vector<bool>::iterator begin = m_boundTextureUnits.begin() + 1;
    std::vector<bool>::iterator end = m_boundTextureUnits.end();
    std::vector<bool>::iterator available = std::find(begin, end, false);

    if (available == end) {
      m_error = "Could not set sampler " + name + ". No remaining texture "
                                                  "units available.";
      return false;
    }

    textureUnitId = static_cast<GLint>(available - begin);

    GLenum textureUnit = lookupTextureUnit(textureUnitId);
    if (textureUnit == 0) {
      m_error =
        "Could not set sampler " + name + ". Texture unit lookup failed.";
      return false;
    }

    glActiveTexture(textureUnit);
    if (!texture.bind()) {
      m_error = "Could not set sampler " + name + ": Error while binding "
                                                  "texture: '" +
                texture.error() + "'.";
      glActiveTexture(GL_TEXTURE0);
      return false;
    }
    glActiveTexture(GL_TEXTURE0);

    // Mark texture unit as in-use.
    m_textureUnitBindings.insert(std::make_pair(&texture, textureUnitId));
    *available = true;
  } else {
    // Texture is already bound.
    textureUnitId = result->second;
  }

  // Set the texture unit uniform
  glUniform1i(location, textureUnitId);

  return true;
}
bool ShaderProgram::setUniformValue(const std::string& name, const Vector2i& v)
{
  GLint location = static_cast<GLint>(findUniform(name));
  if (location == -1) {
    m_error = "Could not set uniform " + name + ". No such uniform.";
    return false;
  }
  glUniform2iv(location, 1, v.data());
  return true;
}
Exemple #3
0
void Shader::setUniform(const string &name, float* val)
{
	unsigned int pos = findUniform(name, 0, Uniforms.size());

	if (pos >= Uniforms.size())
		return;

	if (Uniforms[pos] == name)
		Uniforms[pos].set(val);
}
bool ShaderProgram::setUniformValue(const std::string& name, float f)
{
  GLint location = static_cast<GLint>(findUniform(name));
  if (location == -1) {
    m_error = "Could not set uniform " + name + ". No such uniform.";
    return false;
  }
  glUniform1f(location, static_cast<GLfloat>(f));
  return true;
}
bool ShaderProgram::setUniformValue(const std::string& name, const Vector3ub& v)
{
  GLint location = static_cast<GLint>(findUniform(name));
  if (location == -1) {
    m_error = "Could not set uniform " + name + ". No such uniform.";
    return false;
  }
  Vector3f colorf(v.cast<float>() * (1.0f / 255.0f));
  glUniform3fv(location, 1, colorf.data());
  return true;
}
void opengl::ShaderUniforms::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val)
{
	Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");

	size_t uniform_index = findUniform(name);
	bool resident = false;

	if (uniform_index != (size_t)-1) {
		Assert((size_t)uniform_index < _uniforms.size());

		uniform_bind *bind_info = &_uniforms[uniform_index];

		if (bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count) {
			bool equal = true;

			// if the values are close enough, pass.
			for (int i = 0; i < count; ++i) {
				if (!vm_matrix_equal(val[i], _uniform_data_matrix4[bind_info->index + i])) {
					equal = false;
					break;
				}
			}

			if (equal) {
				return;
			}

			resident = true;
			for (int i = 0; i < count; ++i) {
				_uniform_data_matrix4[bind_info->index + i] = val[i];
			}
		}
	}

	if (!resident) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		for (int i = 0; i < count; ++i) {
			_uniform_data_matrix4.push_back(val[i]);
		}

		uniform_bind new_bind;
		new_bind.count = count;
		new_bind.index = _uniform_data_matrix4.size() - count;
		//	new_bind.index = num_matrix_uniforms - count;
		new_bind.type = uniform_bind::MATRIX4;
		new_bind.name = name;

		_uniforms.push_back(new_bind);

		_uniform_lookup[name] = _uniforms.size() - 1;
	}

	glUniformMatrix4fv(findUniformLocation(name.c_str()), count, GL_FALSE, (const GLfloat*)val);
}
bool ShaderProgram::setUniformValue(const std::string& name,
                                    const Eigen::Matrix4f& matrix)
{
  GLint location = static_cast<GLint>(findUniform(name));
  if (location == -1) {
    m_error = "Could not set uniform " + name + ". No such uniform.";
    return false;
  }
  glUniformMatrix4fv(location, 1, GL_FALSE,
                     static_cast<const GLfloat*>(matrix.data()));
  return true;
}
void opengl_uniform_state::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val)
{
	size_t uniform_index = findUniform(name);
	bool resident = false;

	if ( uniform_index != (size_t)-1) {
		Assert( (size_t)uniform_index < uniforms.size() );

		uniform_bind *bind_info = &uniforms[uniform_index];

		if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count ) {
			bool equal = true;

			// if the values are close enough, pass.
			for ( int i = 0; i < count; ++i ) {
				if ( !vm_matrix_equal(val[i], uniform_data_matrix4[bind_info->index+i]) ) {
					equal = false;
					break;
				}
			}

			if ( equal ) {
				return;
			}

			resident = true;
			for ( int i = 0; i < count; ++i ) {
				uniform_data_matrix4[bind_info->index+i] = val[i];
			}
		}
	}

	if ( !resident ) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		for ( int i = 0; i < count; ++i ) {
			uniform_data_matrix4.push_back(val[i]);
		}

		uniform_bind new_bind;
		new_bind.count = count;
		new_bind.index = uniform_data_matrix4.size() - count;
		//	new_bind.index = num_matrix_uniforms - count;
		new_bind.type = uniform_bind::MATRIX4;
		new_bind.name = name;

		uniforms.push_back(new_bind);

		uniform_lookup[name] = uniforms.size()-1;
	}

	glUniformMatrix4fv(opengl_shader_get_uniform(name.c_str()), count, GL_FALSE, (const GLfloat*)val);
}
Exemple #9
0
void Shader::updateVec3Array(const char* name, const vec3* arr, int size)
{
  GLint x = findUniform(name);
  if (x != -1)
  {
    float* floats = new float[3*size];
    for (int i = 0; i < size; i++)
    {
      floats[i*3] = arr[i].x; floats[i*3+1] = arr[i].y; floats[i*3+2] = arr[i].z;
    }
    glUniform3fv(x, size, floats);
  }
}
Exemple #10
0
float* Shader::getUniformMemPos(string name)
{
	unsigned int pos = findUniform(name, 0, Uniforms.size());

	if (pos >= Uniforms.size())
		return nullptr;

	if (Uniforms[pos] == name)
	{
		Uniforms[pos].enable();
		return Uniforms[pos].getPtr();
	}
	return nullptr;
}
Exemple #11
0
int Shader::findUniform(const Uniform& u, int min, int max)
{
	if (min > max) {
		return min;
	}
	else if (Uniforms.size() == 0)
		return 0;
	else {
		unsigned int mid = (min + max) / 2;
		if (mid >= Uniforms.size())
			return Uniforms.size();

		if (Uniforms[mid] == u) {
			return mid;
		}
		else if (Uniforms[mid] < u) {
			return findUniform(u, mid + 1, max);
		}
		else {
			return findUniform(u, min, mid - 1);
		}
	}
}
Exemple #12
0
int Shader::findUniform(const string& name, int min, int max)
{
	if (min > max) {
		return min;
	}
	else if (Uniforms.size() == 0)
		return 0;
	else {
		unsigned int mid = (min + max) / 2;
		if (mid >= Uniforms.size())
			return Uniforms.size();

		if (Uniforms[mid] == name) {
			return mid;
		}
		else if (Uniforms[mid] < name) {
			return findUniform( name, mid + 1, max);
		}
		else {
			return findUniform( name, min, mid - 1);
		}
	}
}
Exemple #13
0
	PushUniformSPtr ShaderObject::createUniform( UniformType type
		, String const & name
		, int nbOccurences )
	{
		PushUniformSPtr result = findUniform( type, name );

		if ( !result )
		{
			result = doCreateUniform( type, nbOccurences );
			result->getBaseUniform().setName( name );
			doAddUniform( result );
		}

		return result;
	}
void opengl::ShaderUniforms::setUniformMatrix4f(const SCP_string &name, const matrix4 &val)
{
	Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");

	size_t uniform_index = findUniform(name);
	bool resident = false;

	if (uniform_index != (size_t)-1) {
		Assert((size_t)uniform_index < _uniforms.size());

		uniform_bind *bind_info = &_uniforms[uniform_index];

		if (bind_info->type == uniform_bind::MATRIX4 && bind_info->count == 1) {
			if (vm_matrix_equal(_uniform_data_matrix4[bind_info->index], val)) {
				return;
			}

			_uniform_data_matrix4[bind_info->index] = val;
			resident = true;
		}
	}

	if (!resident) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		//matrix_uniform_data[num_matrix_uniforms] = val;
		//memcpy(&(matrix_uniform_data[num_matrix_uniforms]), &val, sizeof(matrix4));
		_uniform_data_matrix4.push_back(val);
		//	num_matrix_uniforms += 1;

		uniform_bind new_bind;
		new_bind.count = 1;
		new_bind.index = _uniform_data_matrix4.size() - 1;
		//	new_bind.index = num_matrix_uniforms - 1;
		new_bind.type = uniform_bind::MATRIX4;
		new_bind.name = name;

		_uniforms.push_back(new_bind);

		_uniform_lookup[name] = _uniforms.size() - 1;
	}

	glUniformMatrix4fv(findUniformLocation(name.c_str()), 1, GL_FALSE, (const GLfloat*)&val);
}
void opengl_uniform_state::setUniformMatrix4f(const SCP_string &name, const matrix4 &val)
{
	size_t uniform_index = findUniform(name);
	bool resident = false;

	if ( uniform_index != (size_t)-1) {
		Assert( (size_t)uniform_index < uniforms.size() );

		uniform_bind *bind_info = &uniforms[uniform_index];

		if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == 1 ) {
			if ( vm_matrix_equal(uniform_data_matrix4[bind_info->index], val) ) {
				return;
			}

			uniform_data_matrix4[bind_info->index] = val;
			resident = true;
		}
	}

	if ( !resident ) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		//matrix_uniform_data[num_matrix_uniforms] = val;
		//memcpy(&(matrix_uniform_data[num_matrix_uniforms]), &val, sizeof(matrix4));
		uniform_data_matrix4.push_back(val);
		//	num_matrix_uniforms += 1;

		uniform_bind new_bind;
		new_bind.count = 1;
		new_bind.index = uniform_data_matrix4.size() - 1;
		//	new_bind.index = num_matrix_uniforms - 1;
		new_bind.type = uniform_bind::MATRIX4;
		new_bind.name = name;

		uniforms.push_back(new_bind);

		uniform_lookup[name] = uniforms.size()-1;
	}

	glUniformMatrix4fv(opengl_shader_get_uniform(name.c_str()), 1, GL_FALSE, (const GLfloat*)&val);
}
void opengl::ShaderUniforms::setUniform4f(const SCP_string &name, const vec4 &val)
{
	Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");

	size_t uniform_index = findUniform(name);
	bool resident = false;

	if (uniform_index != (size_t)-1) {
		Assert((size_t)uniform_index < _uniforms.size());

		uniform_bind *bind_info = &_uniforms[uniform_index];

		if (bind_info->type == uniform_bind::VEC4) {
			if (vm_vec_equal(_uniform_data_vec4[bind_info->index], val)) {
				// if the values are close enough, pass.
				return;
			}

			_uniform_data_vec4[bind_info->index] = val;
			resident = true;
		}
	}

	if (!resident) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		_uniform_data_vec4.push_back(val);

		uniform_bind new_bind;

		new_bind.count = 1;
		new_bind.index = _uniform_data_vec4.size() - 1;
		new_bind.type = uniform_bind::VEC4;
		new_bind.name = name;

		_uniforms.push_back(new_bind);

		_uniform_lookup[name] = _uniforms.size() - 1;
	}

	glUniform4f(findUniformLocation(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]);
}
void opengl::ShaderUniforms::setUniformi(const SCP_string &name, const int val)
{
	Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!");

	size_t uniform_index = findUniform(name);
	bool resident = false;

	if (uniform_index != (size_t)-1) {
		Assert(uniform_index < _uniforms.size());

		uniform_bind *bind_info = &_uniforms[uniform_index];

		if (bind_info->type == uniform_bind::INT) {
			if (_uniform_data_ints[bind_info->index] == val) {
				return;
			}

			_uniform_data_ints[bind_info->index] = val;
			resident = true;
		}
	}

	if (!resident) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		_uniform_data_ints.push_back(val);

		uniform_bind new_bind;

		new_bind.count = 1;
		new_bind.index = _uniform_data_ints.size() - 1;
		new_bind.type = uniform_bind::INT;
		new_bind.name = name;

		_uniforms.push_back(new_bind);

		_uniform_lookup[name] = _uniforms.size() - 1;
	}

	glUniform1i(findUniformLocation(name.c_str()), val);
}
void opengl_uniform_state::setUniform4f(const SCP_string &name, const vec4 &val)
{
	size_t uniform_index = findUniform(name);
	bool resident = false;

	if (uniform_index != (size_t)-1) {
		Assert( (size_t)uniform_index < uniforms.size() );

		uniform_bind *bind_info = &uniforms[uniform_index];

		if ( bind_info->type == uniform_bind::VEC4 ) {
			if ( vm_vec_equal(uniform_data_vec4[bind_info->index], val) ) {
				// if the values are close enough, pass.
				return;
			}

			uniform_data_vec4[bind_info->index] = val;
			resident = true;
		}
	} 

	if ( !resident ) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		uniform_data_vec4.push_back(val);

		uniform_bind new_bind;

		new_bind.count = 1;
		new_bind.index = uniform_data_vec4.size() - 1;
		new_bind.type = uniform_bind::VEC4;
		new_bind.name = name;

		uniforms.push_back(new_bind);

		uniform_lookup[name] = uniforms.size()-1;
	}

	glUniform4f(opengl_shader_get_uniform(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]);
}
void opengl_uniform_state::setUniformf(const SCP_string &name, const float val)
{
	size_t uniform_index = findUniform(name);
	bool resident = false;

	if ( uniform_index != (size_t) -1) {
		Assert( (size_t)uniform_index < uniforms.size() );

		uniform_bind *bind_info = &uniforms[uniform_index];

		if ( bind_info->type == uniform_bind::FLOAT ) {
			if ( fl_equal(uniform_data_floats[bind_info->index], val) ) {
				return;
			}

			uniform_data_floats[bind_info->index] = val;
			resident = true;
		}
	} 

	if ( !resident ) {
		// uniform doesn't exist in our previous uniform block so queue this new value
		uniform_data_floats.push_back(val);

		uniform_bind new_bind;

		new_bind.count = 1;
		new_bind.index = uniform_data_floats.size() - 1;
		new_bind.type = uniform_bind::FLOAT;
		new_bind.name = name;

		uniforms.push_back(new_bind);

		uniform_lookup[name] = uniforms.size()-1;
	}

	glUniform1f(opengl_shader_get_uniform(name.c_str()), val);
}
Exemple #20
0
void Shader::updateMat4(const char* name, mat4 v)
{
  GLint x = findUniform(name);
  if (x != -1) glUniformMatrix4fv(x, 1, GL_FALSE, value_ptr(v));
}
Exemple #21
0
void Shader::updateInt(const char* name, int v)
{
  GLint x = findUniform(name);
  if (x != -1) glUniform1i(x,v);
}
Exemple #22
0
void Shader::updateVec4(const char* name, vec4 v)
{
  GLint x = findUniform(name);
  if (x != -1) glUniform4fv(x, 1, value_ptr(v));
}
Exemple #23
0
 virtual void postLink() { uTEX = uniforms.add(findUniform("tex"), 0); }
Exemple #24
0
void Shader::build()
{
	if (Code.size() == reqArr.size())
	{
		for (size_t i = 0; i < Code.size(); i++)
		{
			Code[i] = *((ShaderCode*)reqArr[i].get());
			Code[i].makeShader();
			vector<Uniform>& t = Code[i].getUniforms();
			for (Uniform& temp : t)
				Uniforms.insert(Uniforms.begin() + findUniform(temp.getName(), 0, Uniforms.size()), temp);
		}
	}

	if (!program.get() || !glIsProgram(*program))
		*program = glCreateProgram(); //no Program existent creating

	int attached = 0;
	glGetProgramiv(*program, GL_ATTACHED_SHADERS, &attached);
	if (attached) //in case old Shaders are attached
	{
		vector<GLuint> shaders = vector<GLuint>();
		for (char i = 0; i < 16; i++) //write invaid numbers to seperate them
			shaders.push_back(-1);
		glGetAttachedShaders(*program, 16, NULL, &shaders[0]); //get all Shaders attached to Program
		for (GLuint shader : shaders)
			if (shader != -1) //check if it is a valid shader
				glDetachShader(*program, shader); //detaches Shader, DOES NO DELETE
		attached = 0; //resets counter
	}

	for (ShaderCode& shader : Code)
	{
		//should check Shader values
		glAttachShader(*program, shader.getPos());
		int ShaderCount = 0;
		glGetProgramiv( *program, GL_ATTACHED_SHADERS, &ShaderCount); //might turn out t be slow since it querries operations and wait for them
		if (ShaderCount > attached) //used for Error catching
			attached++;
	}

	if (attached > 0)
		glLinkProgram(*program);
	else
		LOG << "OpenGL Program " << "NO SHADERS ATTACHED." << "\n";

	int isLinked = 0;
	glGetProgramiv(*program, GL_LINK_STATUS, &isLinked);
	if (!isLinked)
	{
		GLint maxLength = 0;
		glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &maxLength);

		if (maxLength > 1)
		{
			//The maxLength includes the NULL character
			vector<GLchar> infoLog = vector<GLchar>(maxLength);
			glGetProgramInfoLog(*program, maxLength, NULL, &infoLog[0]);
			LOG << "OpenGL Program " << infoLog.data() << "\n";
		}
	}

	//Uniform Phase
	setUniforms();
}
Exemple #25
0
void Shader::updateFloat(const char* name, float v)
{
  GLint x = findUniform(name);
  if (x != -1) glUniform1f(x, v);
}