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);
由于漫反射光和镜面反射光取决于表面的法向量,因此必须设置与顶点关联的法向量属性 (glNormal
)。
当然光参数glLight
也必须设置。
我是你没有设置合适的参数,那我建议关闭灯光。跳过该行:
glEnable(GL_LIGHTING);
启用照明后,可以通过
再次禁用它
glDisable(GL_LIGHTING);
我可以得到一个旋转的字母,但是不能给它上色。你能检查一下哪里出了问题吗?
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);
由于漫反射光和镜面反射光取决于表面的法向量,因此必须设置与顶点关联的法向量属性 (glNormal
)。
当然光参数glLight
也必须设置。
我是你没有设置合适的参数,那我建议关闭灯光。跳过该行:
glEnable(GL_LIGHTING);
启用照明后,可以通过
再次禁用它glDisable(GL_LIGHTING);