如何将OpenGL上下文放入我当前的线程中,找不到opengl上下文 [英] How to get OpenGL context into my current thread, opengl context not found

查看:1445
本文介绍了如何将OpenGL上下文放入我当前的线程中,找不到opengl上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个世界编辑器,以获得乐趣并使用Java和JLWGL。到目前为止一切正常。现在我尝试创建一个窗口,我可以在其中添加例如要使用的地形或新模型。问题是,当我尝试从我的main创建地形时,它被创建并显示,但当我尝试通过按钮eventlistener调用它时,我得到错误:当前线程中找不到OpenGL上下文。我基本上知道为什么我会收到错误。我用来获取输入并单击按钮的框架没有opengl上下文。

I'm working on a world editor for fun and using Java and JLWGL. Everything is working so far. Now I tried creating a window where I can add e.g. a terrain or a new model to use. Problem is, when I try to create the terrain from my main it is created and shown, but when I try to call it by an button eventlistener I get the error: No OpenGL context found in the current thread. I basically know why I get the error. My frame which I use to get the input and click the button has no opengl context.

我现在的问题是:如何将opengl上下文添加到当前帧?
欢迎任何帮助,如果你需要其他课程,请告诉我。

My question is now: How can I get the opengl context to my current frame? Any help is welcome, if you need other classes, let me know.

它确实是错误的,因为如果我运行generateTerrain(args);从我的主要工作完全正常,就好像我在eventlistener addTerrain.addActionListener 中使用它,并且 generateTerrain(1,terrains);

it really bugs be because if I run generateTerrain(args); from my main it works perfectly fine, just if I use it in the eventlistener addTerrain.addActionListener and there the generateTerrain(1, terrains);

这是我的主类:

This is my mainclass:

public class MainGameLoop extends JFrame{
    //CREATING THE LOADER
    final static Loader loader = new Loader();

    public static void main(String[] args) {

        //CREATING THE DISPLAY
        DisplayManager.createDisplay();


        //CREATE CAMERA
        Camera camera = new Camera(15f, 5f, 40f);

        //CREATE MASTER RENDERER
        final MasterRenderer renderer = new MasterRenderer();

        //LISTS
        final List<TexturedModel> texturedModels=new ArrayList<TexturedModel>(); 
        final List<Entity> entities=new ArrayList<Entity>();
        final List<Terrain> terrains=new ArrayList<Terrain>(); 

        //Loading the models into the VAOs
        //1
        loadTexturedModel("stall", "stall", texturedModels);
        //2
        loadTexturedModel("dragon", "white", texturedModels);
        //3
        //loadTexturedModel("lowPolyTree", "lowPolyTree", texturedModels, loader);


        //ERSTELLE ENTITIES
        //generateEntity(texturedModels.get(1-1), 15, 0, 15, 0, 180, 0, 1, entities);
        //generateEntity(texturedModels.get(3-1), 5, 0, 5, 0, 0, 0, 1, entities);
        //generateEntity(texturedModels.get(3-1), 23, 0, 8, 0, 90, 0, 0.7f, entities);


        //TEST REFLECTIVITY
        /*
        ModelTexture texture1 = entities.get(0).getModel().getTexture();
        texture1.setReflectivity(10f);
        texture1.setShineDamper(10);
        */

        //CREATE LIGHT
        Light light = new Light(new Vector3f(3000,2000,2000), new Vector3f(2.5f,2.5f,2.5f));

        //CREATE TERRAIN
        //generateTerrain(0, terrains);
        //generateTerrain(1, terrains);

        ////////////////////////////////////////////////////////////////////
        //WORLD EDITOR FENSTER
        ////////////////////////////////////////////////////////////////////

        //ERSTELLE FENSTER
        final JFrame f=new JFrame("Map Editor"); 

        //MENÜLEISTE
        JMenuBar menuBar;

        //MENÜS 
        JMenu fileMenu;         //FileMenu
        JMenu lightTerrainMenu;     //LightTerrain Menu
        JMenu modelMenu;        //ModelMenu

        //MENÜPUNKTE
        JMenuItem createNewWorld;   //New World
        JMenuItem saveWorld;        //Save
        JMenuItem loadWorld;        //Load
        JMenuItem addTree;          //AddTree
        JMenuItem addModel;         //Add Model
        JMenuItem close;            //Quit

        JMenuItem addTerrain;
        JMenuItem addLight;


        //CREATE MENUBAR
        menuBar = new JMenuBar();

        //CREATE MENUS
        fileMenu = new JMenu("File");
        lightTerrainMenu = new JMenu("Terrain/Light");
        modelMenu = new JMenu("Model");

        //CREATE MENUITEMS
        createNewWorld = new JMenuItem("New world");
        saveWorld = new JMenuItem("Save world");
        loadWorld = new JMenuItem("Load world");
        addTree = new JMenuItem("Add tree");
        addModel = new JMenuItem("Add model");
        close = new JMenuItem("Close");

        addTerrain = new JMenuItem("Add terrain");
        addLight = new JMenuItem("Add light");

        //ADD MENU ITEMS
        fileMenu.add(createNewWorld);
        fileMenu.add(saveWorld);
        fileMenu.add(loadWorld);
        fileMenu.add(close);

        lightTerrainMenu.add(addTerrain);
        lightTerrainMenu.add(addLight);

        modelMenu.add(addTree);
        modelMenu.add(addModel);


        //ADD MENUS TO MENU BAR
        menuBar.add(fileMenu);
        menuBar.add(lightTerrainMenu);
        menuBar.add(modelMenu);


        //ADD MENU TO FRAME
        f.add(menuBar, BorderLayout.NORTH);

        //CREATE WINDOW
        f.setSize(400, 300);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);  


