worldwind学习笔记-2-WorldWindowGLCanvas

来源:互联网 发布:免费下载淘宝网2016 编辑:程序博客网 时间:2024/05/16 19:46

Configuration还有一些属性和方法,就不看了,主要功能都是得到配置文件中的值的作用,唯一一个我觉得值得说一下的是

  public static GLProfile getMaxCompatibleGLProfile()
    {
        return GLProfile.getMaxFixedFunc(true); // Favor a hardware rasterizer.
    }

用来得到OpenGL的版本号的。


Native[GL4bc true [4.2 (Compatibility profile, arb, ES2 compatible, FBO, hardware)], 

GL4 true [4.2 (Compatibility profile, arb, ES2 compatible, FBO, hardware)], 

GL3bc true [4.2 (Compatibility profile, arb, ES2 compatible, FBO, hardware)], 

GL3 true [4.2 (Compatibility profile, arb, ES2 compatible, FBO, hardware)], 

GL2 true [4.2 (Compatibility profile, arb, ES2 compatible, FBO, hardware)], 

GL2ES1 true, (ES主要是针对手机等设备的,我的台机居然也支持哦。好厉害的样子,不觉明历)

GLES1 false,

GL2ES2 true,

GLES2 false]

下面要回到主程序Hellow中了,代码在第一次调用Configuration的时候,就保证了Configuration读取了config/worldwind.xml中的所有配置文件,然后,他就开始产生窗体了——AppFrame,然后看一下AppFrame的构造函数,蛮简单的

private static class AppFrame extends javax.swing.JFrame    {        public AppFrame()        {                 this.setDefaultCloseOperation(EXIT_ON_CLOSE);            WorldWindowGLCanvas wwd = new WorldWindowGLCanvas();            wwd.setPreferredSize(new java.awt.Dimension(1000, 800));            this.getContentPane().add(wwd, java.awt.BorderLayout.CENTER);                         wwd.setModel(new BasicModel());            this.pack();        }    }

第一句不说了,第二句产生了一个wwd,然后将wwd放到了当前frame的CENTER的位置,因为BorderLayout的原因,填充满然后居中,之后给wwd设置了一个model,就是BasicModel。。这里是有一个Gobe控制球,Model定义模型的,不详说,概念在worldwind的介绍里有的。地址:http://goworldwind.org/

那就从第一个WorldWindowGLCanvas 开始吧,F3跟进。

可以看到代码了,到这一层就足够了,不要再跟他的父类GLCanvas内的实现了,那是Jogl的内容了,JOGL的详细内容可以百度下,基于他的应用请移步http://jogamp.org/jogl/www/

对于OpenGL的学习的话,红宝书蓝宝书根本没时间看,我打算看看人家推荐的Nehe的教程。

先看构造函数:

  /** Constructs a new <code>WorldWindowGLCanvas</code> on the default graphics device. */    public WorldWindowGLCanvas()    {        super(getCaps());        try        {            this.wwd = ((WorldWindowGLDrawable) WorldWind.createConfigurationComponent(AVKey.WORLD_WINDOW_CLASS_NAME));            this.wwd.initDrawable(this);            this.wwd.initGpuResourceCache(WorldWindowImpl.createGpuResourceCache());            this.createView();            this.createDefaultInputHandler();            WorldWind.addPropertyChangeListener(WorldWind.SHUTDOWN_EVENT, this);            this.wwd.endInitialization();        }        catch (Exception e)        {            String message = Logging.getMessage("Awt.WorldWindowGLSurface.UnabletoCreateWindow");            Logging.logger().severe(message);            throw new WWRuntimeException(message, e);        }    }

