首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何绘制一个GLCanvas?

如何绘制一个GLCanvas?
EN

Stack Overflow用户
提问于 2017-03-16 03:27:34
回答 2查看 750关注 0票数 2

我希望在3D OpenGL视图上绘制一个HUD,但是似乎在我的面板中完成的任何绘图都会被忽略,尽管它已经完成了。

这是一些基本代码。

MyFrame;

代码语言:javascript
复制
public class MyFrame extends JFrame{
    private static final long serialVersionUID = 1L;
    public MyFrame(Labyrinth l){
        super();
        this.setTitle("My Frame");
        this.setSize(512, 384);
        this.setContentPane(new MyPanel());
        //this.setVisible(true);//If needed here.
    }
}

MyPanel;

代码语言:javascript
复制
public class MyPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    public MyPanel(){
        super();
        this.setLayout(new BorderLayout());
        MyCanvas mc=new MyCanvas(l);
        mc.setFocusable(false);
        this.add(this.mc, BorderLayout.CENTER);
        //this.revalidate();//Doesn't seem needed in the instanciation.
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        this.mc.repaint();
        g.setColor(new Color(128,128,128));
        g.fillRect(0, 0, this.getWidth()/2,this.getHeight()/2); 
        //top-left quarter should be greyed away.
    }
}

MyCanvas;

代码语言:javascript
复制
public class MyCanvas extends GLCanvas{
    private static final long serialVersionUID = 1L;
    public MyCanvas(){
        super(new GLCapabilities(GLProfile.getDefault()));
    }
}

这幅画正在进行中,但没有在视图中显示出来。我已经尝试过重写重画图()、画图(图形)、paintComponent(图形)和update()。有人说,在“重量级”部件上进行绘画是很复杂的,我要么直接在组件中画,要么使用另一种类型。我显然需要GLCanvas来显示3D渲染,同时它似乎不提供绘制覆盖层的工具。有人告诉我只需在JFrame的glassPane中画我的画,但是这似乎有点过火了,而且有人告诉我不要在glassPane上玩,所以我不打算这么做。

我在绘画中看到了许多主题,但我无法确定在重写这样或那样的方法时哪一个是正确的,我甚至不知道是否或哪种方法应该覆盖。是否有一种明显的方式,我会错过让我的简单JPanel绘画显示在它的GLCanvas组件上?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-16 09:49:11

首先,我真的不建议通过这些方法获得HUD。正如我所能想象的那样,这很伤人的表现。当然,我从来没有尝试过像这样混合Java、OpenGL和AWT的图形。

现在,不要使用将这些类与管道胶带放在一起的方法,而是考虑使用JLayeredPane

代码语言:javascript
复制
JLayeredPane layeredPane = new JLayeredPane();

layeredPane.add(new MyCanvas());
layeredPane.add(new MyPanel());

frame.add(layeredPane);

现在,重要的是您必须手动设置两个组件的界限:

代码语言:javascript
复制
canvas.setBounds(x, y, width, height);
panel.setBounds(x, y, width, height);

如果没有,您最终会遇到与以前相同的问题:

这幅画正在进行中,但未在视图中显示

为了演示它是否有效,我创建了这个类似于您的TestPanel的小型MyPanel类。

代码语言:javascript
复制
public static class TestPanel extends JPanel {
    private Color color;

    public TestPanel(Color color) {
        this.color = color;
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(color);
        g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
    }
}

然后创建两个实例,如下所示:

代码语言:javascript
复制
JPanel panel1 = new TestPanel(new Color(255, 0, 0));
panel1.setBounds(25, 25, 100, 100);

JPanel panel2 = new TestPanel(new Color(0, 0, 255));
panel2.setBounds(75, 75, 100, 100);

然后将它们添加到JLayeredPane中,并将其添加到JFrame中,我们可以看到以下内容:

票数 1
EN

Stack Overflow用户

发布于 2019-08-08 08:41:04

我发现使用JFrame玻璃面板是一个很好的解决方案,我用它在3D图形之上绘制调试文本,我没有遇到任何问题。使用玻璃面板方法比使用JLayeredPane更方便,因为3D面板的调整将为您处理。注意,3D图形必须在GLJPanel组件中绘制,否则分层不能工作(相对于不是Swing组件的GLCanvas )。paintComponent(Graphics g)将以与GLJPanel的帧速率相同的速率调用.请注意,默认情况下,玻璃窗格是隐藏的,因此必须在其上调用setVisible(true)

代码语言:javascript
复制
import javax.swing.JFrame;
import com.jogamp.opengl.awt.GLJPanel;
// ...

public class ApplicationWindow extends JFrame {
  public ApplicationWindow(String title) {
    super(title);    
    GLCapabilities gl_profile = new GLCapabilities(GLProfile.getDefault());
    GLJPanel gl_canvas = new GLJPanel(gl_profile);
    // ... code here to draw the graphics (supply a GLEventListener to gl_canvas)

    setContentPane(gl_canvas);
    StatusTextOverlayPanel myGlassPane = new StatusTextOverlayPanel();
    setGlassPane(myGlassPane);
    myGlassPane.setVisible(true);
    setVisible(true);
  }

  class StatusTextOverlayPanel extends JComponent {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      g2d.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
      g2d.setPaint(Color.BLACK);
      String statusText = String.format("C-elev: %.2f S-view %.2f D-view %.2f", 1459.0, 17.0, 2.574691);
      g2d.drawString(statusText, 10, 20);
    }
  }
}

下面是一个示例,说明它可能是什么样子(您需要额外的代码来绘制轴和所示的正方形)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42824765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档