LWJGL / STB:在Intellij中运行时不一致与通过控制台运行



我在Intellij中使用lwjgl和stb truetype时有问题。

现在,当我尝试创建一个位图并将所有内容放入main('代码1 '(时,一切都很好。
一旦我尝试将其拆分创建一个OpenGL Context (如果我在不创建OpenGl上下文的情况下将其拆分,它也可以正常运行((以某种方式损坏了程序,并且程序用access_violation崩溃,或者在没有生成位图的情况下运行。您可以在下面看到损坏的代码为'代码2 '。

错误的行为仅在使用Java运行参数运行时发生,Intellij使用 - 通过Intellij运行或通过控制台。
当建立罐子并运行它时,不会发生这种情况。

有问题的论点是以下内容。如果控制台中缺少此操作,则运行。

-Javaagent:< Intellij_home> lib indub indue_rt.jar = 52850:< Intellij_home> bin

我在这里阅读了IDEA_RT.JAR文件"需要提供优雅的关闭/退出/stacktrace功能",因此我不想在Intellij中将其禁用。


注意:在损坏的代码(下面的'代码2'(中,您会注意到"不必要"行
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);
    }
}


如何解决与文本渲染时无法将程序运行的问题?

我可能会误解STBTT库,实际上无法使用字体?

任何帮助都将不胜感激,以了解错误并解决此问题。

我在LWJGL论坛中问了这个问题,并解决了问题。

STBTTFONTINFO对象仅包含元数据。实际的字体数据未从您传递给stbtt_initfont的字节缩影复制。仅复制其内存地址,并在必要时通过该指针访问字体数据。您看到的Segfault发生了,因为您没有在任何地方存储对字节案的引用,因此在尝试使用字体时,它会被gced/deallocked。一个简单的修复方法是更改您的字体类,也存储字节卷。

您可以在此处查看帖子。

最新更新