纹理绑定不起作用 / C++ / OpenGL
Texture binding isn't working / C++ / OpenGL
我正试图为我的项目创建一个纹理类,该类初始化并加载图像中的纹理。纹理加载良好,但每当我想通过调用GetTexture()函数从类外获取纹理ID时,glIsTexture(()不再将返回值(纹理ID)视为纹理。而我想要纹理化的脸保持空白。
此外,我尝试使用函数texture::SetActive()直接从texture类本身使用glBindTexture()绑定纹理,但仍然不起作用。
最后,当我直接从函数返回纹理ID时,纹理会正确显示。
我这里缺什么了吗?我真的不知道在这一点上该找什么。
提前感谢您的帮助!
这是我的纹理类:
// Constructor
Texture::Texture(std::string const& texPath) {
SDL_Surface *texture = nullptr, *newFormatTexture = nullptr, *flippedTexture = nullptr;
SDL_PixelFormat tmpFormat;
Uint32 amask, rmask, gmask, bmask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xFF000000;
gmask = 0x00FF0000;
bmask = 0x0000FF00;
amask = 0x000000FF;
#else
rmask = 0x000000FF;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
amask = 0xFF000000;
#endif
if ((texture = IMG_Load(texPath.c_str())) == nullptr) {
std::cerr << "[ERROR] : Could not load texture " << texPath << ". Skipping..." << std::endl;
}
tmpFormat = *(texture->format);
tmpFormat.BitsPerPixel = 32;
tmpFormat.BytesPerPixel = 4;
tmpFormat.Rmask = rmask;
tmpFormat.Gmask = gmask;
tmpFormat.Bmask = bmask;
tmpFormat.Amask = amask;
if ((newFormatTexture = SDL_ConvertSurface(texture, &tmpFormat, SDL_SWSURFACE)) == nullptr) {
std::cerr << "[ERROR] : Couldn't convert surface to given format." << std::endl;
}
if ((flippedTexture = this->FlipSurface(newFormatTexture)) == nullptr) {
std::cerr << "[ERROR] : Couldn't flip surface." << std::endl;
}
glGenTextures(1, &(this->_textureID));
glBindTexture(GL_TEXTURE_2D, this->_textureID);
glTexImage2D(GL_TEXTURE_2D, 0, 4, flippedTexture->w, flippedTexture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, flippedTexture->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
SDL_FreeSurface(flippedTexture);
SDL_FreeSurface(newFormatTexture);
SDL_FreeSurface(texture);
}
Texture::Texture(unsigned char *texData, int width, int height) {
glGenTextures(1, &(this->_textureID));
glBindTexture(GL_TEXTURE_2D, this->_textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, texData);
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::~Texture() {
glDeleteTextures(1, &(this->_textureID));
}
Texture Texture::CreateTexture(std::string const& texPath) {
Texture tex(texPath);
return (tex);
}
Texture Texture::CreateTexture(unsigned char *texData, int width, int height) {
Texture tex(texData, width, height);
return (tex);
}
unsigned int Texture::GetTexture() const {
return (this->_textureID);
}
void Texture::SetActive() {
glBindTexture(GL_TEXTURE_2D, this->_textureID);
}
我加载和使用纹理的主要类:
int WinMain(void) {
Window window("Hello", 640, 480);
double angleX, angleZ;
Texture tex;
int height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, (double)640/480, 1, 1000);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
tex = Texture::CreateTexture("caisse.jpg");
while (!window.Quit()) {
Input::Update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(3,4,2,0,0,0,0,0,1);
tex.SetActive();
glBegin(GL_QUADS);
glTexCoord2d(0, 1);
glVertex3d(1, 1, 1);
glTexCoord2d(0, 0);
glVertex3d(1, 1, -1);
glTexCoord2d(1, 0);
glVertex3d(-1, 1, -1);
glTexCoord2d(1, 1);
glVertex3d(-1, 1, 1);
glEnd();
glFlush();
window.RefreshDisplay();
}
return (0);
}
编辑
我解决了我的问题。如本主题所述:OpenGL纹理未显示的常见故障排除步骤是什么,纹理的初始化不能在构造函数中完成。
感谢您的帮助:)
好的,让我们看看这个:
Texture Texture::CreateTexture(std::string const& texPath) {
Texture tex(texPath);
return (tex);
}
我假设这是一个静态函数。因此,它在堆栈上创建了一个Texture
对象。并且CCD_ 2包含OpenGL纹理对象。然后函数返回这个对象。
根据C++的规则,tex
的生存期被限制在创建它的范围内。即Texture::CreateTexture
。这意味着,在该函数结束时,tex
将通过调用其析构函数而被销毁。
但由于返回了tex
,在此之前,tex
将用于初始化函数的返回值。该返回值恰好是Texture
类型的对象,因此编译器将调用Texture
的复制构造函数来初始化返回值。
因此,就在tex
被销毁之前,有两个Texture
对象:tex
本身和从tex
复制的类型为Texture
的返回值。到目前为止,一切都很好。
现在,tex
被摧毁。Texture::~Texture
对包含在其中的纹理对象调用glDestroyTexture
。这会破坏在构造函数中创建的纹理。好的
所以。。。现在发生了什么?好吧,让我们回到CreateTexture
返回值的创建。我说它将调用Texture
的复制构造函数来构造它,并将tex
0作为要复制的对象。
您没有发布完整的代码,但考虑到您编写的其他代码的性质,我敢打赌您没有为Texture
编写复制构造函数。这很好,因为编译器会为您制作一个。
只是那不好。为什么?因为就在tex
被销毁之前,有两个Texture
对象。并且两者存储相同的OpenGL纹理对象名称。这是怎么发生的?
因为您将纹理对象从tex
复制到了返回值中。编译器生成的复制构造函数就是这样做的:它复制类中的所有内容。
因此,当tex
被破坏时,它正在破坏它刚刚返回的OpenGL纹理。
Texture
不应该是可复制的类。它应该是只移动的,就像C++中的许多包含资源的类一样。
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 了解 GLM- openGL 中的相机转换
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- OpenGL大的3D纹理(>2GB)非常慢
- OpenGl glm rotate
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- OpenGL在启用深度测试时不会丢弃我的碎片
- OpenGL相机和相机空间转型的困惑
- OpenGL将纹理四边形渲染为(0,0)
- OpenGL 和 GLM 矩阵无法正确扩展,总是按比例缩小
- 发布旋转矩阵(openGL/glm)
- 如何在Visual Basic中使用矩形函数OpenGL绘制矩形
- 无法使用VAO和EBO(openGL)绘制多个对象
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- OpenGL 16 位模板缓冲区?
- 将QOpenGLWidget子类转换为使用Metal而不是OpenGL的子类是否可行?
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 在 openGL 中多次绑定缓冲区
- opengl glBegin(GL_LINES) 和 glBegin(GL_POINT) 在 2D 中不可视化点矢量