JNI C++ OpenGL Window Crash

Hi. I'm new to C++ and JNI, and just started yesterday. I am trying to make my own OpenGL window system. (yes, I know that is a big task, and I don't care) I got a window a while ago, but now there is a weird issue. I get this console output java-side: 1 Invalid window handle. 2 Invalid window handle. 3 Invalid window handle. 4 Invalid window handle. ... 4 The system cannot find the file specified. ... 1 Invalid window handle. 2 Invalid window handle. 3 Invalid window handle. 4 Invalid window handle. ... The numbers at the start of each line indicate where in my C++ program the issue is coming from. I don't know why the middle one is there, because I'm not loading any files. The "invalid window handle" comes from resizing one dimension of the window, and the crash comes from resizing two at the same time. My code is in comments. Please help.
3 Replies
JavaBot
JavaBot9mo ago
This post has been reserved for your question.
Hey @The Typhothanian! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
The Typhothanian
The TyphothanianOP9mo ago
package net.typho.twgl;

public class GL {
static {
System.load("D:\\Desktop\\dllTest\\x64\\Debug\\dllTest.dll");
}

public static void main(String[] args) {
if (!windowInit("Test Window")) {
System.exit(1);
}

while (windowUpdate());
}

public static native boolean windowInit(String name);

public static native boolean windowUpdate();
}
package net.typho.twgl;

public class GL {
static {
System.load("D:\\Desktop\\dllTest\\x64\\Debug\\dllTest.dll");
}

public static void main(String[] args) {
if (!windowInit("Test Window")) {
System.exit(1);
}

while (windowUpdate());
}

public static native boolean windowInit(String name);

public static native boolean windowUpdate();
}
Errors
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

#include <jni.h>
#include <jni_md.h>
#include <gl/GL.h>
#include <tchar.h>
#include <Windows.h>
#include <cstring>
#include <iostream>

const int width = 1000;
const int height = 1000;

HWND hwnd;
HDC hdc;
HGLRC hglrc;

char* getError() {
DWORD errorMessageID = ::GetLastError();

if (errorMessageID == 0) {
return NULL;
}

LPSTR messageBuffer = NULL;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

char* result = new char[size + 1];
strncpy_s(result, size + 1, messageBuffer, size);
result[size] = '\0'; // Null-terminate the string

// Free the buffer.
LocalFree(messageBuffer);

return result;
}

void boxError() {
char* msg = getError();

if (msg != NULL) {
MessageBoxA(NULL, msg, "Error", MB_OK);
}
}

void printError(int location) {
bool err[1];
char* msg = getError();

if (msg != NULL) {
std::cerr << location << ' ' << msg;
}
}
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

#include <jni.h>
#include <jni_md.h>
#include <gl/GL.h>
#include <tchar.h>
#include <Windows.h>
#include <cstring>
#include <iostream>

const int width = 1000;
const int height = 1000;

HWND hwnd;
HDC hdc;
HGLRC hglrc;

char* getError() {
DWORD errorMessageID = ::GetLastError();

if (errorMessageID == 0) {
return NULL;
}

LPSTR messageBuffer = NULL;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

char* result = new char[size + 1];
strncpy_s(result, size + 1, messageBuffer, size);
result[size] = '\0'; // Null-terminate the string

// Free the buffer.
LocalFree(messageBuffer);

return result;
}

void boxError() {
char* msg = getError();

if (msg != NULL) {
MessageBoxA(NULL, msg, "Error", MB_OK);
}
}

void printError(int location) {
bool err[1];
char* msg = getError();

if (msg != NULL) {
std::cerr << location << ' ' << msg;
}
}
Window Processes
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
wglMakeCurrent(hdc, hglrc);

printError(1);

glClearColor(1, 0, 0, 1);

printError(2);

glClear(GL_COLOR_BUFFER_BIT);

printError(3);

SwapBuffers(hdc);

printError(4);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
wglMakeCurrent(hdc, hglrc);

printError(1);

glClearColor(1, 0, 0, 1);

printError(2);

glClear(GL_COLOR_BUFFER_BIT);

printError(3);

SwapBuffers(hdc);