第一句是super的方法调用一个protected的getCaps()方法,该方法返回一个GLCapabilities,用来初始化系统

  protected static GLCapabilities getCaps()    {        GLCapabilities caps = new GLCapabilities(Configuration.getMaxCompatibleGLProfile());        caps.setAlphaBits(8);        caps.setRedBits(8);        caps.setGreenBits(8);        caps.setBlueBits(8);        caps.setDepthBits(24);        caps.setDoubleBuffered(true);        // Determine whether we should request a stereo canvas        String stereo = System.getProperty(AVKey.STEREO_MODE);        if ("device".equals(stereo))            caps.setStereo(true);        return caps;    }
可以轻松的看到,RGB的值,深度值,透明度的值以及双缓冲开启。

之后给wwd初始化,wwd是

 /** The drawable to which {@link WorldWindow} methods are delegated. */    protected final WorldWindowGLDrawable wwd; // WorldWindow interface delegates to wwd

这么定义的,是WorldWindow的委托,其实基本上所有的方法调用都是从WorldWindow继承来的,用来实现这个接口。

不要被名字搞混了,WorldWindow是一个接口,而WorldWind是一个final类,里面有很多方法。

wwd是被WorldWind的createConfigurationComponent方法初始化的,这个createConfigurationComponent是一个蛮牛的东西,至少在我这样子的java菜鸟看来,是的。

public static Object createConfigurationComponent(String classNameKey)        throws IllegalStateException, IllegalArgumentException    {        if (classNameKey == null || classNameKey.length() == 0)        {            Logging.logger().severe("nullValue.ClassNameKeyNullZero");            throw new IllegalArgumentException(Logging.getMessage("nullValue.ClassNameKeyNullZero"));        }        String name = Configuration.getStringValue(classNameKey);        if (name == null)        {            Logging.logger().log(Level.SEVERE, "WorldWind.NoClassNameInConfigurationForKey", classNameKey);            throw new WWRuntimeException(                Logging.getMessage("WorldWind.NoClassNameInConfigurationForKey", classNameKey));        }        try        {            return WorldWind.createComponent(name.trim());        }        catch (Throwable e)        {            Logging.logger().log(Level.SEVERE, "WorldWind.UnableToCreateClassForConfigurationKey", name);            throw new IllegalStateException(                Logging.getMessage("WorldWind.UnableToCreateClassForConfigurationKey", name), e);        }    }

错误处理比较完备,然后通过上一节的Configuration得到xml中的配置的值,然后根据名字,调用WorldWind.createComponent方法,

public static Object createComponent(String className) throws WWRuntimeException    {        if (className == null || className.length() == 0)        {            Logging.logger().severe("nullValue.ClassNameIsNull");            throw new IllegalArgumentException(Logging.getMessage("nullValue.ClassNameIsNull"));        }        try        {            Class c = Class.forName(className.trim());            return c.newInstance();        }        catch (Exception e)        {            Logging.logger().log(Level.SEVERE, "WorldWind.ExceptionCreatingComponent", className);            throw new WWRuntimeException(Logging.getMessage("WorldWind.ExceptionCreatingComponent", className), e);        }        catch (Throwable t)        {            Logging.logger().log(Level.SEVERE, "WorldWind.ErrorCreatingComponent", className);            throw new WWRuntimeException(Logging.getMessage("WorldWind.ErrorCreatingComponent", className), t);        }    }

WorldWind.createComponent方法里面是一个类加载器,错误处理也很完备,然后使用Class.forName按照名字查找类,然后用Class的newInstance()方法产生对象,

百度了下http://www.cnblogs.com/wjkaola123/archive/2009/11/23/1609119.html 别人介绍Class.forName的,比较详细,涉及到JVM等。(我不用谷歌是因为百度能查到的情况下翻墙会显得麻烦,给谷歌的前面加https也是不错的方法,百度查不到的谷歌能查到,只是我的网络环境原因,所以用百度的)

加载时使用了AVKey.WORLD_WINDOW_CLASS_NAME的值,正好用到AVKey了,AVKey可和AV没关系啊,它是一个键值对的集合,里面全是final String值,就和字典差不多,这里的值用来和xml对接的,比如WORLD_WINDOW_CLASS_NAME的值就是gov.nasa.worldwind.avkey.WorldWindowClassName,到xml文件里,可以找到它的值是gov.nasa.worldwind.WorldWindowGLAutoDrawable,不用问了,这个才是WorldWindowGLDrawable声明的wwd的真正实现类。

不管他,3里面在看Drawable,现在还在做画布呢,wwd相当于画笔吗?

之后wwd再initDrawable下,将当前的画布添加进去,当前的GLCanvas最终是继承GLDrawable的。

在之后给wwd一个初始化的GPU内存,不看WorldWindImpl里面的内用了,就是产生内存大小的。

在之后呢,它产生了一个View,View也是从配置文件读取后加载的,具体的实现类是gov.nasa.worldwind.view.orbit.BasicOrbitView

然后再来一个InputHandel,同上,gov.nasa.worldwind.awt.AWTInputHandler

这两个在产生后,都有一个set方法,但是set确实给wwd的,所以,下面进入wwd中,继续看代码。




原创粉丝点击