OpenGL 中的彩色文本

Colored text in OpenGL

我可以得到一个旋转的字母,但是不能给它上色。你能检查一下哪里出了问题吗?

unit frmMain;

interface

uses
  Winapi.Windows, Vcl.Forms, System.Classes, Vcl.ExtCtrls;

type
  TfrmGL = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private const
    GLF_START_LIST = 1;
    NUM_LISTS = 1;
  private
    _dc: HDC;
    _hrc: HGLRC;
    _ra: Single;
    procedure _setDCPixelFormat();
  protected
    procedure Paint(); override;
    procedure Resize(); override;
    procedure DoCreate(); override;
  public
    destructor Destroy(); override;
  end;

var
  frmGL: TfrmGL;

implementation

uses
  Winapi.OpenGL, Vcl.Graphics;

{$R *.DFM}

procedure TfrmGL.Paint();
const
  Litera: AnsiString = #0; //The "V" is the first and only symbol in the list, therefore index 0
begin
  inherited;
  glLoadIdentity();
  glTranslatef(0.0, 0.0, -6.0);
  glRotatef(10.0, 1.0, 0.0, 0.0); //Rotating through 10 degrees around axis X
  glRotatef(_ra, 0.0, 1.0, 0.0); // Rotating around axis Y
  glTranslatef(-0.35, 0.0, 0.1); // Make the letter rotate around its center
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glPushAttrib(GL_LIST_BIT);
  glListBase(GLF_START_LIST);
  glCallLists(1, GL_UNSIGNED_BYTE, PAnsiChar(Litera));
  glPopAttrib();
  SwapBuffers(_dc);
end;

procedure TfrmGL.Resize();
begin
  inherited;
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(15.0, ClientWidth / ClientHeight, 1.0, 20.0);
  glViewport(0, 0, ClientWidth, ClientHeight);
  glMatrixMode(GL_MODELVIEW);
  InvalidateRect(Handle, nil, False);
end;

procedure TfrmGL.Timer1Timer(Sender: TObject);
begin
  _ra := _ra - 0.5;
  if _ra < 0 then _ra := 360.0;
  InvalidateRect(Handle, nil, False);
end;

procedure TfrmGL._setDCPixelFormat();
var
  nPixelFormat: Integer;
  pfd: TPixelFormatDescriptor;
begin
  FillChar(pfd, SizeOf(pfd), 0);
  pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
  //pfd.cDepthBits := 32;
  nPixelFormat := ChoosePixelFormat(_dc, @pfd);
  SetPixelFormat(_dc, nPixelFormat, @pfd);
end;

destructor TfrmGL.Destroy();
begin
  glDeleteLists(GLF_START_LIST, NUM_LISTS);
  wglMakeCurrent(0, 0);
  wglDeleteContext(_hrc);
  ReleaseDC(Handle, _dc);
  DeleteDC(_dc);
  inherited;
end;

procedure TfrmGL.DoCreate();
begin
  inherited;
  _ra := 0;
  Canvas.Font.Style := [];
  Canvas.Font.Color := clRed;
  _dc := GetDC(Handle);
  _setDCPixelFormat();
  _hrc := wglCreateContext(_dc);
  wglMakeCurrent(_dc, _hrc);
  glClearColor(0.3, 0.4, 0.6, 1.0);
  glColor3f(1.0, 0.0, 0.0); //This does not have any effect
  //makeRasterFont;
  //p1 = graphical device context
  //p2 = from which character to start (86 = code of letter "V")
  //p3 = how many symbols to generate
  //p5 = letter 3D model precision (0 = as in the source font)
  //p6 = 3D depth of the letter
  wglUseFontOutlinesW(Canvas.Handle, 86, NUM_LISTS, GLF_START_LIST, 0, 0.15, WGL_FONT_POLYGONS, nil);
  //Light source initialization
  glEnable(GL_DEPTH_TEST); // Enable depth test
  glEnable(GL_LIGHTING); // Enable lighting
  glEnable(GL_LIGHT0); // Turn on the light source 0
end;

end.

点亮时(GL_LIGHTING) is enabled, then the color which is associated, is taken from the material parameters (glMaterial)。

如果您仍想使用当前颜色属性(由 glColor), then you have to enable GL_COLOR_MATERIAL 设置 并设置颜色 material 参数 (glColorMaterial):

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

另见 Basic OpenGL Lighting


由于漫反射光和镜面反射光取决于表面的法向量,因此必须设置与顶点关联的法向量属性 (glNormal)。
当然光参数glLight也必须设置。

我是你没有设置合适的参数,那我建议关闭灯光。跳过该行:

glEnable(GL_LIGHTING);

启用照明后,可以通过

再次禁用它
glDisable(GL_LIGHTING);