I can get a rotating letter, but cannot color it. Could you check please what is wrong?
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.
When lighting (GL_LIGHTING
) is enabled, then the color which is associated, is taken from the material parameters (glMaterial
).
If you still want to use the current color attribute (which is set by glColor
), then you have to enable GL_COLOR_MATERIAL
and to set the color material paramters (glColorMaterial
):
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
See also Basic OpenGL Lighting.
Since the diffuse and specular light depends on the normal vector of the surface, the normal vector attribute (glNormal
) which is associated to the vertices, has to be set.
Of course the light parameters glLight
have to be set, too.
I've you don't have set the proper parameters, then I recommend to disable lighting. Skip the line:
glEnable(GL_LIGHTING);
Once lighting is enabled, the it can be disabled again by
glDisable(GL_LIGHTING);