如何 运行 与 opengl 并行编程
how to run program parallel to opengl
我想 运行 opengl 并且我还希望我的 C 代码被执行... xD
创建 window 后没有代码执行...这正常吗?
还是我只需要更好地理解 opengl :D
也许我需要将我的 C 代码放入一些 opengl 循环 xD 中,比如进入空闲函数^^
//============================================================================
// Name : cpu_Emulation_19-10-13.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
//https://fms.komkon.org/EMUL8/HOWTO.html
// todo: iam programming the dissambler which just checks my given in commands.. 1927 - 31.10.2019
#include <iostream>
#include <stdint.h>
#include "C8Klasse.h"
#include "Cartridge.h"
#include <stdio.h>
#include <GL/glut.h>
#include <intrin.h> // damit kann man zyklen auslesen...
using namespace std;
// Windows
//#ifdef _WIN32
// what does this whole thing: it ist a Chip8 Interpreter
unsigned short int memory[1000]; // annahem
void initMemory() {
memory[0] = 0;
memory[1] = 1;
}
void display() {
}
void glutInitRoutines() {
glutInitWindowSize(64, 32);
glutCreateWindow("Chip8 V5");
glutDisplayFunc(display); // die obige Funktion display wird als Bildchirm behandler bekanntgemacht
//glutSpecialFunc( process_Normal_Keys);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 32.0, 64.0, 0.0);
//glutIdleFunc( idle);
glutMainLoop();
//void glutIdleFunc(void (*func)(void)
}
int main(int argc, char **argv) {
//screen
glutInit(&argc, argv);
glutInitRoutines(); // initialisation for opengGL window
//screen end
char rom_name[] = "img Fishie.ch8";
// #Start Chip8
C8Klasse c8; // lege interpreter an
c8.initSpeicher(); // initialisiere den Speicher zu 0
// #Setup cartridge
Cartridge testCartridge; // declare a Cartridge ( its the rom with the game data !!
testCartridge.readInOpcodeFromFileInArray(rom_name); // reads opcode of a data-file (should be in workspace) into an intern array
testCartridge.printOpcode();
// # Cartridgecode to Chip8 Memory
c8.setOpCode(testCartridge);// here the Opcode of the game is passed to the c8 CPU ( Cartridge ->internal memory )!
c8.printMemory(); // here the c8 internal memory is printed out, should be same form 0x200 to 0xfff with cartridge , since the game has been read in !
c8.printMemory(0x200); // prints memory by starting at given paramater address !
cout << "\n please press enter to continue with the program !" << endl;
cin.get();
cout << "enter" << endl;
unsigned short int counter = 0x00; // ein zykluscounter - zählt zeit bis zum nächsten unsigned short interrupt....
unsigned short int opCode = 0;
//########################################################## main loop
c8.setPC(0x200); // starte mit dem PC auf Adresse 0x200 !
for (int i = 0; i < testCartridge.getOpcodeLength(); i++) {
// opCOde is a unsigned short int ( 16 Bit ) the memory is just 8 Bit ! so please make some bit-amipulation: executableOpcode=(opcode1 <<8) | (opcode2)
opCode = ((unsigned short int) ((c8.getMemAtPC() & (0xff))) << 8);
c8.incrementPCCounter(1); // increment PC
opCode = opCode | (((unsigned short int) (c8.getMemAtPC() & (0xff))));
c8.incrementPCCounter(1); // increment PC -- for the next round
c8.dissembler(opCode); // so if the opcode variable is fille with 2 Bytes please run the dissembler !
cout << "\ncurrent pc: 0x" << hex << c8.getPC();
// cout << ", the read out OpCode is:0x" << hex << opCode; // show opcode.
printf(" the read OpCode is: 0x%04x", opCode);
cin.get();
// man muss bei den Befehlen unterscheiden: befehle fangen mit einer fixen Zahl an und haben dann variablen!
// man muss deswegen zuerst schauen welche zahl am Anfang steht oder , man muss nach einer Zahlenkombinatuon suchen
//Befehle: http://devernay.free.fr/hacks/chip8/C8TECH10.HTM
//Hex to ASCII converter : https://www.rapidtables.com/convert/number/hex-to-ascii.html
}
return 0;
}
/*
*
All instructions are 2 bytes long and are stored most-significant-byte first.
In memory, the first byte of each instruction should be located at an even addresses.
3.1 - Standard Chip-8 Instructions
00E0 - CLS
00EE - RET
0nnn - SYS addr
1nnn - JP addr
2nnn - CALL addr
3xkk - SE Vx, byte
4xkk - SNE Vx, byte
5xy0 - SE Vx, Vy
6xkk - LD Vx, byte
7xkk - ADD Vx, byte
8xy0 - LD Vx, Vy
8xy1 - OR Vx, Vy
8xy2 - AND Vx, Vy
8xy3 - XOR Vx, Vy
8xy4 - ADD Vx, Vy
8xy5 - SUB Vx, Vy
8xy6 - SHR Vx {, Vy}
8xy7 - SUBN Vx, Vy
8xyE - SHL Vx {, Vy}
9xy0 - SNE Vx, Vy
Annn - LD I, addr
Bnnn - JP V0, addr
Cxkk - RND Vx, byte
Dxyn - DRW Vx, Vy, nibble
Ex9E - SKP Vx
ExA1 - SKNP Vx
Fx07 - LD Vx, DT
Fx0A - LD Vx, K
Fx15 - LD DT, Vx
Fx18 - LD ST, Vx
Fx1E - ADD I, Vx
Fx29 - LD F, Vx
Fx33 - LD B, Vx
Fx55 - LD [I], Vx
Fx65 - LD Vx, [I]
3.2 - Super Chip-48 Instructions
00Cn - SCD nibble
00FB - SCR
00FC - SCL
00FD - EXIT
00FE - LOW
00FF - HIGH
Dxy0 - DRW Vx, Vy, 0
Fx30 - LD HF, Vx
Fx75 - LD R, Vx
Fx85 - LD Vx, R
* */
当您调用 glutMainLoop() 时,您的程序将进入一个看起来有点像这样的循环:
void glutMainLoop()
{
while(true)
{
MSG msg = getWindowEvent();
switch(msg)
{
case QUIT: exit(0); break; //< NOTE: method never returns!!
/* snip */
}
}
}
这就是在调用 glutMainLoop() 之后无法 运行 任何代码的原因。如果您只想 运行 main 底部的代码一次(在应用程序启动时),则只需将 glutMainLoop() 从您的例程设置函数中移出,使其成为 main() 中的最后一次调用。如果您想 运行 该代码 同时 更新 GL window,您有几个选择:
- 只需 运行 std::cin 代码即可(作为对按键等的响应)。它会导致 OpenGL window 在代码为 运行 时冻结,只是因为它是一个单线程应用程序,所以在您完成之前不会发生重绘。
- 使用过剩 keypress/keyrelease 回调将输入的文本填充到全局 std::string(一次按一个键)。当您检测到输入时,解析和处理您的操作码形成全局字符串。不要调用 cin,并通过 OpenGL 在屏幕上呈现文本(或者,如果您非常懒惰,请调用 glutSetWindowTitle,这样就无需查找代码来在屏幕上呈现字体 - 虽然 glut 可以提供帮助!)
- 为基于 std::cin 的代码创建第二个线程(如果这是您真正想要做的事情?)。然后你必须处理线程的麻烦,在这种情况下恕我直言,这可能是矫枉过正。
就个人而言,我会选择选项 2。
我想 运行 opengl 并且我还希望我的 C 代码被执行... xD 创建 window 后没有代码执行...这正常吗? 还是我只需要更好地理解 opengl :D
也许我需要将我的 C 代码放入一些 opengl 循环 xD 中,比如进入空闲函数^^
//============================================================================
// Name : cpu_Emulation_19-10-13.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
//https://fms.komkon.org/EMUL8/HOWTO.html
// todo: iam programming the dissambler which just checks my given in commands.. 1927 - 31.10.2019
#include <iostream>
#include <stdint.h>
#include "C8Klasse.h"
#include "Cartridge.h"
#include <stdio.h>
#include <GL/glut.h>
#include <intrin.h> // damit kann man zyklen auslesen...
using namespace std;
// Windows
//#ifdef _WIN32
// what does this whole thing: it ist a Chip8 Interpreter
unsigned short int memory[1000]; // annahem
void initMemory() {
memory[0] = 0;
memory[1] = 1;
}
void display() {
}
void glutInitRoutines() {
glutInitWindowSize(64, 32);
glutCreateWindow("Chip8 V5");
glutDisplayFunc(display); // die obige Funktion display wird als Bildchirm behandler bekanntgemacht
//glutSpecialFunc( process_Normal_Keys);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 32.0, 64.0, 0.0);
//glutIdleFunc( idle);
glutMainLoop();
//void glutIdleFunc(void (*func)(void)
}
int main(int argc, char **argv) {
//screen
glutInit(&argc, argv);
glutInitRoutines(); // initialisation for opengGL window
//screen end
char rom_name[] = "img Fishie.ch8";
// #Start Chip8
C8Klasse c8; // lege interpreter an
c8.initSpeicher(); // initialisiere den Speicher zu 0
// #Setup cartridge
Cartridge testCartridge; // declare a Cartridge ( its the rom with the game data !!
testCartridge.readInOpcodeFromFileInArray(rom_name); // reads opcode of a data-file (should be in workspace) into an intern array
testCartridge.printOpcode();
// # Cartridgecode to Chip8 Memory
c8.setOpCode(testCartridge);// here the Opcode of the game is passed to the c8 CPU ( Cartridge ->internal memory )!
c8.printMemory(); // here the c8 internal memory is printed out, should be same form 0x200 to 0xfff with cartridge , since the game has been read in !
c8.printMemory(0x200); // prints memory by starting at given paramater address !
cout << "\n please press enter to continue with the program !" << endl;
cin.get();
cout << "enter" << endl;
unsigned short int counter = 0x00; // ein zykluscounter - zählt zeit bis zum nächsten unsigned short interrupt....
unsigned short int opCode = 0;
//########################################################## main loop
c8.setPC(0x200); // starte mit dem PC auf Adresse 0x200 !
for (int i = 0; i < testCartridge.getOpcodeLength(); i++) {
// opCOde is a unsigned short int ( 16 Bit ) the memory is just 8 Bit ! so please make some bit-amipulation: executableOpcode=(opcode1 <<8) | (opcode2)
opCode = ((unsigned short int) ((c8.getMemAtPC() & (0xff))) << 8);
c8.incrementPCCounter(1); // increment PC
opCode = opCode | (((unsigned short int) (c8.getMemAtPC() & (0xff))));
c8.incrementPCCounter(1); // increment PC -- for the next round
c8.dissembler(opCode); // so if the opcode variable is fille with 2 Bytes please run the dissembler !
cout << "\ncurrent pc: 0x" << hex << c8.getPC();
// cout << ", the read out OpCode is:0x" << hex << opCode; // show opcode.
printf(" the read OpCode is: 0x%04x", opCode);
cin.get();
// man muss bei den Befehlen unterscheiden: befehle fangen mit einer fixen Zahl an und haben dann variablen!
// man muss deswegen zuerst schauen welche zahl am Anfang steht oder , man muss nach einer Zahlenkombinatuon suchen
//Befehle: http://devernay.free.fr/hacks/chip8/C8TECH10.HTM
//Hex to ASCII converter : https://www.rapidtables.com/convert/number/hex-to-ascii.html
}
return 0;
}
/*
*
All instructions are 2 bytes long and are stored most-significant-byte first.
In memory, the first byte of each instruction should be located at an even addresses.
3.1 - Standard Chip-8 Instructions
00E0 - CLS
00EE - RET
0nnn - SYS addr
1nnn - JP addr
2nnn - CALL addr
3xkk - SE Vx, byte
4xkk - SNE Vx, byte
5xy0 - SE Vx, Vy
6xkk - LD Vx, byte
7xkk - ADD Vx, byte
8xy0 - LD Vx, Vy
8xy1 - OR Vx, Vy
8xy2 - AND Vx, Vy
8xy3 - XOR Vx, Vy
8xy4 - ADD Vx, Vy
8xy5 - SUB Vx, Vy
8xy6 - SHR Vx {, Vy}
8xy7 - SUBN Vx, Vy
8xyE - SHL Vx {, Vy}
9xy0 - SNE Vx, Vy
Annn - LD I, addr
Bnnn - JP V0, addr
Cxkk - RND Vx, byte
Dxyn - DRW Vx, Vy, nibble
Ex9E - SKP Vx
ExA1 - SKNP Vx
Fx07 - LD Vx, DT
Fx0A - LD Vx, K
Fx15 - LD DT, Vx
Fx18 - LD ST, Vx
Fx1E - ADD I, Vx
Fx29 - LD F, Vx
Fx33 - LD B, Vx
Fx55 - LD [I], Vx
Fx65 - LD Vx, [I]
3.2 - Super Chip-48 Instructions
00Cn - SCD nibble
00FB - SCR
00FC - SCL
00FD - EXIT
00FE - LOW
00FF - HIGH
Dxy0 - DRW Vx, Vy, 0
Fx30 - LD HF, Vx
Fx75 - LD R, Vx
Fx85 - LD Vx, R
* */
当您调用 glutMainLoop() 时,您的程序将进入一个看起来有点像这样的循环:
void glutMainLoop()
{
while(true)
{
MSG msg = getWindowEvent();
switch(msg)
{
case QUIT: exit(0); break; //< NOTE: method never returns!!
/* snip */
}
}
}
这就是在调用 glutMainLoop() 之后无法 运行 任何代码的原因。如果您只想 运行 main 底部的代码一次(在应用程序启动时),则只需将 glutMainLoop() 从您的例程设置函数中移出,使其成为 main() 中的最后一次调用。如果您想 运行 该代码 同时 更新 GL window,您有几个选择:
- 只需 运行 std::cin 代码即可(作为对按键等的响应)。它会导致 OpenGL window 在代码为 运行 时冻结,只是因为它是一个单线程应用程序,所以在您完成之前不会发生重绘。
- 使用过剩 keypress/keyrelease 回调将输入的文本填充到全局 std::string(一次按一个键)。当您检测到输入时,解析和处理您的操作码形成全局字符串。不要调用 cin,并通过 OpenGL 在屏幕上呈现文本(或者,如果您非常懒惰,请调用 glutSetWindowTitle,这样就无需查找代码来在屏幕上呈现字体 - 虽然 glut 可以提供帮助!)
- 为基于 std::cin 的代码创建第二个线程(如果这是您真正想要做的事情?)。然后你必须处理线程的麻烦,在这种情况下恕我直言,这可能是矫枉过正。
就个人而言,我会选择选项 2。