![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Разработка GUI
Nic © (2006-09-18 23:26:00)Задача: сделать текст с картинками и скроллингом всего этого (OGL или на D3D). Что-то не пойму, с чего начать. Может есть у кого статьи по сабжу? Буду заранее благодарен.
Nic (2006-09-19 22:27:00) [1]Опечатка, DX 9, конечно :) Спасибо огромное, буду изучать :)
Cash (2006-09-19 16:09:00) [2]Nic © (19.09.06 15:53) [29]:
> Мне ответили, Visual C++ + DX 10.
И где только такие слова говорят??? Ух я бы им... :)
Ну раз уж такая петрушка пошла, то с языком ты уж сам! Топай сюда:
(регся, логинься и задавай вопросы! :))) П7 сделал так. :) )
http://www.gamedev.ru/community/newbie-zone/?info
Там же (или если нада, по мылу) я помогу с теорией или еще чем другим.
ЗЫ: А DX10 это ваще не в степь пока. Он, факт, еще раз десять
перестраиваться будет. Я на него решил переходить когда висту себе
поставлю.
Nic (2006-09-19 15:53:00) [3]cyborg © (19.09.06 13:25) [23]
Спасибо на добром коде :)
Cash © (19.09.06 13:34) [25]
Пока нисколько. Тестовое задание дали. Я писал в резюме о Delphi + OpenGL. Мне ответили, Visual C++ + DX 10. Я ответил - дайте чуть-чуть времени, я молодой студент и привыкну к тому, к чему даже и не думал привыкать :) Столичная фирма, весьма крупная.
Cash (2006-09-19 13:41:00) [4]cyborg © (19.09.06 13:36) [27]:
Позырим... :)))
Блин, опять он смылся... наверняк опять на сутки.
cyborg (2006-09-19 13:36:00) [5]> cyborg, Nic же говорил о C++. 8)
Ничего, переведёт, он же гибкий :)
cyborg (2006-09-19 13:35:00) [6]Кстати, там некоторые комментарии не соответствуют действительтности, правил код, а коментарии исправить забыл. Например //S у нас PChar, поэтому символы идут с нуля, а не с единицы! :)
Cash (2006-09-19 13:34:00) [7]cyborg, Nic же говорил о C++. 8)
Nic, наверняк Visual C++, и из под MSVS? так? И DirectX только только начал изучать...
И чё? За две недели надо GUI склепать???
А сколько дадут? Иже не секрет? :)
Так, давай с нуля. В C++ разбираешься? Кодить сможешь?
cyborg (2006-09-19 13:31:00) [8]Использование:
Var
Font1, Font2 : T3DFont;
Str1,Str2,Str3,Str4,Str5,StrFPS : P3DString;
Загрузка/создание:
LoadFont(Font1, 'Fonts\MS Sans Serif_512x256.bmp',$01000000);
LoadFont(Font2, 'Fonts\Palatino Linotype_256x256.bmp',$01000000);
S:='ПРОБЕЛ - генерация сцены.'+#10+'Стрелки управления перемещают камеру. Клавиши [Insert] и [Delete] - приблизить/удалить камеру';
InitString( 0, 700, Str1, Font1, S, False, 0,0, $008080FF,$00FFFFFF, $00FFFFFF,$00AAAAAA);
InitString( 10, 10, StrFPS, Font1, 'FPS: 0', False, 0,0, $008080FF,$00FFFFFF, $00FFFFFF,$00AAAAAA);
InitString( 600, 20, Str2, Font2, 'Ниже находится панель с текстом из файла:', False, 0,0, $00FFFFFF,$0000A0A0, $00EECC60,$00CC8810);
Отображение:
BeginDrawText; //Вызывать перед началом вывода текста
DrawText(Str1);
DrawText(Str2);
DrawText(Str3);
DrawText(Str4);
DrawText(Str5);
EndDrawText; //Вызывать после окончания вывода текста
Освобождение:
FreeString(Str1);
FreeString(Str2);
FreeString(Str3);
FreeString(Str4);
FreeString(Str5);
FreeString(StrFPS);
FreeFont(Font1);
FreeFont(Font2);
cyborg (2006-09-19 13:25:00) [9]
Procedure ScrollString(var Str : P3DString; OfsX,OfsY : Single);
Var
i : Longint;
pv : Pointer;
begin
if Str=nil then Exit;
if (Str^.VertexBuffer=nil) or (Str^.VertexBufferSize=0) then Exit;
pv:=Str^.VertexBuffer;
for i:=1 to (Str^.TextLength) * 4 do
begin
With TCustomSpriteVertex1(PV^) do
begin
x:=X+OfsX;
y:=y+OfsY;
end;
Inc(Longint(PV),Str^.BytesPerVertex);
end;
end;
Procedure DrawText(var Str : P3DString);
Var
VP : TD3DVIEWPORT9;
begin
if Str=nil then Exit;
if Str^.Font=nil then Exit;
SetTexture(Str^.Font^.Texture);
SetVFV(Str^.VFV);
if Str^.Rectangled then
begin
With Str^ do
begin
VP.X:=Rect.Left;
VP.Y:=Rect.Top;
// if VP.X<0 then VP.X:=0;
// if VP.Y<0 then VP.Y:=0;
VP.Width:=(Rect.Right-VP.X);
VP.Height:=(Rect.Bottom-VP.Y);
VP.MinZ:=0;
VP.MaxZ:=1;
end;
iD3DDevice.SetViewport(VP);
end;
With iD3DDevice do
begin
DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, Str^.VertexCount, Str^.FacesCount, Str^.IndexBuffer^,Str^.IndexDataFormat, Str^.VertexBuffer^, Str^.BytesPerVertex);
end;
if Str^.Rectangled then
begin
VP.X:=0;
VP.Y:=0;
VP.Width:=ScreenWidth;
VP.Height:=ScreenHeight;
VP.MinZ:=0;
VP.MaxZ:=1;
iD3DDevice.SetViewport(VP);
end;
VertexCount:=VertexCount+(Str^.IndexBufferSize div 6);
end;
//Вызывать перед началом вывода текста:
Procedure BeginDrawText;
begin
With iD3DDevice do
begin
SetRenderState(D3DRS_ZENABLE, D3DZB_False);
// SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
// SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
// SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
//;Выключаем сравнение альфы
// SetRenderState(D3DRS_ALPHATESTENABLE,1);
SetRenderState(D3DRS_ALPHABLENDENABLE,1);
SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD);
SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_NONE );
end;
end;
//Вызывать после окончания вывода текста:
Procedure EndDrawText;
begin
With iD3DDevice do
begin
SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC );
SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC );
end;
end;
cyborg (2006-09-19 13:24:00) [10]
Procedure InitString(X,Y : Longint; var Str : P3DString; var Font : T3DFont; const S : ansistring; Rectangled : LongBool; RectW,RectH : Longint; ColorUp,ColorDown,SelColorUp,SelColorDown : Cardinal; StrInterval : Longint = 0 );
Var
L,L2 : Longint;
tX,tY : Longint;
p : Pointer;
i : Longint;
ch : byte;
SubstrLength : Longint;
CurPos : Longint;
Selected : LongBool;
begin
//Оптимизированная функция, неиспользуемые символы не занимают драгоценные вертексы :)
//S у нас PChar, поэтому символы идут с нуля, а не с единицы! :)
L:=Length(S);
if (Font.Texture=nil) or (L<=0) then Exit;
FreeString(Str, true);
if Str=nil then
begin
GetMem(Str,SizeOf(T3DString));
FillChar(Str^,SizeOf(T3DString),$00);
end else
begin
//Если изменяем существующий текст, то удаляем старые вертексы и индексы:
if Str^.VertexBuffer<>nil then
begin
FreeMem(Str^.VertexBuffer,Str^.VertexBufferSize);
Str^.VertexBuffer:=nil;
end;
if Str^.IndexBuffer<>nil then
begin
FreeMem(Str^.IndexBuffer,Str^.IndexBufferSize);
Str^.IndexBuffer:=nil;
end;
end;
Str^.Font:=@Font;
Str^.Rectangled:=Rectangled;
Selected := false;
L2:=0;
for i:=1 to L do
begin
ch:=byte(S[i]);
if (ch>32) and (ch<>91) and (ch<>93) then Inc(L2);
end;
With Str^ do
begin
dX:=X;
dY:=Y;
TextLength:=L2;
//Прямоугольник отсечения:
Rect.Left:=X;
Rect.Top:=Y;
Rect.Right:=X+RectW;
Rect.Bottom:=Y+RectH;
VFV:=PVB_FVFSprite1;
BytesPerVertex:=SizeOf(TCustomSpriteVertex1);
Text:=S;
VertexCount:=L2*4; //кол-во точек
FacesCount:=L2*2; //кол-во треугольников
VertexBufferSize:=VertexCount*BytesPerVertex;
GetMem(VertexBuffer,VertexBufferSize);
IndexBufferSize:=FacesCount*(3*2);
GetMem(IndexBuffer,IndexBufferSize);
IndexDataFormat:=D3DFMT_INDEX16;
//Очистка данных:
FillChar(VertexBuffer^,VertexBufferSize,$00);
FillChar(IndexBuffer^,IndexBufferSize,$00);
end;
tX:=X;
tY:=Y;
SubstrLength:=0;
CurPos:=0;
//Вертексы:
p:=Str^.VertexBuffer;
for i:=1 to L do
begin
//Если с отсечением, то рассчитываем переносы по словам:
if Rectangled then
begin
if (i>=CurPos) then
begin
SubstrLength:=0;
//Повторять пока не конец строки:
While CurPos<L do
begin
// ch:=Byte(Pointer(Longint(S)+(curPos))^);
ch:=Byte(S[curPos]);
Inc(SubstrLength,Font.CharsInfo[ch].W);
//Если пробел, то конец слова, или длина слова превышает ширину отсечения,
//значит длину рассчитали, выходим из цикла:
if (ch<=32) or (ch=91) or (ch=93) or (Str^.Rect.Right-Str^.Rect.Left<SubstrLength) then
begin
Inc(CurPos);
break;
end; //if ch=32
Inc(CurPos);
//Если вышли за пределы отсечения, то переходим на другую строку:
if (TX>Str^.Rect.Right-SubstrLength) then
begin
tX:=X;
Inc(tY,Font.CharsInfo[48].H+StrInterval);
end;
end; //While CurPos<L
end; //if (i<=CurPos)
end; //if Rectangled
// ch:=Byte(Pointer(Longint(S)+(i))^);
ch:=Byte(S[i]);
if Ch<=32 then
begin
if Ch=10 then
begin
tX:=X;
Inc(tY,Font.CharsInfo[48].H+StrInterval);
end else
if Ch=32 then
begin
Inc(tX,Font.CharsInfo[32].W);
end;
Continue;
end;
if (ch=91) then
begin
Selected := True;
Continue;
end;
if (ch=93) then
begin
Selected := False;
Continue;
end;
if Rectangled then
begin
if TX>Str^.Rect.Right-Font.CharsInfo[ch].W then
begin
tX:=X;
Inc(tY,Font.CharsInfo[48].H+StrInterval);
end;
end; //if Rectangled
if tX>Str^.W then Str^.W:=tX;
if tY>Str^.H then Str^.H:=tY;
//Левый верхний угол:
With TCustomSpriteVertex1(P^) do
begin
x:=tX;
y:=tY;
z:=0.0;
RHW:=1;
if Selected then Color:=SelColorUp else Color:=ColorUp;
tu:=Font.CharsInfo[ch].TX1;
tv:=Font.CharsInfo[ch].TY1;
end;
Inc(Longint(P),Str^.BytesPerVertex);
//Правый верхний угол:
With TCustomSpriteVertex1(P^) do
begin
x:=tX+Font.CharsInfo[Byte(Str^.Text[i])].W+1;
y:=tY;
z:=0.0;
RHW:=1;
if Selected then Color:=SelColorUp else Color:=ColorUp;
tu:=Font.CharsInfo[ch].TX2;
tv:=Font.CharsInfo[ch].TY1;
end;
Inc(Longint(P),Str^.BytesPerVertex);
//Правый нижний угол:
With TCustomSpriteVertex1(P^) do
begin
x:=tX+Font.CharsInfo[ch].W+1;
y:=tY+Font.CharsInfo[ch].H+1;
z:=0.0;
RHW:=1;
if Selected then Color:=SelColorDown else Color:=ColorDown;
tu:=Font.CharsInfo[ch].TX2;
tv:=Font.CharsInfo[ch].TY2;
end;
Inc(Longint(P),Str^.BytesPerVertex);
//Левый нижний угол:
With TCustomSpriteVertex1(P^) do
begin
x:=tX;
y:=tY+Font.CharsInfo[ch].H+1;
z:=0.0;
RHW:=1;
if Selected then Color:=SelColorDown else Color:=ColorDown;
tu:=Font.CharsInfo[ch].TX1;
tv:=Font.CharsInfo[ch].TY2;
end;
Inc(Longint(P),Str^.BytesPerVertex);
Inc(tX,Font.CharsInfo[ch].W);
end; //for i:=0 to L-1 do
//Индексы:
p:=Str^.IndexBuffer;
for i:=0 to L2-1 do
begin
//Первый треугольник:
Word(P^):=(i*4); //Левый верхний угол
Inc(Longint(P),2);
Word(P^):=(i*4)+1; //Правый верхний угол
Inc(Longint(P),2);
Word(P^):=(i*4)+3; //Левый нижний угол
Inc(Longint(P),2);
//Второй треугольник:
Word(P^):=(i*4)+3; //Левый нижний угол
Inc(Longint(P),2);
Word(P^):=(i*4)+1; //Правый верхний угол
Inc(Longint(P),2);
Word(P^):=(i*4)+2; //Правый нижний угол
Inc(Longint(P),2);
end; //for i:=1 to L do
Str^.W:=Str^.W-X;
Str^.H:=Str^.H-Y;
P:=nil;
end;
cyborg (2006-09-19 13:24:00) [11]
Procedure FreeFont(var Font : T3DFont);
begin
FreeTexture(Font.Texture);
FillChar(Font,SizeOf(T3DFont),$00);
end;
Procedure LoadFont(var Font : T3DFont; FileName : PChar; ColorKey : Cardinal = $FF000000);
Var
F : File;
begin
if (not FileExists(FileName)) or (not FileExists(FileName+'.crd')) then Exit;
FreeFont(Font);
LoadTexture(Font.Texture, FileName, ColorKey);
FileMode:=0 ; //Режим окрытия файла ТОЛЬКО ЧТЕНИЕ
AssignFile(F,FileName+'.crd');
Reset(F,1);
BlockRead(F,Font.CharsInfo,SizeOf(Font.CharsInfo));
CloseFile(F);
FileMode:=2; //Режим окрытия файла ЧТЕНИЕ/ЗАПИСЬ
end;
Procedure FreeString(var Str : P3DString; Clear : Longbool = false);
begin
if Str=nil then Exit;
With Str^ do
begin
Text:='';
if (VertexBuffer<>nil) and (VertexBufferSize>0) then FreeMem(VertexBuffer,VertexBufferSize);
if (IndexBuffer<>nil) and (IndexBufferSize>0) then FreeMem(IndexBuffer,IndexBufferSize);
end;
if Clear then FillChar(Str^,SizeOf(T3DString),$00) else
begin
FreeMem(Str,SizeOf(T3DString));
Str:=nil;
end;
end;
cyborg (2006-09-19 13:23:00) [12]Вот разбирайся, не знаю достаточно вырезал или чего забыл.
CONST
PVB_FVFSprite1 = D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_TEX1;
TYPE
PCustomSpriteVertex1 = ^TCustomSpriteVertex1;
TCustomSpriteVertex1 = packed record
x, y, z : Single;
RHW : Single;
Color : DWORD;
tu, tv : Single;
end;
p3DSpriteRect1 = ^t3DSpriteRect1;
t3DSpriteRect1 = array[0..5] of TCustomSpriteVertex1;
P3DFont = ^T3DFont;
T3DFont = packed record
CharsInfo : TCharSizeArr;
Texture : IDirect3DTexture9; //Указатель на интерфейс текстуры
end;
P3DString = ^T3DString;
T3DString = packed record
Font : P3DFont;
Text : AnsiString;
dX,dY : Longint; //Первоначальные координаты текста (пригодится для сброса изменений координат текста)
W,H : Longint; //Ширина и высота текста
TextLength : Longint;
Rectangled : LongBool;
Rect : TRect;
VFV : Cardinal; //Формат вершин
BytesPerVertex : Cardinal; //Кол-во байт на вертекс
VertexBuffer : Pointer; //Указатель на буфер вертексов
VertexBufferSize : Cardinal; //Размер данных буфера вертексов
IndexBuffer : Pointer; //Указатель на буфер индексов
IndexBufferSize : Cardinal; //Размер буфера индексов
IndexDataFormat : _D3DFormat; //Формат индексов
VertexCount : Cardinal; //Кол-во вертексов
FacesCount : Cardinal; //Кол-во треугольников
end;
Nic (2006-09-19 13:07:00) [13]Мне нужно только текст, картинки. кнопочки. Прорисовка окон не требуеттся. За пару неделек с полного нуля что-то работающее реально сделать? Если ни с D3D ни с C++ никогда не работал серьёзно. Купил книгу Франка Д. Луны "Введение в программирование DirectX 9.0" + книгу по C++, рекомендованную министерством образования РФ для ВУЗов. Опыт в графике имеется (OGL) и в программировании тоже, но только на Delphi. Если у кого есть простые примеры, чтоб можно было посмотреть - намыльте плиз :)
Nic (2006-09-19 12:49:00) [14]Не ожидал такой быстрой реакции :) В принципе, реализуемо. Просто никогда не делал, а тут надо за короткий срок на незнакомом языке программирования на незнакомом АПИ. Вот и спросил, мож у кого исходник или статья.
Cash (2006-09-19 12:35:00) [15]Вон, освеженный бинарник (только бинарка) с этими багофиксами.
http://webfile.ru/1112578
Чего то Nic не отвечает...
Вот с закреплением окон, в KDE содержимое окна становится полупрозрачным,
а в EVE-Online оно выще не отрисовывается.
Вот и думаю, мож действительно при закреплении убирать с экрана
содержимое окна... Хотя эффект с полупрозрачностью тоже интересно
сделать.
А сквозь такое прозрачное окошко можно работать с остальным интерфейсом.
cyborg (2006-09-19 11:17:00) [16]> Кста, там в заголовке окна есть кнопочка [*] очень интересная,
Да я уже оценил, прикрепить окно :)
Cash (2006-09-19 11:10:00) [17]По закону жанра окно я сделал так, чтобы оно не вылезало за пределы
экрана. Потом сменил тип координат с Word на SmallInt (важно, что 2 байта),
а о приведении типов в сообщениях забыл. Вот такой я я склеротик. :)
Кста, там в заголовке окна есть кнопочка [*] очень интересная, я такую
в KDE оболочке и в GUI EVE-Onilne видел, понравилась, вот и реализовал.
cyborg (2006-09-19 11:09:00) [18]> SmallInt->Word
Сейчас не те времена, чтобы из за двух байт жаться. Лонгинт - наше настоящее, и инт64 наше будущее. :)
Cash (2006-09-19 11:06:00) [19]cyborg © (19.09.06 10:59) [12]:
Объявляю первого тестера и награждаю его почетной грамотой! Спасибо.
Малость неверное преобразование типов (SmallInt->Word) сделало свое дело. :)
+Fixed! Спасибо еще раз!
cyborg (2006-09-19 10:59:00) [20]> [10] Cash © (19.09.06 10:32)
Да, атолн 64 и фич много :), видео гф6600
Глюк - тянем это окошечко с инфой влево вверх за пределы окна и опаля, оно справа снизу рисуется. Проверку на отрицательные значения сделай.