        ////////////////////////////////////////////////////////////////////////////////////////////////
        //LISTENER LISTENER LISTENER LISTENER
        ////////////////////////////////////////////////////////////////////////////////////////////////


      //ADDTERRAIN LISTENR
        addTerrain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {

                final JFrame f2=new JFrame("Add Terrain");
                final JLabel l1 = new JLabel("Terrain can only be: 1x1, 2x2, 3x3...");
                final JLabel l2 = new JLabel("e.g. if you enter 2 it will be a 2x2 terrain");
                Button b1=new Button("Create Terrain"); 
                final TextField tfield = new TextField("", 1);
                l1.setBounds(50, 10, 250, 30);
                l2.setBounds(50, 40, 250, 30);
                tfield.setBounds(50, 70, 130, 30);  
                b1.setBounds(50,100,120,30);  


                b1.addActionListener(new ActionListener(){  
                public void actionPerformed(ActionEvent e){  

                        String input= tfield.getText();
                        generateTerrain(1, terrains);

                }  
                });


                f2.add(b1);
                f2.add(l1);
                f2.add(l2);
                f2.add(tfield);

                f2.setSize(400,300);  
                f2.setLayout(null);

                f2.setVisible(true);

                }

        });

        //ADDMODEL LISTENER
        addModel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                final JFrame f1=new JFrame("Add Model");
                final JLabel l1 = new JLabel("NO MODEL");
                final JLabel l2 = new JLabel("NO TEXTURE");
                l1.setBounds(100, 30, 120, 30);
                l2.setBounds(250, 30, 120, 30);
                /////////////////////////
                //BUTTON ADD MODEL
                /////////////////////////
                Button b1=new Button("Choose model");  
                b1.setBounds(50,100,120,30);  

                b1.addActionListener(new ActionListener(){  
                public void actionPerformed(ActionEvent e){  
                    //CREATE FILE CHOOSER
                    JFileChooser fc = new JFileChooser();
                    FileNameExtensionFilter filter = new FileNameExtensionFilter("Object Dateien", "obj");
                    fc.setFileFilter(filter);
                    int returnVal = fc.showOpenDialog(null);
                    if(returnVal == JFileChooser.APPROVE_OPTION) {
                       System.out.println("You added the following model to your model library: " + fc.getSelectedFile().getName());
                       String currentLine = fc.getSelectedFile().getName();
                       System.out.println(currentLine);

                       String[] parts = currentLine.split("\\.");

                       String part1 = parts[0];
                       l1.setText(part1);
                    }  

                }  
                });

                /////////////////////////
                //BUTTON ADD TEXTURE
                /////////////////////////
                Button b2=new Button("Choose texture");  
                b2.setBounds(200,100,120,30);  

                b2.addActionListener(new ActionListener(){  
                    public void actionPerformed(ActionEvent e){  
                        //CREATE FILE CHOOSER
                        JFileChooser fc = new JFileChooser();
                        FileNameExtensionFilter filter = new FileNameExtensionFilter("Texture Dateien", "png");
                        fc.setFileFilter(filter);
                        int returnVal = fc.showOpenDialog(null);
                        if(returnVal == JFileChooser.APPROVE_OPTION) {
                            System.out.println("You added the following texture to your model: " + fc.getSelectedFile().getName());
                            String currentLine = fc.getSelectedFile().getName();
                            System.out.println(currentLine);

                            String[] parts = currentLine.split("\\.");

                            String part1 = parts[0];
                            l2.setText(part1);
                        }  

                    }  
                });
               Button b3=new Button("Add Model");  
                b3.setBounds(150,150,120,30);  

                b3.addActionListener(new ActionListener(){  
                    public void actionPerformed(ActionEvent e){  

                        l1.getText();
                        l2.getText();
                        //loadTexturedModel("lowPolyTree", "lowPolyTree", texturedModels, loader);
                        }  


                });


                f1.add(b1);
                f1.add(b2);
                f1.add(b3);
                f1.add(l1);
                f1.add(l2);
                f1.setSize(400,300);  
                f1.setLayout(null);

                f1.setVisible(true);

                }
        });
        //ADDTREE LISTENR
        addTree.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                //TREE

                generateEntity(texturedModels.get(3-1), 0, 0, 0, 0, 0, 0, 1, entities);
            }
        });

        //CLOSE LISTENER
        close.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                //Programm schließen

                int result = JOptionPane.showConfirmDialog((Component) null, "Unsaved changes will be lost!","Quit world editor?", JOptionPane.YES_NO_OPTION);
                if(result==0)
                System.exit(0);
            }
        });





        //////////////////////////////////////////////////////////////////////
        ////MAIN GAME LOOP
        /////////////////////////////////////////////////////////////////////
        while(!Display.isCloseRequested()){

            renderer.render(light, camera);
            DisplayManager.updateDisplay();

            camera.move();

            for(Terrain terr:terrains){
                renderer.processTerrain(terr);
            }

            for(Entity ent:entities){
                renderer.processEntity(ent);
            }


        }
        //////////////////////////////////////////////////////////////////////
        ////END MAIN GAME LOOP
        /////////////////////////////////////////////////////////////////////

        //CLEANUP
        renderer.cleanUp();
        loader.cleanUp();
        DisplayManager.closeDisplay();
    }


    public static void loadTexturedModel(String modelName, String textureName, List<TexturedModel> texturedModels){

        texturedModels.add( new TexturedModel(OBJLoader.loadObjModel(modelName,
                loader), new ModelTexture(loader.loadTexture(textureName))));
    }

    public static void generateEntity(TexturedModel model, int posX, int posY, int posZ,
            float rotX, float rotY, float rotZ, float scale, List<Entity> entities){

        entities.add(new Entity(model, new Vector3f(posX,posY,posZ), rotX, rotY, rotZ, scale));
    }
    public static void generateTerrain(int size, List<Terrain> terrains){
        terrains.add(new Terrain(size, 0, loader, new ModelTexture(loader.loadTexture("grass"))));
    }

    public static void genTexturedModel(String name1, String name2, List texturedModels){
        loadTexturedModel("lowPolyTree", "lowPolyTree", texturedModels);
    }



}




