OpenGL:在3D场景中以2D方式绘制文本?

时间:2011-06-04 15:49:36

标签: java opengl fonts lwjgl

当我尝试在我的3D场景中显示文字时,它不会显示场景的其余部分。我该怎么做才能解决这个问题?我在这里尝试了答案:Opengl drawing a 2d overlay on a 3d scene problem但它对我不起作用。这是我的代码:

public class GunCraft {
    private boolean done = false;
    Texture texture;
    Camera cam;
    private float yspeed;
    float legAngle;
    float playerX = 0;
    float playerZ = 0;
    float playerSpeed = 0.01f;
    float enemyX = 0;
    float enemyZ = 0;
    private TrueTypeFont font2;


    public static void main(String args[]) {
        GunCraft gc = new GunCraft();
        gc.run();
    }

    public void run() {
        try {
            init();
            while (!done) {
                mainloop();
                render();
                Display.update();
            }
            cleanup();
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    /**
     * Very basic for first lesson.  Just check for escape key or user
     * clicking to close the window.
     */
    private void mainloop() {
        if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {       // Exit if Escape is pressed
            done = true;
        }
        if(Display.isCloseRequested()) {                     // Exit if window is closed
            done = true;
        }
    }

    /**
     * For rendering all objects to the screen
     * @return boolean for success or not
     */
    private void render() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer
        font2.drawString(100, 100, "NICE LOOKING FONTS!", Color.green);

        loadIdentity();
        //GL11.glRotatef(yspeed,0.0f,1.0f,0.0f);
        drawRect(texture, 1f, 1f, 1f);


    }

    public void loadIdentity(){
        GL11.glLoadIdentity();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        float camAngle = (float) Math.atan2(playerX, playerZ);
        float radius = 5;
        GLU.gluLookAt(playerX + (float)(Math.sin(camAngle) * radius), 0, playerZ + (float)(Math.cos(camAngle) * radius), 0, 0, 0, 0, 1, 0); 
        //GL11.glGetMatrix();
    }

    public void drawRect(Texture texture, float width, float height, float depth){
        texture.bind();
        GL11.glBegin(GL11.GL_QUADS);                            // Start Drawing Quads
            // Front Face
            GL11.glNormal3f( 0.0f, 0.0f, 1.0f);                 // Normal Pointing Towards Viewer
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(-width, -height, depth);    // Point 1 (Front)
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f( width, -height,  depth);    // Point 2 (Front)
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f( width,  height,  depth);    // Point 3 (Front)
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(-width,  height,  depth);    // Point 4 (Front)
            // Back Face
            GL11.glNormal3f( 0.0f, 0.0f,-1.0f);                 // Normal Pointing Away From Viewer
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f(-width, -height, -depth);    // Point 1 (Back)
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f(-width,  height, -depth);    // Point 2 (Back)
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f( width,  height, -depth);    // Point 3 (Back)
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f( width, -height, -depth);    // Point 4 (Back)
            // Top Face
            GL11.glNormal3f( 0.0f, 1.0f, 0.0f);                 // Normal Pointing Up
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(-width,  height, -depth);    // Point 1 (Top)
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(-width,  height,  depth);    // Point 2 (Top)
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f( width,  height,  depth);    // Point 3 (Top)
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f( width,  height, -depth);    // Point 4 (Top)
            // Bottom Face
            GL11.glNormal3f( 0.0f,-1.0f, 0.0f);                 // Normal Pointing Down
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f(-width, -height, -depth);    // Point 1 (Bottom)
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f( width, -height, -depth);    // Point 2 (Bottom)
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f( width, -height,  depth);    // Point 3 (Bottom)
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f(-width, -height,  depth);    // Point 4 (Bottom)
            // Right face
            GL11.glNormal3f( 1.0f, 0.0f, 0.0f);                 // Normal Pointing Right
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f( width, -height, -depth);    // Point 1 (Right)
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f( width,  height, -depth);    // Point 2 (Right)
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f( width,  height,  depth);    // Point 3 (Right)
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f( width, -height,  depth);    // Point 4 (Right)
            // Left Face
            GL11.glNormal3f(-1.0f, 0.0f, 0.0f);                 // Normal Pointing Left
            GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(-width, -height, -depth);    // Point 1 (Left)
            GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f(-width, -height,  depth);    // Point 2 (Left)
            GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f(-width,  height,  depth);    // Point 3 (Left)
            GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(-width,  height, -depth);    // Point 4 (Left)
        GL11.glEnd();                                      // Done Drawing The Quad
    }

    /**
     * Create a window for all display
     * @throws Exception
     */
    private void createWindow() throws Exception {
        Display.setFullscreen(false);
        Display.setDisplayMode(new DisplayMode(640, 480));
        Display.setTitle("GunCraft - By William Starkovich");
        Display.create();
    }

    /**
     * Initialize the environment
     * @throws Exception
     */
    private void init() throws Exception {
        createWindow();
        try{
            FileInputStream fis;
            fis = new FileInputStream(new File("font.ttf"));

            Font awtFont2 = Font.createFont(Font.TRUETYPE_FONT, fis);
            awtFont2 = awtFont2.deriveFont(24f); // set font size
            font2 = new TrueTypeFont(awtFont2, false);

        } catch (Exception e) {
            e.printStackTrace();
        }

        initGL(640,480);
    }

    /**
     * Initialize OpenGL
     *
     */
    private void initGL(int width, int height) {
        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
        GL11.glClearDepth(1.0); // Depth Buffer Setup
        GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
        GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
        GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
        GL11.glLoadIdentity(); // Reset The Projection Matrix

        // Calculate The Aspect Ratio Of The Window
        GLU.gluPerspective(
          45.0f,
          (float) Display.getDisplayMode().getWidth() / (float) Display.getDisplayMode().getHeight(),
          0.1f,
          100.0f);

        //GLU.gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz)

        GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix

        // Really Nice Perspective Calculations
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);                                    

        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, width, height, 0, -1000, 1000);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glDisable(GL11.GL_CULL_FACE);

