使用Glut和C闪烁2D纹理



我正在尝试使用普通的C制作chip8仿真器。我得到了大多数opcodes设置,所以我只需要在显示屏上工作即可。我决定将Glut用于显示器,因为它看起来是快速设置。主要思想是将CHIP8 Sprites显示在2D纹理上。我得到了它显示一些数字,但有些操作码执行,但它正在闪烁。我正在使用双重缓冲,因为从我阅读的内容来看,这是确保展示某件事的最佳方法,但我仍在闪烁。关于什么可能导致它的想法?

这是显示器的所有代码。

int main(int argc,  char * argv[]) {
//    if(argc < 2){
//        printf("Usage: %s <bin file>n", argv[0]);
//        exit(0);
//    }
    //initialize chip 8
    chip8_Init();
    //load file if exists
    chip8_load("test6.bin");
    //setup graphics
    glutInit(&argc, argv);
    glutInitWindowSize(display_width, display_height);
    glutInitWindowPosition(320, 320);
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("Chip8 GL");
    setupTexture();
    glutDisplayFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutIdleFunc(renderScene);
    glutKeyboardFunc(chip8_keypad);
    glutKeyboardUpFunc(chip8_keypadUp);
    glutMainLoop();
    return 0;
}

void setupTexture(){ 
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);
    //set texture parameters
    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_MAG_FILTER,
                GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                GL_NEAREST);
    //update texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH,
             SCREEN_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE,
             screenData);
}
void updateTexture(){ //display()
    //update pixels
    for (int i = 0; i < SCREEN_HEIGHT; i++) {
        for (int j = 0; j < SCREEN_WIDTH; j++) {
            if(chip8.gfx[(i * SCREEN_WIDTH)+j] == 0){
                screenData[i][j][0] = 0;
                screenData[i][j][1] = 0;
                screenData[i][j][2] = 0;
            }
            else{
                screenData[i][j][0] = 255;
                screenData[i][j][1] = 255;
                screenData[i][j][2] = 255;
            }  
        }
    }
    //update texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH,
             SCREEN_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE,
             screenData);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, texName);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex2d(0.0, 0.0);
    glTexCoord2f(1.0, 0.0); glVertex2d(display_width, 0.0);
    glTexCoord2f(1.0, 1.0); glVertex2d(display_width, display_height);
    glTexCoord2f(0.0, 1.0); glVertex2d(0.0, display_height);
    glEnd();
    glutSwapBuffers();
}
void renderScene(){
    chip8_emulateCycle();
    if(drawFlag == 1){
    updateTexture();
    drawFlag = 0;
    }  
}
void changeSize(int w, int h){
    glClearColor(0.0f, 0.0f, 0.5f, 0.0f);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, w, h, 0);
    glMatrixMode(GL_MODELVIEW);
    glViewport(0, 0, w, h);
    // Resize quad
    display_width = w;
    display_height = h;
}

编辑:我可能已经弄清楚了。在绘制opcode中,它使用XOR。因此,当第一次显示精灵的绘制命令并再次调用时,它会消失等等。

我的OpenGl非常尘土飞扬,但是我在您的代码中看到了一些点:

您应该在初始化之前启用GL_TEXTURE_2D

void setupTexture()
{ 
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    /* enable texturing */
    glEnable(GL_TEXTURE_2D);
    /* create texture */
    glGenTextures(1, &texName);
    /* select texture */
    glBindTexture(GL_TEXTURE_2D, texName);
    /* select behavior */
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    /* ... */
}

您应该在修改纹理之前选择纹理

void updateTexture(){ 
    /* update pixels */
    /* ... */
    /*select texture */
    glBindTexture(GL_TEXTURE_2D, texName);
    /*update texture */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH,
             SCREEN_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE,
             screenData);
    /* clear screen */    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /* draw texture */
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex2d(0.0, 0.0);
    glTexCoord2f(1.0, 0.0); glVertex2d(display_width, 0.0);
    glTexCoord2f(1.0, 1.0); glVertex2d(display_width, display_height);
    glTexCoord2f(0.0, 1.0); glVertex2d(0.0, display_height);
    glEnd();
    glutSwapBuffers();
}

此外,您可以使用glGetError()

测试称为函数的结果
void check_for_error(void)
{
    GLenum err = glGetError();
    if (GL_NO_ERROR != err)
    {
        fprintf("Error %dn", err);
        exit(EXIT_FAILURE);
    }
}

说,我不知道chip8.gfx[]内的数据可能不是您预期的。

最新更新