推荐答案

首先,要了解实际问题:当OpenGL上下文在调用线程中是最新的时,可以发出OpenGL调用。 OpenGL使用线程本地存储来跟踪任何线程的当前上下文。您创建的LWJGL 2显示的OpenGL上下文将在调用Display.create()的Thread中是最新的,它可能位于主线程调用的未公开DisplayManager类中的某个位置。另一方面,AWT(和Swing到那个程度)使用单独的专用线程来处理窗口消息事件,例如单击按钮,并将使用该线程调用事件回调。并且LWJGL显示的OpenGL上下文在AWT事件线程中不是最新的。

First, to understand the actual problem: OpenGL calls can ony be issued when an OpenGL context is current in the calling Thread. OpenGL uses thread-local storage to keep track of which context is current for any Thread. The OpenGL context of the LWJGL 2 Display you created will be current in the Thread that called Display.create(), which was probably somewhere in your undisclosed DisplayManager class called by the main Thread. AWT (and Swing to that extent) on the other hand uses a separate dedicated Thread to process window message events, such as the click of a button, and will use that Thread to call into your event callbacks. And the OpenGL context of the LWJGL Display will not be current in that AWT Event Thread.

我的建议:创建一个渲染命令队列(可能是java.lang的实例)。 Runnable)将被轮询并且包含的​​渲染命令由Thread处理,其中LWJGL Display OpenGL上下文是最新的并且让你的AWT回调向该队列发出渲染命令。

My advice: Create a queue of rendering commands (possibly instances of java.lang.Runnable) which will be polled and the contained render commands processed by the Thread in which the LWJGL Display OpenGL context is current and have your AWT callbacks issue rendering commands into that queue.

这篇关于如何将OpenGL上下文放入我当前的线程中,找不到opengl上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