【问题标题】:Display image in JOGL在 JOGL 中显示图像
【发布时间】:2012-11-26 11:48:04
【问题描述】:

我目前正在执行一项任务,我需要在 JOGL 中创建一个游戏,进展顺利,但我遇到了一个问题:

我想创建一个可以通过在游戏中按 ESC 访问的菜单功能,当按 ESC 时,显示功能需要停止显示游戏并开始显示菜单。菜单由带有一些文本覆盖的背景图像组成。

这就是我尝试实现菜单功能的方式,但我没有设法让它显示除清晰颜色之外的任何其他内容:

public class OptionsMenu 
{
    public void display(GL gl) {

        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(0, 300, 300, 0, 0, 1);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glDisable(GL.GL_DEPTH_TEST);
        gl.glClearColor(1f, 0.5f, 0.5f, 0.5f);  
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); 
        gl.glEnable (GL.GL_BLEND);
        BufferedImage bufferedImage = null;
        int w = 0;
        int h = 0;
        try {
            bufferedImage = ImageIO.read(OptionsMenu.class.getResource("menuBackground.jpg")); //The menu background
            w = ceilingPow2(bufferedImage.getWidth());
            h = ceilingPow2(bufferedImage.getHeight());
        } catch (IOException e) {
            e.printStackTrace();
        }
        WritableRaster raster = 
                Raster.createInterleavedRaster (DataBuffer.TYPE_BYTE,
                        w,
                        h,
                        4,
                        null);
        ComponentColorModel colorModel=
                new ComponentColorModel (ColorSpace.getInstance(ColorSpace.CS_sRGB),
                        new int[] {8,8,8,8},
                        true,
                        false,
                        ComponentColorModel.TRANSLUCENT,
                        DataBuffer.TYPE_BYTE);
        BufferedImage img = 
                new BufferedImage (colorModel,
                        raster,
                        false,
                        null);

        Graphics2D g = img.createGraphics();
        g.drawImage(bufferedImage, null, null);

        DataBufferByte imgBuf =
                (DataBufferByte)raster.getDataBuffer();
        byte[] imgRGBA = imgBuf.getData();
        ByteBuffer bb = ByteBuffer.wrap(imgRGBA);
        bb.position(0);
        bb.mark();

        gl.glBindTexture(GL.GL_TEXTURE_2D, 13);
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
        gl.glTexImage2D (GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, w, h, 0, GL.GL_RGBA, 
                GL.GL_UNSIGNED_BYTE, bb);

        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glBindTexture (GL.GL_TEXTURE_2D, 13);
        gl.glBegin (GL.GL_POLYGON);
        gl.glTexCoord2d (0, 0);
        gl.glVertex2d (0, 0);
        gl.glTexCoord2d(1,0);
        gl.glVertex2d (w, 0);
        gl.glTexCoord2d(1,1);
        gl.glVertex2d (w, h);
        gl.glTexCoord2d(0,1);
        gl.glVertex2d (0, h);
        gl.glEnd ();    
        gl.glFlush();
    }
    private static int ceilingPow2(int n) {
        int pow2 = 1;
        while (n > pow2) {
            pow2 = pow2<<1;
        }
        return pow2;
    }
}

此代码基于本教程:http://wiki.tankaar.com/index.php?title=Displaying_an_Image_in_JOGL_(Part_1)

我这样调用 OptionsMenu:

    public void display(GLAutoDrawable drawable) 
    {
        GL gl = drawable.getGL();
        GLU glu = new GLU();

        if(state.equals("optionsMenu"))
        {
            if(menu == null)
                menu = new OptionsMenu;

            menu.display(gl);
        } 
        else 
        {   
            // Calculating time since last frame.
            Calendar now = Calendar.getInstance();      
            long currentTime = now.getTimeInMillis();
            int deltaTime = (int)(currentTime - previousTime);
            previousTime = currentTime;

            // Update any movement since last frame.
            updateMovement(deltaTime);
            updateCamera();

            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
            gl.glLoadIdentity();
            glu.gluLookAt( camera.getLocationX(), camera.getLocationY(), camera.getLocationZ(), 
                    camera.getVrpX(), camera.getVrpY(), camera.getVrpZ(),
                    camera.getVuvX(), camera.getVuvY(), camera.getVuvZ() );

            // Display all the visible objects of MazeRunner.
            for( Iterator<VisibleObject> it = visibleObjects.iterator(); it.hasNext(); ) {
                it.next().display(gl);
            }

            gl.glLoadIdentity();
            gl.glFlush();
        }
    }

它不会抛出任何错误,只是不会显示图像。但是它确实显示了清晰的颜色 gl.glClearColor(1f, 0.5f, 0.5f, 0.5f);在OptionsMenu的显示函数中定义

我很困惑,我不知道我将如何解决这个问题。

很抱歉,这篇文章很长,但如果有人能帮助我,我将不胜感激。

【问题讨论】:

    标签: java image jogl


    【解决方案1】:

    我想清除颜色缓冲区gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT ); 应该放在OptionsMenu的显示方法的开头。

    我有一些建议,例如上面发布的代码:

    • 更改GLU glu = new GLU(); 的范围,因为每次调用opengl 显示回调方法时都会分配glu
    • 还将gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 移动到 if 语句之前,并且不要使用每个对象的显示方法(例如 OptionsMenu.display())。试着保持单身。
    • 使用 TextureIO 上传纹理,如果可能,只需上传一次,然后在显示方法中使用该纹理。纹理加载过程的开销很大。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多