1066×1600分辨率下OpenGL纹理创建访问违例问题问询
OpenGL纹理创建访问违例问题(仅1066×1600分辨率触发)
我此前在多个项目中使用stbi_load将图像数据加载到OpenGL纹理对象均成功,但当前场景下创建纹理时出现访问违例错误(Access violation reading location)。
根据经验,这类错误通常意味着OpenGL读取超出了分配的纹理内存,大概率是提供的纹理数据大小不正确。
该问题仅在分辨率为1066×1600时出现:将宽度减1或加2即可避免错误,但修改高度无任何影响,说明问题根源在宽度上。
已尝试的操作
我使用的是OpenGL 3.3,根据官方文档:
所有实现均支持至少1024 texels宽度的纹理图像。
因此1066应为合法宽度,但问题依然存在。
为排除stbi_load的问题,我尝试手动创建含虚拟数据的纹理:
Texture::Texture(const glm::ivec2& texSize, const void* optData) { m_size = texSize; glGenTextures(1, &ID); glBindTexture(GL_TEXTURE_2D, ID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_size.x, m_size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); size_t dataSize = m_size.x * m_size.y * 3; // width * height * 3 (for RGB) unsigned char* data = new unsigned char[dataSize]; memset(data, 0, dataSize); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.x, m_size.y, GL_RGB, GL_UNSIGNED_BYTE, data); delete[] data; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); if (CCJFB_Utils::CheckGLerror(__FUNCTION__)) throw std::runtime_error("Error while allocating texture memory"); }
即便使用手动分配的虚拟数据,1066×1600分辨率仍会触发错误。
唯一能避免错误的方式是将内存分配改为width × height × 4字节,而非width × height × 3——就像纹理要求每个像素额外1字节一样,但我使用的纹理格式是GL_RGB8,理论上每个像素应占用3字节而非4字节。
我的问题
- 为何1066×1600分辨率会导致访问违例?
- 为何将分配内存改为
width × height × 4可解决问题,尽管纹理格式是GL_RGB8(本应使用3字节每像素)?
环境信息
- Windows 10
- OpenGL版本:3.3.0 NVIDIA 560.94
- GPU:RTX 3060 Ti
内容的提问来源于stack exchange,提问作者CheerThe2nd
相关产品推荐
相关产品推荐

