単純な C だけを使用して chip8 エミュレーターを作成しようとしています。ほとんどのオペコードが設定されているので、ディスプレイで作業する必要があります。セットアップが簡単に見えたので、ディスプレイに GLUT を使用することにしました。主なアイデアは、chip8 スプライトを 2D テクスチャに表示することです。オペコードを実行していくつかの数字を表示するようにしましたが、ちらつきます。私が読んだことから、何かを表示する準備ができていることを確認するための最良の方法であるため、ダブルバッファリングを使用していますが、まだちらつきがあります。何がそれを引き起こす可能性があるかについてのアイデアはありますか?
ディスプレイ用の OpenGL と GLUT のすべてのコードを次に示します。
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;
}
編集:私はそれを理解したかもしれません。描画オペコードでは、XOR を使用します。そのため、最初に描画コマンドを実行するとスプライトが表示され、再度呼び出されると消えます。