C++ OpenGL在调整缓冲区大小时失败
我需要每帧更新屏幕上的像素阵列。它最初可以工作,但是当我尝试调整屏幕大小时,它会出现小故障,并最终抛出C++ OpenGL在调整缓冲区大小时失败,c++,c,opengl,exc-bad-access,C++,C,Opengl,Exc Bad Access,我需要每帧更新屏幕上的像素阵列。它最初可以工作,但是当我尝试调整屏幕大小时,它会出现小故障,并最终抛出EXC_BAD_ACCESS 1。我已经检查了在每一帧之前缓冲区是否分配到了正确的大小,但是它似乎不会影响结果 #include <stdio.h> #include <stdlib.h> #include <GLUT/GLUT.h> unsigned char *buffer = NULL; int width = 400, height = 400; u
EXC_BAD_ACCESS 1
。我已经检查了在每一帧之前缓冲区是否分配到了正确的大小,但是它似乎不会影响结果
#include <stdio.h>
#include <stdlib.h>
#include <GLUT/GLUT.h>
unsigned char *buffer = NULL;
int width = 400, height = 400;
unsigned int screenTexture;
void Display()
{
for (int y = 0; y < height; y+=4) {
for (int x = 0; x < width; x++) {
buffer[(x + y * width) * 3] = 255;
}
}
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// This function results in EXC_BAD_ACCESS 1, although the buffer is always correctly allocated
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glBegin (GL_QUADS);
glTexCoord2f(0,0); glVertex2i(0, 0);
glTexCoord2f(1,0); glVertex2i(width,0);
glTexCoord2f(1,1); glVertex2i(width,height);
glTexCoord2f(0,1); glVertex2i(0, height);
glEnd ();
glFlush();
glutPostRedisplay();
}
void Resize(int w, int h)
{
width = w;
height = h;
buffer = (unsigned char *)realloc(buffer, sizeof(unsigned char) * width * height * 3);
if (!buffer) {
printf("Error Reallocating buffer\n");
exit(1);
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(width, height);
glutCreateWindow("Rasterizer");
glutDisplayFunc(Display);
glutReshapeFunc(Resize);
glGenTextures(1, &screenTexture);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glDisable(GL_DEPTH_TEST);
buffer = (unsigned char *)malloc(sizeof(unsigned char) * width * height * 3);
glutMainLoop();
}
#包括
#包括
#包括
无符号字符*缓冲区=NULL;
内部宽度=400,高度=400;
无符号整数屏幕纹理;
无效显示()
{
对于(int y=0;y
调整大小后,屏幕也无法正确显示:
是什么导致了这个问题?代码编译并运行,您只需链接GLUT和OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
^^^^^^
GL\u解包对齐
默认为4
,而不是1
。因此OpenGL将为每个像素读取4个字节,而不是您假设的3个字节
使用
glPixelStorei()
将GL\u UNPACK\u对齐设置为1
,正如@genpfault提到的,OpenGL每像素读取4个字节,而不是假设的3个字节
您也可以通过一个简单的结构将代码更改为每像素4字节的正确假设,而不是更改GL\u UNPACK\u对齐方式
:
struct pixel {
unsigned char r, g, b;
unsigned char unused;
};
然后,您可以使用更清晰的sizeof(struct pixel)
,而不是使用魔常数3。这使得阅读和传达代码的意图更加容易,并且不会产生任何额外的代码(因为结构“有效地”是一个4字节的数组)。听起来您找到了一些有效的方法,但我认为问题没有得到正确的诊断。我认为最大的问题是在这里初始化纹理数据的方式:
for (int y = 0; y < height; y+=4) {
for (int x = 0; x < width; x++) {
buffer[(x + y * width) * 3] = 255;
}
}
您还需要将GL\u UNPACK\u校准设置为1:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
这将控制行对齐(而不是像素对齐,如其他几个答案中所建议的)。GL\u UNPACK\u对齐的默认值为4。但是,在您使用的GL_RGB
格式中,每像素3个字节,如果像素数是4的倍数,则行的大小仅为4字节的倍数。因此,对于每像素3字节的紧密压缩行,需要将该值设置为1。GL\u UNPACK\u ALIGNMENT
是每行的对齐方式,而不是每像素的对齐方式,不是吗?设置UNPACK ALIGNMENT无助于将数据对齐为4字节worked@StasJaro-仅供参考,有时您可以查看图像并立即说出一般问题是什么。你的图像有“楼梯”的效果——一旦你看到,这几乎可以保证图像没有对齐。我尝试将unpack对齐设置为1,这样就不重要了,但我会尝试这样做。事实上,我已经编写了一个软件3d光栅化器,但是在这里发布整个内容没有任何意义,因此纹理数据只加载一个红色(字节1[r]、字节2[g]、字节3[b])简单的条纹图案。(在调整大小时使用memset 0清除)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);