我有一个加载纹理的简单函数,但问题是当我加载2个纹理时,第二个纹理与第一个纹理相同。
我认为纹理加载或渲染可能有问题吗?
纹理加载:
GLuint loadTexture(std::string path)
{
GLuint load;
glGenTextures(1, &load);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, load);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
float borderColor[] = { 1.0f, 1.0f, 1.0f, 0.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
int tw, th;
unsigned char* image = SOIL_load_image(path.c_str(), &tw, &th, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
return load;
}
渲染和其他:
头
class TexturedCube {
static GLuint vbo;
static GLuint vao;
bool spec;
GLuint texture, specular;
glm::vec3 ambient, diffuse, Lspecular,viewPos;
float shiny;
public:
TexturedCube();
void render(Shader* shader, glm::mat4* model, glm::mat4* view, glm::mat4* projection,glm::vec3 cam);
void setTexture(std::string path);
void setSpecular(std::string path);
void useSpecular(bool x);
void setAttribs(glm::vec3 amb, glm::vec3 diff, glm::vec3 specs, float shine);
};
GLuint loadTexture(std::string);
const GLfloat cubeverts[] = {
// Positions // Normals // Texture Coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
CPP
void TexturedCube::render(Shader * shader, glm::mat4 * model, glm::mat4 * view, glm::mat4 * projection, glm::vec3 cam)
{
glBindVertexArray(vao);
shader->Use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(shader->Program, "texture0"), GL_TEXTURE0);
if (spec)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specular);
glUniform1i(glGetUniformLocation(shader->Program, "texture1"), GL_TEXTURE1);
}
glUniformMatrix4fv(glGetUniformLocation(shader->Program, "model"), 1, GL_FALSE, glm::value_ptr(*model));
glUniformMatrix4fv(glGetUniformLocation(shader->Program, "view"), 1, GL_FALSE, glm::value_ptr(*view));
glUniformMatrix4fv(glGetUniformLocation(shader->Program, "projection"), 1, GL_FALSE, glm::value_ptr(*projection));
glUniform1f(glGetUniformLocation(shader->Program, "material.shininess"), shiny);
glUniform3f(glGetUniformLocation(shader->Program, "material.ambient"), ambient.r, ambient.g, ambient.b);
glUniform3f(glGetUniformLocation(shader->Program, "material.diffuse"), diffuse.r, diffuse.g, diffuse.b);
glUniform3f(glGetUniformLocation(shader->Program, "material.specular"), Lspecular.r, Lspecular.g, Lspecular.b);
glUniform3f(glGetUniformLocation(shader->Program, "viewPos"), cam.x, cam.y, cam.z);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
}
void TexturedCube::setTexture(std::string path)
{
texture = loadTexture(path);
}
void TexturedCube::setSpecular(std::string path)
{
specular = loadTexture(path);
spec = true;
}
Frag shader
#version 330 core
struct Material {
sampler2D texture0;
sampler2D texture1;
float shininess;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct PointLight {
vec3 position;
vec3 color;
};
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;
out vec4 color;
uniform vec3 viewPos;
uniform Material material;
uniform PointLight light;
void main()
{
// Ambient
vec3 ambient = material.ambient * vec3(texture(material.texture0, TexCoords));
// Diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = material.diffuse * diff * vec3(texture(material.texture0, TexCoords));
// Specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = material.specular * spec * vec3(texture(material.texture1, TexCoords));
color = vec4(ambient + diffuse + specular, 1.0f);
}
然后我只是在渲染循环中调用SetSpecular()和SetTexture()然后调用render()。
感谢您的帮助。
答案 0 :(得分:2)
问题是,你将错误的值传递给制服。你要做的是传递纹理单位索引而不是OpenGL常量。所以
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(shader->Program, "texture0"), GL_TEXTURE0);
必须更改为
glUniform1i(glGetUniformLocation(shader->Program, "texture0"), 0);
其他纹理相同:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specular);
glUniform1i(glGetUniformLocation(shader->Program, "texture1"), 1);