如何与opengl并行运行程序[关闭]

Posted

技术标签:

【中文标题】如何与opengl并行运行程序[关闭]【英文标题】:how to run program parallel to opengl [closed] 【发布时间】:2019-11-27 20:52:16 【问题描述】:

我想运行 opengl,我还希望我的 c 代码被执行... xD 创建窗口后不执行任何代码...这是正常的吗? 还是我需要更好地理解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...https://***.com/questions/13772567/how-to-get-the-cpu-cycle-count-in-x86-64-from-c
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
 * */

【问题讨论】:

i 另一个程序,例如我在按键检测后计算了我的外星人精灵......我认为每次没有调用任何其他内容时都会调用空闲()显示......但是对于这段代码,它会改变结构......它不会那么糟糕......但是我无法想象opengl是那么不灵活..但是我猜有一些改进。也许 sdl 更聪明? 【参考方案1】:

当你调用 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 窗口的同时运行该代码,您有两个选择:

    只要你想运行std::cin 代码(作为对按键等的响应)。这将导致 OpenGL 窗口在运行该代码时冻结,这仅仅是因为它是一个单线程应用程序,因此在完成之前不会发生重绘。 使用 glut keypress/keyrelease 回调来用输入的文本填充全局 std::string(一次按一个键)。当您检测到输入时,解析和处理来自全局字符串的操作码。不要调用 cin,并通过 OpenGL 在屏幕上渲染文本(或者,如果您非常懒惰,请调用 glutSetWindowTitle,这样就无需查找代码以在屏幕上渲染字体 - 尽管 glut 可以提供帮助!) 为基于 std::cin 的代码创建第二个线程(如果这是您真正想做的事情?)。然后,您必须处理线程的麻烦,在这种情况下,恕我直言,这可能是矫枉过正。

就个人而言,我会选择选项 2。

【讨论】:

很好的答案,但我建议完全放弃过剩并使用像 GLFW 这样的真正框架。 谢谢!哇...是的,我认为这是 3Dave 所说的很好的答案! ....我认为我需要这样一个“真正的”框架..因为对我来说一开始可能会更容易。你提到的 3 个选项对我来说太复杂了。 ...好的,但缺点是,我必须了解“框架”xD,我对此一无所知...哦..也许我真的必须寻找您的 3 个解决方案之一 xD 啊..也许对你来说这很容易,你可能告诉我它是隐含的等等,但是 void glutPostRedisplay (void);我认为对我来说是openGL的一个非常有趣的部分。我可以每次运行代码...是的,这是您提到的主循环...是的,但是您是对的,它不再是并行的..好的,但是对于我而言,这可能就足够了..void idle() cout

以上是关于如何与opengl并行运行程序[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从 PHP 应用程序运行并行 CLI 进程的最有效方法 [关闭]

如何在 Windows 中运行基本的“Hello World”GLSL 程序? [关闭]

如何限制运行的并行任务数量? [关闭]

OpenGL程序如何在VC环境中运行

使用 glutBitmapCharacter() 绘制文本关闭 opengl 程序

运行并行 AsyncTask