        try {
            texture  = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("tex.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }

    /**
     * Cleanup all the resources.
     *
     */
    private void cleanup() {
        Display.destroy();
    }

}

1 个答案:

答案 0 :(得分:4)

你应该仔细研究OpenGL是如何工作的,你的代码中有一堆截断的语句,以后会被覆盖几行。你必须得到“OpenGL是状态机”的意思。如果你不想处理它,你应该找到一个更抽象的游戏引擎来处理所有的绘制调用。

我只是将你的render()和loadIdentity()方法复制到工作中,但这不是真正的解决方案。 (每帧重新创建投影矩阵而不是保存/加载它们并不聪明)。 OpenGL 1.1也非常不赞成,强烈建议不要使用立即模式。

private void render() {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer

    loadIdentity();
    GL11.glRotatef(yspeed++,0.0f,1.0f,0.0f);
    drawRect(texture, 1f, 1f, 1f);

    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, 640, 480, 0, -1000, 1000);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();

    font2.drawString(100, 100, "NICE LOOKING FONTS!", Color.green);

}

public void loadIdentity(){
    GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
    GL11.glLoadIdentity(); // Reset The Projection Matrix

    // Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(
      45.0f,
      (float) Display.getDisplayMode().getWidth() / (float) Display.getDisplayMode().getHeight(),
      0.1f,
      100.0f);


    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    float camAngle = (float) Math.atan2(playerX, playerZ);
    float radius = 5;
    GLU.gluLookAt(playerX + (float)(Math.sin(camAngle) * radius), 0, playerZ + (float)(Math.cos(camAngle) * radius), 0, 0, 0, 0, 1, 0);
    //GL11.glGetMatrix();
}