Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL在调整缓冲区大小时失败_C++_C_Opengl_Exc Bad Access - Fatal编程技术网

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);