当前位置: 首页 > 知识库问答 >
问题:

是否可以使用LWJGL将C OpenGL代码与Java混合?

颜森
2023-03-14

我想制作Java应用程序。使用CEF3库。CEF是在任何应用程序中嵌入谷歌Chrome浏览器的库。LWJGL用于编写Java的GL代码。但是在使用CEF之前,基本问题是如何混合C和Java。

>

  • Java main将C部分调用为DLL

    C部分创建窗口并设置GL上下文

    在消息循环中,C再次回调Java部分,以便在Java中完成一些GL工作。

    以下测试代码失败,并显示消息:

    本机方法中的致命错误:线程[main,5,main]:没有当前上下文,或者调用了在当前上下文中不可用的函数。JVM将中止执行
    在组织。lwjgl。opengl。GL11.glColor3f(本机方法)
    Main。在Main上运行(Main.java:18)
    。cppmain(本机方法)
    Main。main(main.java:10)

    可能是因为Java部分不知道由C部分创建的GL上下文。我的问题是如何设置GL上下文,以便C和Java都可以调用GL函数?

    主要的Java语言

    import org.lwjgl.opengl.GL11;
    
    public class Main implements Runnable {
        {
            System.loadLibrary("cppgl");
        }
    
        public static void main(String[] args) {
            Main me = new Main();
            me.cppmain(me);
        }
    
        private native void cppmain(Runnable callback);
    
        @Override
        public void run() {
            // callback from cpp
            GL11.glColor3f(1.0f, 0.0f, 1.0f);
        }
    }
    

    cppgl.cpp

    #pragma comment(lib, "OpenGL32.lib")
    
    #include <windows.h>
    #include <tchar.h>
    #include <functional>
    #include <gl/gl.h>
    #include <jni.h>
    #pragma comment(lib, "jvm.lib")
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam) {
        if (mes == WM_DESTROY || mes == WM_CLOSE) { PostQuitMessage(0); return 0; }
        return DefWindowProc(hWnd, mes, wParam, lParam);
    }
    
    extern "C" JNIEXPORT void JNICALL Java_Main_cppmain
    (JNIEnv *env, jobject, jobject callback) {
    
        LPCTSTR title = L"gl test";
    
        // prepare JNI call
        jclass cls = env->FindClass("Ljava/lang/Runnable;");
        jmethodID mid = env->GetMethodID(cls, "run", "()V");
    
        // window class
        HINSTANCE hInstance = ::GetModuleHandle(NULL);
        WNDCLASSEX wcex;
        ZeroMemory(&wcex, sizeof(wcex));
        wcex.cbSize = sizeof(wcex);
        wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.hInstance = hInstance;
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszClassName = title;
        if (!RegisterClassEx(&wcex)) return;
    
        // window
        RECT R = { 0, 0, 640, 480 };
        AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, FALSE);
        HWND hWnd = CreateWindow(title, title, WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, R.right - R.left, R.bottom - R.top,
            NULL, NULL, hInstance, NULL);
        if (!hWnd) return;
    
        // GL context
        PIXELFORMATDESCRIPTOR pfd;
        ZeroMemory(&pfd, sizeof(pfd));
        pfd.nSize = sizeof(pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 32;
        pfd.cDepthBits = 24;
        pfd.iLayerType = PFD_MAIN_PLANE;
        HDC dc = GetDC(hWnd);
        int format = ChoosePixelFormat(dc, &pfd);
        SetPixelFormat(dc, format, &pfd);
        HGLRC glRC = wglCreateContext(dc);
        if (!wglMakeCurrent(dc, glRC)) return;
    
        // message loop
        ShowWindow(hWnd, SW_SHOW);
        MSG msg;
        do {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else {
                wglMakeCurrent(dc, glRC);
                glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
    
                // call Java and change clear color here
                env->CallVoidMethod(callback, mid);
    
                glClear(GL_COLOR_BUFFER_BIT);
                glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
                glFlush();
                SwapBuffers(dc);
                wglMakeCurrent(NULL, NULL);
            }
        } while (msg.message != WM_QUIT);
    
        // clean up
        wglMakeCurrent(NULL, NULL);
        wglDeleteContext(glRC);
        ReleaseDC(hWnd, dc);
    }
    
  • 共有1个答案

    卫松
    2023-03-14

    在从java进行任何渲染之前,您应该在开始时调用它一次。

        // This line is critical for LWJGL's interoperation with GLFW's
        // OpenGL context, or any context that is managed externally.
        // LWJGL detects the context that is current in the current thread,
        // creates the GLCapabilities instance and makes the OpenGL
        // bindings available for use.
        GL.createCapabilities();
    
     类似资料:
    • 问题内容: 遗言(现在的业力)很棒,角度场景也是如此。然而,将它们一起使用是一个挑战。在睾丸中有一个ANGENLAR-SCENARIO- ADAPTER,但这打破了简单的测试。如果您自己包含angular-scenario.js,Testacular将完全不进行任何测试。有人能正常运行吗? 角度场景适配器 我已经尝试过使用它进行琐碎的测试,但是我看到了一些奇怪的行为: 测试: 配置的正常行为: 输

    • 问题内容: 我正在使用Phonegap + React.js和Socket.io开发一个应用程序。但是,随后React-Native发行了,其原生感觉很棒。 我试图让socket.io-client与React Native一起工作,但是不幸的是没有成功。我做了一些研究,发现与此问题中描述的错误完全相同:https : //github.com/facebook/react- native/iss

    • 我想让flume代理位于hadoop集群之外,并想知道是否有可能使用flume通过WebHDFS向hadoop集群发送消息。 如果没有,是否有使用WebHDFS的替代方案?使用多层水槽层仍然需要我在hadoop集群中运行水槽代理。

    • 问题内容: 现在我有了一些C源代码,我想在我的Java应用程序中使用它。我需要执行C源代码,并将结果返回到我的Java应用程序。与其将所有C源代码重写为Java,我如何在Java应用程序中重用C源代码? 问题答案: 看一下Java Native Interface 。 Java本机接口(JNI)是一种编程框架,它使Java虚拟机(JVM)中运行的Java代码能够被本机应用程序(特定于硬件和操作系统

    • 我想通过代理服务器连接到Azure Service Bus消息队列。我在Spring应用程序中使用流绑定库 波姆。xml: 应用yml 我试图通过命令行参数提供HTTP和SOCKS代理设置,但这似乎不起作用。是否可以为“examplehost.servicebus.windows.net”的连接提供SOCKS或HTTP代理?

    • 是否可以在AWS Lambda中构建一个函数来创建websocket并将数据发送到订阅的应用程序? 类似这样: John在他的手机中打开了应用程序SuperPhotoApp,但决定使用桌面浏览器将照片上传到SuperPhotoApp服务(S3 Bucket),此事件执行创建套接字的Lambda函数。io服务器并将更新推送到所有订户,他的手机打开了应用程序,因此应用程序会自动更新新照片。 这可以通过