LWJGL / STB:IntelliJ 中 运行 与控制台 运行 不一致
LWJGL / STB: Inconsistency when running in IntelliJ vs. running over Console
我在 IntelliJ 中使用 LWJGL 和 STB TrueType 时遇到问题。
当我现在尝试创建位图并将所有内容放入 Main(下面的“代码 1”)时,一切正常。
一旦我尝试将其拆分 和 创建一个 OpenGL 上下文 (如果我将其拆分而不创建 OpenGL 上下文它也可以正常工作), 加载的字体以某种方式损坏,并且程序崩溃并显示 ACCESS_VIOLATION 或 运行s 而没有生成位图。您可以在下面看到损坏的代码,如“代码 2”。
错误行为仅在 运行 java 运行 参数时发生,IntelliJ 使用 - 通过 Intellij 运行 或通过控制台。
它不会发生在构建到 JAR 中并 运行ning 时不会发生。
有问题的论点如下。如果控制台中缺少这个,它 运行s.
-javaagent:<INTELLIJ_HOME>\lib\idea_rt.jar=52850:<INTELLIJ_HOME>\bin
我已阅读 here idea_rt.jar 文件 "is needed to provide graceful shutdown/exit/stacktrace features",因此我不想在 IntelliJ 中禁用它。
注意: 在损坏的代码中(下面的 'Code 2'),您会注意到 'unnecessary' 行
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
模拟加载多种字体。如果我只加载一种字体,一切正常。
您还会注意到代码 2 中的 OpenGL 上下文创建,这似乎也是问题的原因(如上所述)
代码 1(有效)
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.stb.STBTTFontinfo;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.stb.STBTruetype.stbtt_GetCodepointBitmap;
import static org.lwjgl.stb.STBTruetype.stbtt_InitFont;
public class STBTTExampleOnlyMain {
private static ByteBuffer loadByteBufferFromResource(String resource) throws IOException {
try(InputStream stream = STBTTExampleOnlyMain .class.getResourceAsStream(resource)) {
byte[] bytes = stream.readAllBytes();
ByteBuffer buffer = BufferUtils.createByteBuffer(bytes.length);
buffer.put(bytes);
buffer.flip();
return buffer;
}
}
public static void main(String[] args) throws IOException {
ByteBuffer data = loadByteBufferFromResource("/fonts/arial.ttf");
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
STBTTFontinfo font = STBTTFontinfo.create();
stbtt_InitFont(font, data);
IntBuffer bufWidth = BufferUtils.createIntBuffer(1);
IntBuffer bufHeight = BufferUtils.createIntBuffer(1);
ByteBuffer bitmap = stbtt_GetCodepointBitmap(font, 0, 1, 'a', bufWidth, bufHeight, null, null);
System.out.println(bitmap);
}
}
代码 2(损坏)
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.stb.STBTTFontinfo;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.stb.STBTruetype.stbtt_GetCodepointBitmap;
import static org.lwjgl.stb.STBTruetype.stbtt_InitFont;
public class STBTTExample {
private static final Map<Integer, STBTTFontinfo> fontMap = new HashMap<>();
private static ByteBuffer loadByteBufferFromResource(String resource) throws IOException {
try(InputStream stream = STBTTExample.class.getResourceAsStream(resource)) {
byte[] bytes = stream.readAllBytes();
ByteBuffer buffer = BufferUtils.createByteBuffer(bytes.length);
buffer.put(bytes);
buffer.flip();
return buffer;
}
}
private static void initFont() throws IOException {
ByteBuffer data = loadByteBufferFromResource("/fonts/arial.ttf");
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
STBTTFontinfo font = STBTTFontinfo.create();
stbtt_InitFont(font, data);
fontMap.put(0, font);
}
public static void main(String[] args) throws IOException {
initFont();
glfwInit();
glfwDefaultWindowHints();
long windowHandle = glfwCreateWindow(800, 600, "Test", 0, 0);
glfwMakeContextCurrent(windowHandle);
GL.createCapabilities();
IntBuffer bufWidth = BufferUtils.createIntBuffer(1);
IntBuffer bufHeight = BufferUtils.createIntBuffer(1);
ByteBuffer bitmap = stbtt_GetCodepointBitmap(fontMap.get(0), 0, 1, 'a', bufWidth, bufHeight, null, null);
System.out.println(bitmap);
}
}
如何解决在使用文本渲染时无法 运行 程序脱离 IntelliJ 的问题?
我是否可能误解了 STBTT 库并且实际上不能以这种方式使用字体?
如果您能帮助我们理解错误并解决这个问题,我们将不胜感激。
我在LWJGL论坛问过,问题解决了
The STBTTFontinfo object contains metadata only. The actual font data is NOT copied from the ByteBuffer you pass to stbtt_InitFont. Only its memory address is copied and the font data is accessed via that pointer when necessary. The segfault you're seeing happens because you don't store a reference to the ByteBuffer anywhere, it is GCed/deallocated by the time you try to use the font. An easy fix would be to change your Font class to also store the ByteBuffer.
你可以看看post here.
我在 IntelliJ 中使用 LWJGL 和 STB TrueType 时遇到问题。
当我现在尝试创建位图并将所有内容放入 Main(下面的“代码 1”)时,一切正常。
一旦我尝试将其拆分 和 创建一个 OpenGL 上下文 (如果我将其拆分而不创建 OpenGL 上下文它也可以正常工作), 加载的字体以某种方式损坏,并且程序崩溃并显示 ACCESS_VIOLATION 或 运行s 而没有生成位图。您可以在下面看到损坏的代码,如“代码 2”。
错误行为仅在 运行 java 运行 参数时发生,IntelliJ 使用 - 通过 Intellij 运行 或通过控制台。
它不会发生在构建到 JAR 中并 运行ning 时不会发生。
有问题的论点如下。如果控制台中缺少这个,它 运行s.
-javaagent:<INTELLIJ_HOME>\lib\idea_rt.jar=52850:<INTELLIJ_HOME>\bin
我已阅读 here idea_rt.jar 文件 "is needed to provide graceful shutdown/exit/stacktrace features",因此我不想在 IntelliJ 中禁用它。
注意: 在损坏的代码中(下面的 'Code 2'),您会注意到 'unnecessary' 行
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
模拟加载多种字体。如果我只加载一种字体,一切正常。
您还会注意到代码 2 中的 OpenGL 上下文创建,这似乎也是问题的原因(如上所述)
代码 1(有效)
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.stb.STBTTFontinfo;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.stb.STBTruetype.stbtt_GetCodepointBitmap;
import static org.lwjgl.stb.STBTruetype.stbtt_InitFont;
public class STBTTExampleOnlyMain {
private static ByteBuffer loadByteBufferFromResource(String resource) throws IOException {
try(InputStream stream = STBTTExampleOnlyMain .class.getResourceAsStream(resource)) {
byte[] bytes = stream.readAllBytes();
ByteBuffer buffer = BufferUtils.createByteBuffer(bytes.length);
buffer.put(bytes);
buffer.flip();
return buffer;
}
}
public static void main(String[] args) throws IOException {
ByteBuffer data = loadByteBufferFromResource("/fonts/arial.ttf");
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
STBTTFontinfo font = STBTTFontinfo.create();
stbtt_InitFont(font, data);
IntBuffer bufWidth = BufferUtils.createIntBuffer(1);
IntBuffer bufHeight = BufferUtils.createIntBuffer(1);
ByteBuffer bitmap = stbtt_GetCodepointBitmap(font, 0, 1, 'a', bufWidth, bufHeight, null, null);
System.out.println(bitmap);
}
}
代码 2(损坏)
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.stb.STBTTFontinfo;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.stb.STBTruetype.stbtt_GetCodepointBitmap;
import static org.lwjgl.stb.STBTruetype.stbtt_InitFont;
public class STBTTExample {
private static final Map<Integer, STBTTFontinfo> fontMap = new HashMap<>();
private static ByteBuffer loadByteBufferFromResource(String resource) throws IOException {
try(InputStream stream = STBTTExample.class.getResourceAsStream(resource)) {
byte[] bytes = stream.readAllBytes();
ByteBuffer buffer = BufferUtils.createByteBuffer(bytes.length);
buffer.put(bytes);
buffer.flip();
return buffer;
}
}
private static void initFont() throws IOException {
ByteBuffer data = loadByteBufferFromResource("/fonts/arial.ttf");
ByteBuffer data2 = loadByteBufferFromResource("/fonts/arial.ttf");
STBTTFontinfo font = STBTTFontinfo.create();
stbtt_InitFont(font, data);
fontMap.put(0, font);
}
public static void main(String[] args) throws IOException {
initFont();
glfwInit();
glfwDefaultWindowHints();
long windowHandle = glfwCreateWindow(800, 600, "Test", 0, 0);
glfwMakeContextCurrent(windowHandle);
GL.createCapabilities();
IntBuffer bufWidth = BufferUtils.createIntBuffer(1);
IntBuffer bufHeight = BufferUtils.createIntBuffer(1);
ByteBuffer bitmap = stbtt_GetCodepointBitmap(fontMap.get(0), 0, 1, 'a', bufWidth, bufHeight, null, null);
System.out.println(bitmap);
}
}
如何解决在使用文本渲染时无法 运行 程序脱离 IntelliJ 的问题?
我是否可能误解了 STBTT 库并且实际上不能以这种方式使用字体?
如果您能帮助我们理解错误并解决这个问题,我们将不胜感激。
我在LWJGL论坛问过,问题解决了
The STBTTFontinfo object contains metadata only. The actual font data is NOT copied from the ByteBuffer you pass to stbtt_InitFont. Only its memory address is copied and the font data is accessed via that pointer when necessary. The segfault you're seeing happens because you don't store a reference to the ByteBuffer anywhere, it is GCed/deallocated by the time you try to use the font. An easy fix would be to change your Font class to also store the ByteBuffer.
你可以看看post here.