printError(4);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
Window Init
extern "C" JNIEXPORT bool JNICALL Java_net_typho_twgl_GL_windowInit(JNIEnv * env, jclass cls, jstring name) {
WNDCLASSEX w;

w.cbSize = sizeof(WNDCLASSEX);
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpfnWndProc = WindowProcedure;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = GetModuleHandle(NULL);
w.hIcon = LoadIcon(w.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
w.lpszMenuName = NULL;
w.lpszClassName = L"net.typho.twgl.GL";
w.hIconSm = LoadIcon(w.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&w))
{
printError(-1);
return false;
}

hwnd = CreateWindow(
L"net.typho.twgl.GL",
L"Window", // TODO implement the jstring as window name
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
NULL,
NULL,
w.hInstance,
NULL
);

if (!hwnd)
{
printError(-2);
return false;
}

hdc = GetDC(hwnd);

if (!hdc) {
printError(-3);
return false;
}
extern "C" JNIEXPORT bool JNICALL Java_net_typho_twgl_GL_windowInit(JNIEnv * env, jclass cls, jstring name) {
WNDCLASSEX w;

w.cbSize = sizeof(WNDCLASSEX);
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpfnWndProc = WindowProcedure;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = GetModuleHandle(NULL);
w.hIcon = LoadIcon(w.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
w.lpszMenuName = NULL;
w.lpszClassName = L"net.typho.twgl.GL";
w.hIconSm = LoadIcon(w.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&w))
{
printError(-1);
return false;
}

hwnd = CreateWindow(
L"net.typho.twgl.GL",
L"Window", // TODO implement the jstring as window name
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
NULL,
NULL,
w.hInstance,
NULL
);

if (!hwnd)
{
printError(-2);
return false;
}

hdc = GetDC(hwnd);

if (!hdc) {
printError(-3);
return false;
}
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor
1, // Version number
PFD_DRAW_TO_WINDOW | // Format must support window
PFD_SUPPORT_OPENGL | // Format must support OpenGL
PFD_DOUBLEBUFFER, // Must support double buffering
PFD_TYPE_RGBA, // Request an RGBA format
24, // Select a 24 bit color depth
0, 0, 0, 0, 0, 0, // Color bits (ignored)
0, // No alpha buffer
0, // Shift bit (ignored)
0, // No accumulation buffer
0, 0, 0, 0, // Accumulation bits (ignored)
32, // 32 bit z-buffer (depth buffer)
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Main drawing layer
0, // Reserved
0, 0, 0 // Layer masks (ignored)
};

int iPixelFormat = ChoosePixelFormat(hdc, &pfd);

if (iPixelFormat == 0) {
printError(-4);
return false;
}

if (!SetPixelFormat(hdc, iPixelFormat, &pfd)) {
printError(-5);
return false;
}

hglrc = wglCreateContext(hdc);

if (!hglrc) {
printError(-6);
return false;
}

if (!wglMakeCurrent(hdc, hglrc)) {
printError(-7);
return false;
}

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

return true;
}
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor
1, // Version number
PFD_DRAW_TO_WINDOW | // Format must support window
PFD_SUPPORT_OPENGL | // Format must support OpenGL
PFD_DOUBLEBUFFER, // Must support double buffering
PFD_TYPE_RGBA, // Request an RGBA format
24, // Select a 24 bit color depth
0, 0, 0, 0, 0, 0, // Color bits (ignored)
0, // No alpha buffer
0, // Shift bit (ignored)
0, // No accumulation buffer
0, 0, 0, 0, // Accumulation bits (ignored)
32, // 32 bit z-buffer (depth buffer)
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Main drawing layer
0, // Reserved
0, 0, 0 // Layer masks (ignored)
};

int iPixelFormat = ChoosePixelFormat(hdc, &pfd);

if (iPixelFormat == 0) {
printError(-4);
return false;
}

if (!SetPixelFormat(hdc, iPixelFormat, &pfd)) {
printError(-5);
return false;
}

hglrc = wglCreateContext(hdc);

if (!hglrc) {
printError(-6);
return false;
}

if (!wglMakeCurrent(hdc, hglrc)) {
printError(-7);
return false;
}

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

return true;
}
And, window updating
extern "C" JNIEXPORT bool JNICALL Java_net_typho_twgl_GL_windowUpdate(JNIEnv * env, jclass cls) {
MSG msg;

if (GetMessage(&msg, NULL, 0, 0) <= 0) {
return false;
}

TranslateMessage(&msg);
DispatchMessage(&msg);

return true;
}
extern "C" JNIEXPORT bool JNICALL Java_net_typho_twgl_GL_windowUpdate(JNIEnv * env, jclass cls) {
MSG msg;

if (GetMessage(&msg, NULL, 0, 0) <= 0) {
return false;
}

TranslateMessage(&msg);
DispatchMessage(&msg);

return true;
}
Please help. I have no clue what the problem is. It worked fine before OpenGL. The SwapBuffers method seems to be the issue?
JavaBot
JavaBot9mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server