【问题标题】:Multiple texture mapping with openGL使用 openGL 进行多重纹理映射
【发布时间】:2016-10-13 12:28:11
【问题描述】:

我尝试在线搜索,但不明白如何为我的模型添加纹理。 (可以从一开始就设置) 我遇到了麻烦,我希望在我应该对我的代码进行的更改方面获得一些帮助。

我的纹理设置函数是:

void Texture::setTexture(unsigned char* data, unsigned int width, unsigned int height) {
  glGenTextures(1, &m_texture[unit]); // Genatate 1 texture in m_texture
  glBindTexture(GL_TEXTURE_2D, m_texture[unit]); 


  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 


  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

我的绑定函数:

void Texture::Bind(unsigned int unit) {
  glActiveTexture(GL_TEXTURE0 + unit);
  glBindTexture(GL_TEXTURE_2D, m_texture[unit]);

我的顶点着色器看起来像这样:

attribute vec3 position;    // Position values
attribute vec2 texCoord;    // Texture coordinates values
attribute vec3 normal;      // Normal

varying vec2 texCoord0; 
varying vec3 normal0;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(position, 1.0); 
    texCoord0 = texCoord; 
    normal0= (transform * vec4(normal, 0.0)).xyz; 
}

片段着色器:

varying vec2 texCoord0;
varying vec3 normal0;

uniform sampler2D diffuse;

void main()
{
    gl_FragColor =  texture2D(diffuse, texCoord0) *
                    clamp(dot(-vec3(0,0,1), normal0), 1.0, 1.0);
}

着色器:

Shader::Shader(const string& fileName)
{
    m_program = glCreateProgram();
    m_shaders[0] = CreateShader(LoadShader(fileName + ".vs"), GL_VERTEX_SHADER); 
    m_shaders[1] = CreateShader(LoadShader(fileName + ".fs"), GL_FRAGMENT_SHADER);

    for (unsigned int i = 0; i < NUM_SHADERS; i++)
        glAttachShader(m_program, m_shaders[i]);

    glBindAttribLocation(m_program, 0, "position"); 
    glBindAttribLocation(m_program, 1, "texCoord"); 
    glBindAttribLocation(m_program, 2, "normal");

    glLinkProgram(m_program);

    glValidateProgram(m_program);

    m_uniforms[TRANSFORM_U] = glGetUniformLocation(m_program, "transform");
}

我想选择一些顶点来使用第一个纹理和另一个。例如,一个立方体,每个正方形都有不同的纹理。

如何添加另一个纹理?我应该对我的 Mesh 类进行哪些更改?

抱歉这个愚蠢的问题,我是 openGL 的新手 :) 提前致谢!

【问题讨论】:

  • 简而言之,您需要使用多个纹理单元,每个单元然后映射到片段着色器中的 sampler2D。一些优秀的信息可以找到here

标签: c++ opengl texture-mapping


【解决方案1】:

不知道这是不是你要找的。但是,我走了..

在片段着色器中,您将使用多个sampler2D,例如:

uniform sampler2D tex0;
uniform sampler2D tex1;

您还需要对 c++ 代码进行一些调整,像这样分配sampler2D

glUniform1i(glGetUniformLocation(shader, "tex0"), 0);
glUniform1i(glGetUniformLocation(shader, "tex1"), 1);

01 是来自 GL_TEXTURE0GL_TEXTURE1 的活动纹理编号。如果是GL_TEXTUREN,则为 N。话虽如此,您应该先将这些纹理与glActiveTexture 绑定,如下所示:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex1);

我相信你已经这样做了。


哦,也许你也可以像这样在片段着色器中使用数组:

uniform sampler2D tex[2];

而 c++ 代码会是这样的:

for (int i = 0; i < 2; i++) {
    glUniform1i(glGetUniformLocation(shader, "tex[" + std::to_string(i) + "]"), i);
}

编辑:我没有测试"tex[" + std::to_string(i) + "]" 是否有效。但我想你明白了。 可能是("tex[" + std::to_string(i) + "]").c_str()

编辑:说到数组,还有一种叫做纹理数组的东西。有关详细信息和更多选项,请考虑查看this

【讨论】:

  • 谢谢!如何选择一些顶点来使用第一个纹理和另一个?例如,一个立方体,每个正方形都有不同的纹理。
  • @Yuval.Sightec 我还没有尝试过。但如果是我,我会为每个顶点分配一个额外的属性来确定应该使用哪个纹理来简单起见。但简单并不总是一个好方法。更简单的方法是使用纹理图集(如果纹理不是那么大)。
猜你喜欢
  • 2014-10-22
  • 1970-01-01
  • 2011-05-04
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2012-07-28
  • 2011-05-16
相关资源
最近更新 更多