2010-09-28 2 views
2

Я пытаюсь отобразить текст в моем приложении OpenGL/JOGL. Вот некоторые из кода:Сложность с текстом в JOGL

private void display(GLAutoDrawable drawable) { 
    GL2 gl = drawable.getGL().getGL2(); 
    GLUgl2 glu = new GLUgl2(); 

    float[] rgba = new float[4]; 
    backgroundColor.getRGBComponents(rgba); 
    gl.glClearColor(rgba[0], rgba[1], rgba[2], 1); 
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 

    gl.glMatrixMode(GL2.GL_MODELVIEW); 
    gl.glLoadIdentity(); 


    // Position the camera 
    glu.gluLookAt(cameraPos.x, cameraPos.y, cameraPos.z, cameraPos.x + cameraForward.x, cameraPos.y + cameraForward.y, 
      cameraPos.z + cameraForward.z, cameraUp.x, cameraUp.y, cameraUp.z); 

    gl.glPushMatrix(); 
    GLUT glut = new GLUT(); 
    gl.glTranslatef(0, 0, 0); 
    gl.glColor3f(1, 0, 0); 
    glut.glutBitmapString(GLUT.BITMAP_HELVETICA_18, "We're going to the moon!"); 
    gl.glPopMatrix(); 

    // ... 

текст появляется, как только начинается рендеринг, а затем убегает правую часть экрана. Почему это происходит?

Я бы хотел показать текст перед пользователем, а не как модель в мире.

ответ

3

Перед вызовом glutBitmapString необходимо установить текущее растровое положение. Растровое положение - это пиксель, в котором начнется рисование строки. Вы можете установить его, используя семейство функций glRasterPos.... Причина, по которой ваш текст «убегает» в правой части экрана, заключается в том, что вызов glutBitmapString неявно перемещает растровое положение в конец строки (см. here).

+0

Хорошо, это похоже на работу, и текст рисуется в каком-то месте в мире. Теперь, как я могу заставить его рисоваться в той же точке на экране пользователя, независимо от ориентации камеры? –

+1

Ах, я забыл, что растровое положение преобразуется, как вершина, если вы укажете его таким образом. Вам может понадобиться 'glWindowPos' (http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml) –

+0

Человек, вы экономите свое время! – kristyna

1

Существует очень простое решение, но оно «связывает» ваше приложение с awt, что может быть плохо, если вы попытаетесь держаться подальше от него в пользу тритона.

Ниже приведен пример проигрывателя osd с использованием количества средств визуализации текста: один для символа воспроизведения/паузы, еще один для некоторой информации, такой как время и т. Д., И еще один для названия фильма.

import com.jogamp.opengl.util.awt.TextRenderer; 

    private static final Color DROP_SHADOW_COLOR = new Color(0, 0, 0, 0.5f); 

    class CustomRenderDelegate implements TextRenderer.RenderDelegate { 
     private int dropShadowDepth; 
     private Color color; 

     CustomRenderDelegate(int dropShadowDepth, Color color) { 
      this.dropShadowDepth = dropShadowDepth; 
      this.color = color; 
     } 

     public boolean intensityOnly() { 
      return false; 
     } 

     public Rectangle2D getBounds(CharSequence str, Font font, FontRenderContext frc) { 
      return getBounds(str.toString(), font, frc); 
     } 

     public Rectangle2D getBounds(String str, Font font, FontRenderContext frc) { 
      return getBounds(font.createGlyphVector(frc, str), frc); 
     } 

     public Rectangle2D getBounds(GlyphVector gv, FontRenderContext frc) { 
      Rectangle2D stringBounds = gv.getPixelBounds(frc, 0, 0); 
      return new Rectangle2D.Double(stringBounds.getX(), stringBounds.getY(), stringBounds.getWidth() 
        + dropShadowDepth, stringBounds.getHeight() + dropShadowDepth); 
     } 

     public void drawGlyphVector(Graphics2D graphics, GlyphVector str, int x, int y) { 
      graphics.setColor(DROP_SHADOW_COLOR); 
      graphics.drawGlyphVector(str, x + dropShadowDepth, y + dropShadowDepth); 
      graphics.setColor(color); 
      graphics.drawGlyphVector(str, x, y); 
     } 

     public void draw(Graphics2D graphics, String str, int x, int y) { 
      graphics.setColor(DROP_SHADOW_COLOR); 
      graphics.drawString(str, x + dropShadowDepth, y + dropShadowDepth); 
      graphics.setColor(color); 
      graphics.drawString(str, x, y); 
     } 
    } 

    public void init(GLAutoDrawable drawable) { 
      ... 
      pathRenderer = new TextRenderer(new Font("Helvetica", Font.ITALIC, 16), true, true, new CustomRenderDelegate(0, 
       Color.WHITE)); 
     pathRenderer.setSmoothing(true); 

     playRenderer = new TextRenderer(new Font("Helvetica", Font.BOLD, 65), true, true, new CustomRenderDelegate(0, 
       Color.WHITE)); 
     pauseRenderer = new TextRenderer(new Font("Helvetica", Font.BOLD, 50), true, true, new CustomRenderDelegate(0, 
       Color.WHITE)); 

     osdRenderer = new TextRenderer(new Font("Helvetica", Font.PLAIN, 32), true, true, new CustomRenderDelegate(0, 
       Color.WHITE)); 
     osdRenderer.setSmoothing(true); 
    } 

    private final void updateOsd() { 
     Time t = currentFrame != null ? currentFrame.getTime() : new Time(0, 0, 0, 0, 0); 
     String direction = video.direction == DirectionType.DIRECTION_LEFT ? "<" : ">"; 
     String frameNumber = enterFrameNumber != null ? String.format("[%s]", enterFrameNumber) 
       : String.format("(%d)", t.fn); 
     osdText = String.format(" %s%s x %d @ %.2f fps < %d/%d (%s) @ %d fps", TimeUtil.hmsms(t.getPtsMillis()), frameNumber, (int) video.getPlaybackRate(), playbackFps, video.readyFrames(), maxFrames, direction, video.getFilterFps()); 
    } 

    private void renderOsd(GLAutoDrawable drawable) { 
     updateOsd(); 

     if (isOsdEnabled) { 
      maxModeWidth = (int) Math.max(maxModeWidth, playRenderer.getBounds("\u25B8").getWidth()); 
      maxOsdHeight = (int) Math.max(maxOsdHeight, playRenderer.getBounds("\u25B8").getHeight()); 

      if (isPaused) { 
       pauseRenderer.beginRendering(drawable.getWidth(), drawable.getHeight()); 
       pauseRenderer.draw("\u2759", 10, drawable.getHeight() - maxOsdHeight - 2); 
       int barWidth = (int) pauseRenderer.getBounds("\u2759").getWidth(); 
       pauseRenderer.draw("\u2759", 10 + barWidth - 3, drawable.getHeight() - maxOsdHeight - 2); 
       pauseRenderer.flush(); 
       pauseRenderer.endRendering(); 
      } else { 
       playRenderer.beginRendering(drawable.getWidth(), drawable.getHeight()); 
       playRenderer.draw("\u25B8", 10, drawable.getHeight() - maxOsdHeight - 5); 
       playRenderer.flush(); 
       playRenderer.endRendering(); 
      } 

      int y = (int) ((maxOsdHeight + 10) - osdRenderer.getBounds(osdText).getHeight()/2); 
      osdRenderer.beginRendering(drawable.getWidth(), drawable.getHeight()); 
      osdRenderer.draw(osdText, maxModeWidth + 18, drawable.getHeight() - y - 2); 
      osdRenderer.flush(); 
      osdRenderer.endRendering(); 

      if (isFullScreen) { 
       pathRenderer.beginRendering(drawable.getWidth(), drawable.getHeight()); 
       pathRenderer.draw(videoFile.getName(), 18, drawable.getHeight() - y - maxOsdHeight + 15); 
       pathRenderer.flush(); 
       pathRenderer.endRendering(); 
      } 
     } 
    } 


    public void display(GLAutoDrawable drawable) { 
     GL gl = drawable.getGL(); 
     gl.glClear(GL.GL_COLOR_BUFFER_BIT); 
     gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
     renderFrame(drawable); 
     renderOsd(drawable); 
     gl.glFinish(); 
    }