OpenGL для начинающих
Falk0ner, вс, 06/07/2008 - 15:35.
Для ортогональной этого делать не надо - центр и так где-то перед нами.Другой способ задавать перспективную проекцию - это воспользоваться gluPerspective. Примечание: чем меньше расстояние между плоскостями отсечения, тем быстрее все считается. 05 Текструры============Текстуру сначала надо загрузить и получить ее идентификатор (хендл). перед созданием объекта текстура выбирается по своему идентификатору(делается текущей) и автоматом прилепляется к объекту (GLUquadricObj).
uses
OpenGL;
...
var
Texture: glUint;
...
// функция для установки текущей текстуры по идентификатору texture
// в openGL.pas ее почему то нет :(, потому импортируем
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
...
// Где-то вначале программы, перед использованием glDraw
LoadTexture('1.bmp', Texture);
...
{------------------------------------------------------------------}
{ Создание объектов под отрисовку }
{------------------------------------------------------------------}
procedure glDraw();
var
Obj : GLUquadricObj;
begin
...
// 1-ый вариант
glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture
Obj:=gluNewQuadric;
gluQuadricTexture(Obj, GL_TRUE); // при создании объекта наложить текущую текстуру
gluSphere(Obj, 100, 25, 25); // создать сферу R = 100, детализация - 25х25
...
или так
...
// 2-ой вариант
glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture
// Рисуем фигуру, на которую наложится текстура при помощи glTexCoord2f
glBegin(GL_QUADS);
glNormal3f( 0.0, 0.0, 1.0);
// 1-я точка текстуры + 1-я точка объекта
glTexCoord2f(0.0, 0.0);
glVertex3f(-100.0, -100.0, 0.0);
// 3-я точка текстуры + 2-я точка объекта
glTexCoord2f(1.0, 0.0);
glVertex3f( 100.0, -100.0, 0.0);
// 3-я точка текстуры + 3-я точка объекта
glTexCoord2f(1.0, 1.0);
glVertex3f( 100.0, 100.0, 0.0);
// 1-я точка текстуры + 1-я точка объекта
glTexCoord2f(0.0, 1.0);
glVertex3f(-100.0, 100.0, 0.0);
glEnd();
При этом должен быть разрешен режим наложения текстур (по умолчанию - отключен)
glEnable(GL_TEXTURE_2D);
Примечание:Функция MyOpenGL.glLoadTexture поддерживает загрузку только 8 и 24-битных изображений. Дополнительноwww.ru-coding.com/ogl_1_5.php06 Unit MyOpenGL.pas====================
OpenGL;
...
var
Texture: glUint;
...
// функция для установки текущей текстуры по идентификатору texture
// в openGL.pas ее почему то нет :(, потому импортируем
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
...
// Где-то вначале программы, перед использованием glDraw
LoadTexture('1.bmp', Texture);
...
{------------------------------------------------------------------}
{ Создание объектов под отрисовку }
{------------------------------------------------------------------}
procedure glDraw();
var
Obj : GLUquadricObj;
begin
...
// 1-ый вариант
glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture
Obj:=gluNewQuadric;
gluQuadricTexture(Obj, GL_TRUE); // при создании объекта наложить текущую текстуру
gluSphere(Obj, 100, 25, 25); // создать сферу R = 100, детализация - 25х25
...
или так
...
// 2-ой вариант
glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture
// Рисуем фигуру, на которую наложится текстура при помощи glTexCoord2f
glBegin(GL_QUADS);
glNormal3f( 0.0, 0.0, 1.0);
// 1-я точка текстуры + 1-я точка объекта
glTexCoord2f(0.0, 0.0);
glVertex3f(-100.0, -100.0, 0.0);
// 3-я точка текстуры + 2-я точка объекта
glTexCoord2f(1.0, 0.0);
glVertex3f( 100.0, -100.0, 0.0);
// 3-я точка текстуры + 3-я точка объекта
glTexCoord2f(1.0, 1.0);
glVertex3f( 100.0, 100.0, 0.0);
// 1-я точка текстуры + 1-я точка объекта
glTexCoord2f(0.0, 1.0);
glVertex3f(-100.0, 100.0, 0.0);
glEnd();
unit MyOpenGL;
interface
uses windows, OpenGL;
procedure glOnResize(Width, Height : Integer);
procedure glInit(Wnd: hWND);
procedure glKill(Wnd: hWND);
procedure glDraw();
procedure glLoadTexture(Filename: String; var Texture: GLuint);
implementation
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
function gluBuild2DMipmaps(Target: GLenum; Components, Width, Height: GLint; Format, atype: GLenum; Data: Pointer): GLint; stdcall; external glu32;
procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
procedure SetDCPixelFormat(DC: hDC); forward;
var
DC: hDC; // контекст устройства
RC: hGLRC; // контекст воспроизведения
Texture: GLuint; // хэндл текстуры
Angle: Integer = 0; // угол поворота сферы
{------------------------------------------------------------------}
{ Обработчик на изменение размеров окна }
{------------------------------------------------------------------}
procedure glOnResize(Width, Height: Integer);
begin
if (Height = 0) then Height := 1; // Предупреждаем деление на 0
glViewport(0, 0, Width, Height); // Устанавливаем область отображения
// на все окно
// Настройка матрицы проекции
glMatrixMode(GL_PROJECTION); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
// Устанавливаем тип проеции - Ортогональный
glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);
// Настройка видовой матрицы
glMatrixMode(GL_MODELVIEW); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
end;
{------------------------------------------------------------------}
{ Инициализация OpenGL }
{------------------------------------------------------------------}
procedure glInit(Wnd: hWND);
const
// Константы, задающие свойства материала фигур
mat1_amb : array [0..2] of Single = (0.2, 0.2, 0.2);
mat1_dif : array [0..2] of Single = (0.8, 0.8, 0.0);
mat1_spec: array [0..2] of Single = (0.6, 0.6, 0.6);
mat1_shininess = 10;
// Константы для источника света
light_pos : array [0..3] of glFloat = (100.0, 100.0, 0.0, 1.0);
light_amb : array [0..3] of glFloat = (0.6, 0.6, 0.6, 1.0);
light_dif : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
light_spec : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
light_spot_direction : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
// Цвет тумана
fogColor: array [0..3] of GLfloat = (0, 1.0, 0, 1.0);
var
fogMode: GLint;
begin
// Инициализация контекста воспроизведения OpenGL
DC := GetDC(Wnd); // Получить контекст устройства для окна
SetDCPixelFormat(DC); // Установить формата пикселов
RC := wglCreateContext(DC); // создать новый контекст воспроизведения
wglMakeCurrent(DC,RC); // Установить его текущим
// Свойства материала для режима glEnable(GL_COLOR_MATERIAL)
glMaterialfv(GL_FRONT, GL_AMBIENT, @mat1_amb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat1_dif);
glMaterialfv(GL_FRONT, GL_SPECULAR, @mat1_spec);
glMaterialf (GL_FRONT, GL_SHININESS,mat1_shininess);
// Свойства источника света GL_LIGHT1 для режима glEnable(GL_LIGHTING)
// Стандартный источник одна команда: glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_POSITION,@light_pos);
glLightfv(GL_LIGHT1, GL_AMBIENT, @light_amb); // направленность
glLightfv(GL_LIGHT1, GL_DIFFUSE, @light_dif); // рассеивание
glLightfv(GL_LIGHT1, GL_SPECULAR, @light_spec);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, @light_spot_direction);
// разрешить источник света GL_LIGHT1
glEnable(GL_LIGHT1);
// Свойства тумана для режима glEnable(GL_FOG)
fogMode := GL_EXP; // GL_EXP2, GL_LINEAR
glFogi(GL_FOG_MODE, fogMode); // установить режим
glFogfv(GL_FOG_COLOR, @fogColor); // цвет тумана
glFogf(GL_FOG_DENSITY, 0.002); // плотность - 0.2%
glHint(GL_FOG_HINT, GL_DONT_CARE); // GL_NICEST, GL_FASTEST.
glClearColor(0.0, 0.0, 0.2, 1.0); // Установить цвет фона - синий
glClearDepth(1.0); // Очистить буфер глубины
glDepthFunc(GL_LESS); // Тип теста глубины
glShadeModel(GL_SMOOTH); // плавное цветовое сглаживание
// glEnable(..) - включить режим, glDisable(..) - отключить
glEnable(GL_LIGHTING); // разрешить осещенность
//glEnable(GL_FOG); // разрешить тумана
glEnable(GL_DEPTH_TEST); // разрешить тест глубины, с использованием
// функции определенной в glDepthFunc
glEnable(GL_NORMALIZE); // разрешить нормали (различение передней
// и задней сторон плоских объектов)
glEnable(GL_COLOR_MATERIAL); // разрешить использование материалов на объектах
glEnable(GL_TEXTURE_2D); // разрешить наложение текстур
//glEnable(GL_BLEND); // разрешить смешивание (напр. прозрачность)
// не совместимо с glEnable(GL_DEPTH_TEST)
glLoadTexture('1.bmp', Texture); // загружаем текстуру
end;
{------------------------------------------------------------------}
{ Завершение работы с OpenGL }
{------------------------------------------------------------------}
procedure glKill(Wnd: hWND);
begin
wglMakeCurrent(DC, 0);
wglDeleteContext(RC);
ReleaseDC(Wnd, DC);
end;
{------------------------------------------------------------------}
{ Создание объектов под отрисовку }
{------------------------------------------------------------------}
procedure glDraw();
var
Obj: GLUquadricObj;
begin
// очистка Экрана и буфера глубины
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Переключаемся на видовую матрицу
glLoadIdentity; // Сбрасываем все преобразования
// Пример рисования разноцветного треугольника
glBegin(GL_POLYGON);
glColor(0.0, 0.5, 0.0, 0.0); // Цвет 1-ой вершины
glVertex3F(-50, -sqrt(3)*50, 0); // 1-я вершина
glColor(0.5, 0.0, 0.0, 0.0); // Цвет 2-ой вершины
glVertex3F(-100, -sqrt(3)*100, 0); // 2-я вершина
glColor(0.0, 0.0, 0.5, 0.0); // Цвет 3-ей вершины
glVertex3F(-125, -sqrt(3)*100, 0); // 3-я вершина
glEnd;
// Следующая фигура будет нарисована повернутой
// Поворачиваем сферу так, чтобы северный полюс на текстуре
// смотрел в нужную сторону
glRotate(-90, 0.0, 1.0, 0.0);
glRotate(60, 1.0, 0.0, 0.0);
// здесь поворот сферы вокруг оси
glRotate(-Angle, 0.0, 0.0, 1.0);
// Пример рисования сферы
glColor(1.0, 1.0, 1.0, 0.5); // установить цвет объекта
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Функция смешивания для непрозрачности,
// базирующаяся на значении альфы
// Отрабатывает только при glEnable(GL_BLEND)
glBindTexture(GL_TEXTURE_2D, Texture); // установить текущую текстуру Texture
Obj:=gluNewQuadric;
gluQuadricTexture(Obj, GL_TRUE); // разрешить наложить текущую текстуру на
// создаваемый объект
gluSphere(Obj, 100, 25, 25); // создать сферу R = 100, детализация - 25х25
gluDeleteQuadric(Obj); // Освобождаем память
Angle := (Angle + 5) mod 360;
// Выводим на экран подготовленную сцену
SwapBuffers(DC);
end;
{------------------------------------------------------------------}
{ Выбор приемлемого формата точки для данного DC }
{------------------------------------------------------------------}
procedure SetDCPixelFormat(DC: hDC);
var
pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do
begin
nSize := sizeof(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 16;
cDepthBits := 64;
iLayerType := PFD_MAIN_PLANE;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
{------------------------------------------------------------------}
{ Загрузка 8 или 24-битного bmp-файла текстуры }
{------------------------------------------------------------------}
procedure glLoadTexture(Filename: String; var Texture: GLuint);
type BitmapHeader=
record
FH: BitmapFileHeader;
IH: BitmapInfoHeader;
end;
var
ColorTable: array of TRGBQuad;
Data: array of Byte;
RGBData: array of TRGBTriple;
Bmp: BitmapHeader;
tmp, i, L: Cardinal;
F: hFile;
begin
F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if F = INVALID_HANDLE_VALUE then
begin
MessageBox(0,PChar('File '+ FileName + ' not found'), 'glLoadTexture',0);
exit;
end;
ReadFile(F, Bmp, sizeof(BitmapHeader),tmp, nil );
L := Bmp.IH.biWidth * Bmp.IH.biHeight;
SetLength(RGBData, L);
case Bmp.IH.biBitCount of
8:
begin
SetLength(ColorTable, round(exp(Bmp.IH.biBitCount*Ln(2))));
ReadFile(F, ColorTable[0], SizeOf(TRGBQuad) * round(exp(Bmp.IH.biBitCount*Ln(2))), tmp, nil);
SetLength(Data, L);
ReadFile(F, Data[0], SizeOf(Byte) * L, tmp, nil);
for i := 0 to L - 1 do
begin
RGBData[L - i - 1].rgbtRed := ColorTable[Data[i]].rgbBlue;
RGBData[L - i - 1].rgbtGreen := ColorTable[Data[i]].rgbGreen;
RGBData[L - i - 1].rgbtBlue := ColorTable[Data[i]].rgbRed;
end;
end;
24:
begin
SetLength(Data, L * 3);
ReadFile(F, Data[0], SizeOf(Byte) * L * 3, tmp, nil);
for i := 0 to L - 1 do
begin
RGBData[L - i - 1].rgbtRed := Data[3 * i];
RGBData[L - i - 1].rgbtGreen := Data[3 * i + 1];
RGBData[L - i - 1].rgbtBlue := Data[3 * i + 2];
end;
end;
else MessageBox(0, 'Format not support', 'glLoadTexture', 0);
end; { end case}
CloseHandle(F);
// Далее код из BMP.pas от Jan Horn
glGenTextures(1, Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); {Texture blends with object background}
// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); {Texture does NOT blend with object background}
{
Select a filtering type. BiLinear filtering produces very good results with little performance impact
GL_NEAREST - Basic texture (grainy looking texture)
GL_LINEAR - BiLinear filtering
GL_LINEAR_MIPMAP_NEAREST - Basic mipmapped texture
GL_LINEAR_MIPMAP_LINEAR - BiLinear Mipmapped texture
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, GL_RGB, GL_UNSIGNED_BYTE, RGBData);
// Use when not wanting mipmaps to be built by openGL
// glTexImage2D(GL_TEXTURE_2D, 0, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBData);
end;
end.
07 Собранный пример VCL=======================На форме таймер, в проект включен MyOpenGL.pas. В той же папке лежит 8 или 24-битный bmp-фаил.
interface
uses windows, OpenGL;
procedure glOnResize(Width, Height : Integer);
procedure glInit(Wnd: hWND);
procedure glKill(Wnd: hWND);
procedure glDraw();
procedure glLoadTexture(Filename: String; var Texture: GLuint);
implementation
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
function gluBuild2DMipmaps(Target: GLenum; Components, Width, Height: GLint; Format, atype: GLenum; Data: Pointer): GLint; stdcall; external glu32;
procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
procedure SetDCPixelFormat(DC: hDC); forward;
var
DC: hDC; // контекст устройства
RC: hGLRC; // контекст воспроизведения
Texture: GLuint; // хэндл текстуры
Angle: Integer = 0; // угол поворота сферы
{------------------------------------------------------------------}
{ Обработчик на изменение размеров окна }
{------------------------------------------------------------------}
procedure glOnResize(Width, Height: Integer);
begin
if (Height = 0) then Height := 1; // Предупреждаем деление на 0
glViewport(0, 0, Width, Height); // Устанавливаем область отображения
// на все окно
// Настройка матрицы проекции
glMatrixMode(GL_PROJECTION); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
// Устанавливаем тип проеции - Ортогональный
glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);
// Настройка видовой матрицы
glMatrixMode(GL_MODELVIEW); // Выбираем матрицу проекции
glLoadIdentity(); // Устанавливаем ее единичной
end;
{------------------------------------------------------------------}
{ Инициализация OpenGL }
{------------------------------------------------------------------}
procedure glInit(Wnd: hWND);
const
// Константы, задающие свойства материала фигур
mat1_amb : array [0..2] of Single = (0.2, 0.2, 0.2);
mat1_dif : array [0..2] of Single = (0.8, 0.8, 0.0);
mat1_spec: array [0..2] of Single = (0.6, 0.6, 0.6);
mat1_shininess = 10;
// Константы для источника света
light_pos : array [0..3] of glFloat = (100.0, 100.0, 0.0, 1.0);
light_amb : array [0..3] of glFloat = (0.6, 0.6, 0.6, 1.0);
light_dif : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
light_spec : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
light_spot_direction : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);
// Цвет тумана
fogColor: array [0..3] of GLfloat = (0, 1.0, 0, 1.0);
var
fogMode: GLint;
begin
// Инициализация контекста воспроизведения OpenGL
DC := GetDC(Wnd); // Получить контекст устройства для окна
SetDCPixelFormat(DC); // Установить формата пикселов
RC := wglCreateContext(DC); // создать новый контекст воспроизведения
wglMakeCurrent(DC,RC); // Установить его текущим
// Свойства материала для режима glEnable(GL_COLOR_MATERIAL)
glMaterialfv(GL_FRONT, GL_AMBIENT, @mat1_amb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat1_dif);
glMaterialfv(GL_FRONT, GL_SPECULAR, @mat1_spec);
glMaterialf (GL_FRONT, GL_SHININESS,mat1_shininess);
// Свойства источника света GL_LIGHT1 для режима glEnable(GL_LIGHTING)
// Стандартный источник одна команда: glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_POSITION,@light_pos);
glLightfv(GL_LIGHT1, GL_AMBIENT, @light_amb); // направленность
glLightfv(GL_LIGHT1, GL_DIFFUSE, @light_dif); // рассеивание
glLightfv(GL_LIGHT1, GL_SPECULAR, @light_spec);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, @light_spot_direction);
// разрешить источник света GL_LIGHT1
glEnable(GL_LIGHT1);
// Свойства тумана для режима glEnable(GL_FOG)
fogMode := GL_EXP; // GL_EXP2, GL_LINEAR
glFogi(GL_FOG_MODE, fogMode); // установить режим
glFogfv(GL_FOG_COLOR, @fogColor); // цвет тумана
glFogf(GL_FOG_DENSITY, 0.002); // плотность - 0.2%
glHint(GL_FOG_HINT, GL_DONT_CARE); // GL_NICEST, GL_FASTEST.
glClearColor(0.0, 0.0, 0.2, 1.0); // Установить цвет фона - синий
glClearDepth(1.0); // Очистить буфер глубины
glDepthFunc(GL_LESS); // Тип теста глубины
glShadeModel(GL_SMOOTH); // плавное цветовое сглаживание
// glEnable(..) - включить режим, glDisable(..) - отключить
glEnable(GL_LIGHTING); // разрешить осещенность
//glEnable(GL_FOG); // разрешить тумана
glEnable(GL_DEPTH_TEST); // разрешить тест глубины, с использованием
// функции определенной в glDepthFunc
glEnable(GL_NORMALIZE); // разрешить нормали (различение передней
// и задней сторон плоских объектов)
glEnable(GL_COLOR_MATERIAL); // разрешить использование материалов на объектах
glEnable(GL_TEXTURE_2D); // разрешить наложение текстур
//glEnable(GL_BLEND); // разрешить смешивание (напр. прозрачность)
// не совместимо с glEnable(GL_DEPTH_TEST)
glLoadTexture('1.bmp', Texture); // загружаем текстуру
end;
{------------------------------------------------------------------}
{ Завершение работы с OpenGL }
{------------------------------------------------------------------}
procedure glKill(Wnd: hWND);
begin
wglMakeCurrent(DC, 0);
wglDeleteContext(RC);
ReleaseDC(Wnd, DC);
end;
{------------------------------------------------------------------}
{ Создание объектов под отрисовку }
{------------------------------------------------------------------}
procedure glDraw();
var
Obj: GLUquadricObj;
begin
// очистка Экрана и буфера глубины
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Переключаемся на видовую матрицу
glLoadIdentity; // Сбрасываем все преобразования
// Пример рисования разноцветного треугольника
glBegin(GL_POLYGON);
glColor(0.0, 0.5, 0.0, 0.0); // Цвет 1-ой вершины
glVertex3F(-50, -sqrt(3)*50, 0); // 1-я вершина
glColor(0.5, 0.0, 0.0, 0.0); // Цвет 2-ой вершины
glVertex3F(-100, -sqrt(3)*100, 0); // 2-я вершина
glColor(0.0, 0.0, 0.5, 0.0); // Цвет 3-ей вершины
glVertex3F(-125, -sqrt(3)*100, 0); // 3-я вершина
glEnd;
// Следующая фигура будет нарисована повернутой
// Поворачиваем сферу так, чтобы северный полюс на текстуре
// смотрел в нужную сторону
glRotate(-90, 0.0, 1.0, 0.0);
glRotate(60, 1.0, 0.0, 0.0);
// здесь поворот сферы вокруг оси
glRotate(-Angle, 0.0, 0.0, 1.0);
// Пример рисования сферы
glColor(1.0, 1.0, 1.0, 0.5); // установить цвет объекта
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Функция смешивания для непрозрачности,
// базирующаяся на значении альфы
// Отрабатывает только при glEnable(GL_BLEND)
glBindTexture(GL_TEXTURE_2D, Texture); // установить текущую текстуру Texture
Obj:=gluNewQuadric;
gluQuadricTexture(Obj, GL_TRUE); // разрешить наложить текущую текстуру на
// создаваемый объект
gluSphere(Obj, 100, 25, 25); // создать сферу R = 100, детализация - 25х25
gluDeleteQuadric(Obj); // Освобождаем память
Angle := (Angle + 5) mod 360;
// Выводим на экран подготовленную сцену
SwapBuffers(DC);
end;
{------------------------------------------------------------------}
{ Выбор приемлемого формата точки для данного DC }
{------------------------------------------------------------------}
procedure SetDCPixelFormat(DC: hDC);
var
pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do
begin
nSize := sizeof(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 16;
cDepthBits := 64;
iLayerType := PFD_MAIN_PLANE;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
{------------------------------------------------------------------}
{ Загрузка 8 или 24-битного bmp-файла текстуры }
{------------------------------------------------------------------}
procedure glLoadTexture(Filename: String; var Texture: GLuint);
type BitmapHeader=
record
FH: BitmapFileHeader;
IH: BitmapInfoHeader;
end;
var
ColorTable: array of TRGBQuad;
Data: array of Byte;
RGBData: array of TRGBTriple;
Bmp: BitmapHeader;
tmp, i, L: Cardinal;
F: hFile;
begin
F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if F = INVALID_HANDLE_VALUE then
begin
MessageBox(0,PChar('File '+ FileName + ' not found'), 'glLoadTexture',0);
exit;
end;
ReadFile(F, Bmp, sizeof(BitmapHeader),tmp, nil );
L := Bmp.IH.biWidth * Bmp.IH.biHeight;
SetLength(RGBData, L);
case Bmp.IH.biBitCount of
8:
begin
SetLength(ColorTable, round(exp(Bmp.IH.biBitCount*Ln(2))));
ReadFile(F, ColorTable[0], SizeOf(TRGBQuad) * round(exp(Bmp.IH.biBitCount*Ln(2))), tmp, nil);
SetLength(Data, L);
ReadFile(F, Data[0], SizeOf(Byte) * L, tmp, nil);
for i := 0 to L - 1 do
begin
RGBData[L - i - 1].rgbtRed := ColorTable[Data[i]].rgbBlue;
RGBData[L - i - 1].rgbtGreen := ColorTable[Data[i]].rgbGreen;
RGBData[L - i - 1].rgbtBlue := ColorTable[Data[i]].rgbRed;
end;
end;
24:
begin
SetLength(Data, L * 3);
ReadFile(F, Data[0], SizeOf(Byte) * L * 3, tmp, nil);
for i := 0 to L - 1 do
begin
RGBData[L - i - 1].rgbtRed := Data[3 * i];
RGBData[L - i - 1].rgbtGreen := Data[3 * i + 1];
RGBData[L - i - 1].rgbtBlue := Data[3 * i + 2];
end;
end;
else MessageBox(0, 'Format not support', 'glLoadTexture', 0);
end; { end case}
CloseHandle(F);
// Далее код из BMP.pas от Jan Horn
glGenTextures(1, Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); {Texture blends with object background}
// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); {Texture does NOT blend with object background}
{
Select a filtering type. BiLinear filtering produces very good results with little performance impact
GL_NEAREST - Basic texture (grainy looking texture)
GL_LINEAR - BiLinear filtering
GL_LINEAR_MIPMAP_NEAREST - Basic mipmapped texture
GL_LINEAR_MIPMAP_LINEAR - BiLinear Mipmapped texture
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, GL_RGB, GL_UNSIGNED_BYTE, RGBData);
// Use when not wanting mipmaps to be built by openGL
// glTexImage2D(GL_TEXTURE_2D, 0, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBData);
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, MyOpenGL;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormDestroy(Sender: TObject);
begin
glKill(Form1.Handle);
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glOnResize(Form1.ClientWidth,Form1.ClientHeight);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
glDraw();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
glInit(Form1.Handle);
glOnResize(Form1.ClientWidth,Form1.ClientHeight);
end;
end.
08 Собранный пример WinApi==========================В той же папке лежит 8 или 24-битный bmp-файл.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, MyOpenGL;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormDestroy(Sender: TObject);
begin
glKill(Form1.Handle);
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glOnResize(Form1.ClientWidth,Form1.ClientHeight);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
glDraw();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
glInit(Form1.Handle);
glOnResize(Form1.ClientWidth,Form1.ClientHeight);
end;
end.
program a;
uses
windows,
messages,
MyOpenGL in 'MyOpenGL.pas';
var
MainWnd: hWND;
function WindowProc(Wnd: HWND; Msg: Integer; wParam: wParam; lParam:lParam):lResult;stdcall;
begin
case Msg of
WM_DESTROY:
begin
glKill(MainWnd);
postquitmessage(0);
Result := 0;
exit;
end;
WM_TIMER:
begin
glDraw(); // Рисуем сцену
Result := 0;
end;
WM_SIZE:
begin
// В lParam содержатся размеры клиентской области ;-)
glOnResize(loWord(lParam), hiWord(lParam));
Result := 0;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
var
Mesg: TMsg;
wc : TWndClassEx;
begin
wc.cbSize := sizeof(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := LoadIcon(0, IDI_WINLOGO);
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground := COLOR_BTNFACE+2;
wc.lpszMenuName := nil;
wc.lpszClassName := 'aWnd';
RegisterClassEx(wc);
// Создаем окно 400х400
MainWnd := CreateWindowEx (0, 'aWnd', 'MyOpenGL', WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400, 0, 0, hInstance, nil);
// Создаем контекст воспроизведения OpenGL и его параметры
glInit(MainWnd);
// Задаем матрицы OpenGL для размера окна 400х400
glOnResize(400, 400);
// Устанавливаем таймер 10мс для перерисовки сцены
SetTimer(MainWnd, 1, 10, nil);
while GetMessage(Mesg, 0, 0, 0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
uses
windows,
messages,
MyOpenGL in 'MyOpenGL.pas';
var
MainWnd: hWND;
function WindowProc(Wnd: HWND; Msg: Integer; wParam: wParam; lParam:lParam):lResult;stdcall;
begin
case Msg of
WM_DESTROY:
begin
glKill(MainWnd);
postquitmessage(0);
Result := 0;
exit;
end;
WM_TIMER:
begin
glDraw(); // Рисуем сцену
Result := 0;
end;
WM_SIZE:
begin
// В lParam содержатся размеры клиентской области ;-)
glOnResize(loWord(lParam), hiWord(lParam));
Result := 0;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
var
Mesg: TMsg;
wc : TWndClassEx;
begin
wc.cbSize := sizeof(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := LoadIcon(0, IDI_WINLOGO);
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground := COLOR_BTNFACE+2;
wc.lpszMenuName := nil;
wc.lpszClassName := 'aWnd';
RegisterClassEx(wc);
// Создаем окно 400х400
MainWnd := CreateWindowEx (0, 'aWnd', 'MyOpenGL', WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400, 0, 0, hInstance, nil);
// Создаем контекст воспроизведения OpenGL и его параметры
glInit(MainWnd);
// Задаем матрицы OpenGL для размера окна 400х400
glOnResize(400, 400);
// Устанавливаем таймер 10мс для перерисовки сцены
SetTimer(MainWnd, 1, 10, nil);
while GetMessage(Mesg, 0, 0, 0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
Очень сильно помогло для вывода текста. Спасибо.
Отправить комментарий