2

ネットワークからのopenglおよびprinimaetストリームでのレンダリングに従事しているライブラリがあります。

私はポピーの下で書いていますが、Linuxで使用する予定です

そのため、目的のc用にウィンドウが作成されます。データを受信して​​デコードする別のスレッドで描画を開始します。

シングル スレッドでのみ使用している場合でも、opengl のメソッドでバグ (EXT_BAD_ACCESS) がクラッシュします。

私のコードの主な過剰:

int main(int argc, const char * argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
int win = glutGetWindow();
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL lesson 1");
client_init(1280, 720, win, "192.168.0.98", 8000, 2222);
return 0;

}

または目的 c

- (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat*)format{
self = [super initWithFrame:frameRect];
if (self != nil) {
    NSOpenGLPixelFormatAttribute attributes[] = {

        NSOpenGLPFANoRecovery,
        NSOpenGLPFAFullScreen,
        NSOpenGLPFAScreenMask,
        CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
        (NSOpenGLPixelFormatAttribute) 0
    };
    _pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
    if (!_pixelFormat)
    {
        return nil;
    }
    //_pixelFormat   = [format retain];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(_surfaceNeedsUpdate:)
                                                 name:NSViewGlobalFrameDidChangeNotification
                                               object:self];
    _openGLContext = [self openGLContext];
    client_init(1280, 720, win, "192.168.0.98", 8000, 2222);
}
return self;

}

client_init コード

    // pthread_create(&posixThreadID, NULL, (void*(*)(void*))ShowThread, dh_tmp);
pthread_create(&posixThreadID, NULL, (void*(*)(void*))ShowThread, NULL);

void* ShowThread(struct drawhandle * dh){

        //glViewport(0, 0, dh->swidth, dh->sheight);//EXT_BAD_ACCESS
        glViewport(0, 0, 1280, 720);//EXT_BAD_ACCESS

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        //gluOrtho2D(0, dh->swidth, 0, dh->sheight);
        gluOrtho2D(0, 1280, 0, 720);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

    ...
        return 0;
    }

私は問題があると思いますか?その未作成のコンテキスト opengl.

macos / linuxで作成する方法は?

4

2 に答える 2

2

このスレッドには現在の OpenGL コンテキストがありません。プログラムの早い段階でコンテキストを作成した場合でも (スニペットには表示されません)、起動したスレッドでは最新のものではありません。

OpenGL コンテキストは、例外なく、一度に 1 つのスレッドに対して常に「最新」です。デフォルトでは、これはコンテキストを作成したスレッドです。OpenGL を呼び出すスレッドは、最初に「最新」にする必要があります。

このスレッドでコンテキストを作成するか、内部で(Unix/Linux) または(Mac) または(Windows) を呼び出す必要があります ( OpenGL に関連する他の処理を行う前に)。glXMakeCurrentaglMakeCurrentwglMakeCurrentShowThread

(おそらくクラッシュの理由ではありませんが...クラッシュの考えられる理由についてはdatenwolfの回答を参照してください-それでもそれは間違っています)`

于 2012-12-21T14:18:44.807 に答える
1

OpenGL とマルチスレッドは難しい条件です。できますが、注意が必要です。何よりもまず、OpenGL コンテキストは一度に 1 つのスレッドでしかアクティブにできません。また、一部のシステムでは、Windows 拡張関数ポインターはコンテキストごとに存在するため、異なるスレッドの異なるコンテキストでは、プロビジョニングが必要な異なる拡張関数ポインターになる可能性があります。

したがって、問題 1 があります。おそらく、このスレッドには OpenGL コンテキストがありませんが、非拡張関数を呼び出してもクラッシュしないはずです。何もしないだけです。

指定した行で実際にクラッシュする場合、dhポインターは確実に無効です。唯一の説明です。C のポインターは、特別な方法で解釈される単なる数値です。ポインターを渡す場合 (特にコールバックまたはスレッド関数へのパラメーターとして使用される場合)、このポインターにアクセスできなくなることが確認されるまで、オブジェクトからポインターへのポインターが無効になってはなりません。つまり、スタック上で作成するもの、つまり C 自動ストレージでこれを使用してはなりません。

これは壊れます:

void foo(void)
{
    struct drawhandle dh_tmp;

    pthread_create(&posixThreadID, NULL, (void*(*)(void*))ShowThread, &dh_tmp);
}

なぜ?オブジェクトが無効になる瞬間fooが返されるためです。dh_tmpしかし、&dh_tmp(それへのポインター)は単なる数値であり、この数値は「魔法のように」ゼロにならず、その瞬間dh_tmpは無効になります。

これを機能させるには、ヒープに割り当てる必要があります。もちろん、いつメモリを解放するかという問題があります。

于 2012-12-21T14:23:22.910 に答える