Можно ли смешивать код C ++ OpenGL с Java, используя LWJGL?

Я хочу сделать приложение Java. используя библиотеку CEF3.
CEF — это библиотека для встроенного браузера Google Chrome в любом приложении.
И LWJGL используется для написания кода GL на Java.
Но прежде чем использовать CEF, основной вопрос заключается в том, как смешать C ++ и Java.

  1. Java вызывает C ++ часть как DLL

  2. Часть C ++ создает окно и устанавливает контекст GL

  3. В цикле сообщений C ++ снова вызывает Java-часть для выполнения некоторого GL
    работать на яве.

Следующий тестовый код завершается с сообщением:

ФАТАЛЬНАЯ ОШИБКА в собственном методе: Thread [main, 5, main]: нет контекста
текущий или функция, которая недоступна в текущем контексте, была
называется. JVM прервет выполнение.
на org.lwjgl.opengl.GL11.glColor3f (родной метод)
на Main.run (Main.java:18)
в Main.cppmain (собственный метод)
в Main.main (Main.java:10)

Наверное потому что Java часть не знает
о контексте GL, созданном частью C ++.
Мой вопрос, как я могу настроить контекст GL
чтобы и C ++, и Java могли вызывать функции GL?


Main.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);
}

0

Решение

Вы должны вызвать это один раз в начале, прежде чем делать какой-либо рендеринг из 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();
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]