光照贴图

问题:在实现镜面光贴图时,在渲染循环外按照代码1激活并绑定纹理,发现无法显示0层的纹理(即木质纹理),只能看到1层的纹理(铁框)。

代码1:

unsigned texture = genTexture(tpath);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
unsigned stexture = genTexture(spath);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, stexture);

scape_shader.setUniform1i("material.diffuse", 0);
scape_shader.setUniform1i("material.specular", 1);

效果:

希望的效果是:

开始以为是图像透明度的问题,将铁框中间的黑色部分挖空设为透明并重新保存为png,发现仍然无法显示出0层的纹理。

首先看genTexture的实现:

unsigned genTexture(const string &path) {
	unsigned char *data;
	int width, height, nrChannels;
	stbi_set_flip_vertically_on_load(true);
	data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);

	unsigned texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);

	GLenum format;

	if (nrChannels == 1) format = GL_RED;
	if (nrChannels == 3) format = GL_RGB;
	if (nrChannels == 4) format = GL_RGBA;

	//重复填充效果
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

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

	return texture;
}

其中有一句话:glBindTexture(GL_TEXTURE_2D, texture);

发现这句话前面没有写glActiveTexture(...),即这句话默认是将当前生成的texture绑定到GL_TEXTURE0上,问题就出在这。

在代码1中我是创建纹理就立即绑定他了,对于第一个木质纹理(tpath对应的纹理),在生成texture之后,就将其绑定在GL_TEXTURE0上了,而在第二个纹理(铁框纹理)产生的时候,由于当前活跃的纹理目标是GL_TEXTURE0(默认也是他),所以会将铁框纹理绑定在GL_TEXTURE0,此时原本绑定在GL_TEXTURE0上的木质纹理就失效了,所以代码1其实实现的是在GL_TEXTURE0GL_TEXTURE1上均绑定了铁框纹理,所以木质纹理自然就看不见了。

如何修改?

应该先将所有texture生成(因为生成的texture不会消失,在内存中存在,并且一个texture(unsigned整数)对应唯一一个内存区域),再挨个绑定。

unsigned texture = genTexture(tpath);
unsigned stexture = genTexture(spath);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, stexture);

scape_shader.setUniform1i("material.diffuse", 0);
scape_shader.setUniform1i("material.specular", 1);
posted @ 2021-02-15 10:51  akujyo_c  阅读(111)  评论(0编辑  收藏  举报