Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2019, 12:09   #1
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию Написание функции для создания точек внутри куба и сферы: перевод кода из C++ в Delphi

Добрый день! В лабораторной работе мне дали задание - создать три трекбара и поместить тысячу точек внутри куба и сферы с кодом на C++:

Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        TGLPoints *P[100];
        for(int i=0;i<100;i++)
        {
          P[i]=new TGLPoints(GLDummyCube1);
          P[i]->Colors->Add(((float)(rand()%256))/256.0,
                                           ((float)(rand()%256))/256.0,
                                           ((float)(rand()%256))/256.0,0.5);
          P[i]->Size=5;
          P[i]->Position->X=1.0*rand()/RAND_MAX-0.5;
          P[i]->Position->Y=1.0*rand()/RAND_MAX-0.5;
          P[i]->Position->Z=1.0*rand()/RAND_MAX-0.5;
        }
}
//Поворот  куба интерактивно
//---------------------------------------------------------------------------
void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
GLDummyCube1->PitchAngle=TrackBar1->Position; }
void __fastcall TForm1::TrackBar2Change(TObject *Sender) {
GLDummyCube1->RollAngle=TrackBar2->Position; }
void __fastcall TForm1::TrackBar3Change(TObject *Sender) {
GLDummyCube1->TurnAngle=TrackBar3->Position; }
//---------------------------------------------------------------------------
Но это только для даммикуба, а я пытаюсь сделать для того объекта, на который смотрит камера. Вдобавок, на C++ возникли ошибки с адаптером OpenGLAdapter, из-за которых мне пришлось переходить на Delphi. В моём проекте есть две формы, а во второй - две камеры. Одна смотрит на куб, а другая - на сферу. Я сделал куб и сферу полупрозрачными, выставив свойство BlendingMode в главе Material в bmAdditive, и попытался сам перевести код на Delphi, но не понял, как создавать массив указателей, разыменовывать указатели, используя конструктор класса и генерировать случайные числа. Почему в C++ в функции Add генерируемое число переводится в тип float, а потом ещё и делится на 256.0, и какой аналог сишной переменной RANDOM_MAX, чтобы узнать максимальное число, которое может сгенерировать мой компилятор? Я брал 5000, но при нажатии кнопки Add ничего не вывелось.

Код:
procedure TForm2.Button4Click(Sender: TObject);
var
P: array [0..99] of TGLPoints;
i: Integer;
begin
for i:=Low(P) to High(P) do
begin
P[i]:=TGLPoints.Create(Form2.GLSceneViewer1.Camera.TargetObject);
P[i].Colors.Add((Double(Random(256)))/256.0,
                   (Double(Random(256)))/256.0,
                   (Double(Random(256)))/256.0,0.5);
P[i].Size:=5;
P[i].Position.X:=1.0*Random(5000)/5000-0.5;
P[i].Position.Y:=1.0*Random(5000)/5000-0.5;
P[i].Position.Z:=1.0*Random(5000)/5000-0.5;
end;
end;
 
procedure TForm2.TrackBar1Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.PitchAngle:=TrackBar1.Position;
end;
 
procedure TForm2.TrackBar2Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.RollAngle:=TrackBar2.Position;
end;
 
procedure TForm2.TrackBar3Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.TurnAngle:=TrackBar3.Position;
end;
Как перевести код из C++ в Delphi, но не для даммикуба, а для объекта, на который смотрит камера? Скиньте, пожалуйста, книгу по GLScene, где есть пример функции для добавления точек в куб на Delphi. Ведь я не знаю, что искать - либо книг очень много, либо так мало, что пересчитаешь по пальцам, и всё равно не найдешь нужную информацию.
Изображения
Тип файла: jpg задание-лаба-2.jpg (73.0 Кб, 96 просмотров)
Тип файла: jpg задание-лаба-2-часть-2.jpg (96.9 Кб, 48 просмотров)
Тип файла: jpg задание-лаба-2-часть-3.jpg (60.4 Кб, 81 просмотров)
Тип файла: jpg задание-лаба-2-часть-4.jpg (38.0 Кб, 45 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 20.09.2019, 12:28   #2
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Код:
unit Lab2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Lab1, Vcl.StdCtrls, GLWin32Viewer, GLKeyboard, Math,
  GLCrossPlatform, GLBaseClasses, GLScene, GLObjects, GLCoordinates, GLCadencer,
  Vcl.ComCtrls;
 
type
  TForm2 = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    Button1: TButton;
    GLCadencer1: TGLCadencer;
    GLCamera1: TGLCamera;
    GLLightSource1: TGLLightSource;
    GLCube1: TGLCube;
    GLSphere1: TGLSphere;
    GLCamera2: TGLCamera;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TrackBar3: TTrackBar;
    procedure Button1Click(Sender: TObject);
    procedure GLCube1Progress(Sender: TObject; const deltaTime,
      newTime: Double);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
      newTime: Double);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar3Change(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    mx,my: Integer;
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.dfm}
 
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.Visible:=True;
Form2.Visible:=False;
end;
 
procedure TForm2.Button2Click(Sender: TObject);
begin
   Form2.GLSceneViewer1.Camera:=Form2.GLCamera1;
   Form2.Button2.Enabled:=False;
   Form2.Button3.Enabled:=True;
end;
 
procedure TForm2.Button3Click(Sender: TObject);
begin
   Form2.GLSceneViewer1.Camera:=Form2.GLCamera2;
   Form2.Button3.Enabled:=False;
   Form2.Button2.Enabled:=True;
end;
 
procedure TForm2.Button4Click(Sender: TObject);
var
P: array [0..99] of TGLPoints;
i: Integer;
begin
for i:=Low(P) to High(P) do
begin
P[i]:=TGLPoints.Create(Form2.GLSceneViewer1.Camera.TargetObject);
P[i].Colors.Add((Double(Random(256)))/256.0,
                   (Double(Random(256)))/256.0,
                   (Double(Random(256)))/256.0,0.5);
P[i].Size:=5;
P[i].Position.X:=1.0*Random(5000)/5000-0.5;
P[i].Position.Y:=1.0*Random(5000)/5000-0.5;
P[i].Position.Z:=1.0*Random(5000)/5000-0.5;
end;
end;
 
procedure TForm2.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
if(Form2.GLSceneViewer1.MouseInControl=true) then Form2.GLSceneViewer1.Camera.AdjustDistanceToTarget(Power(1.1,-WheelDelta/120))
end;
 
procedure TForm2.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
//Движение вперед по клавишам ‘ц’ и’ w’
if (IsKeyDown('ц') OR IsKeyDown('w')) then Form2.GLSceneViewer1.Camera.Move(2* deltaTime);
//Движение назад по клавишам ‘ы’ и ‘s’
if (IsKeyDown('ы') OR IsKeyDown('s')) then Form2.GLSceneViewer1.Camera.Move(-2* deltaTime);
//Поворот влево по клавишам ‘ф’ и’ a’
if (IsKeyDown('ф') OR IsKeyDown('a')) then Form2.GLSceneViewer1.Camera.slide(-2* deltaTime);
//Поворот вправо по клавишам ‘в’ и ‘d’
if (IsKeyDown('в') OR IsKeyDown('d')) then Form2.GLSceneViewer1.Camera.slide(2* deltaTime);
//Движение вверх по клавишам ‘u’ и ‘г’
if (IsKeyDown('u') OR IsKeyDown('г')) then Form2.GLSceneViewer1.Camera.Lift(0.01);
//Движение вниз по клавишам ‘n’ и ‘т’
if (IsKeyDown('n') OR IsKeyDown('т')) then Form2.GLSceneViewer1.Camera.Lift(-0.01);
if (IsKeyDown('c') OR IsKeyDown('с')) then GLSceneViewer1.Camera:=GLCamera1;
if (IsKeyDown('v') OR IsKeyDown('м')) then GLSceneViewer1.Camera:=GLCamera2
end;
 
procedure TForm2.GLCube1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
Form2.GLCube1.TurnAngle:=Form2.GLCube1.TurnAngle + deltaTime * 100;
end;
 
procedure TForm2.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  mx:=x; my:=y; //Запомнить координаты мыши
end;
 
procedure TForm2.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Shift<>[] then begin //Если нажата клавиша
  Form2.GLSceneViewer1.Camera.MoveAroundTarget(my-y, mx-x); //Перемещаем камеру вокруг целевого объекта
  Form2.GLLightSource1.Position:=Form2.GLSceneViewer1.Camera.Position; //Пусть источник освещения будет рядом с камерой
  mx:=x; my:=y;
  end;
end;
 
procedure TForm2.TrackBar1Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.PitchAngle:=TrackBar1.Position;
end;
 
procedure TForm2.TrackBar2Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.RollAngle:=TrackBar2.Position;
end;
 
procedure TForm2.TrackBar3Change(Sender: TObject);
begin
Form2.GLSceneViewer1.Camera.TargetObject.TurnAngle:=TrackBar3.Position;
end;
 
end.
Изображения
Тип файла: jpg результат-проекта-1.jpg (37.4 Кб, 43 просмотров)
Тип файла: jpg результат-проекта-2.jpg (46.4 Кб, 45 просмотров)
Тип файла: jpg результат-проекта-3.jpg (35.7 Кб, 43 просмотров)
Тип файла: jpg результат-проекта-4.jpg (46.6 Кб, 43 просмотров)
Тип файла: jpg результат-проекта-5.jpg (48.3 Кб, 43 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 21.09.2019, 04:15   #3
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Сделал так:

Код:
Procedure TForm2.Button4Click(Sender: TObject);
Var
  i: Integer;
  Pt: TGLPoints;
Begin
For i := 1 To 1000 Do
  Begin
  Pt := TGLPoints.Create(GLSceneViewer1.Camera.TargetObject);
  Pt.Colors.Add(RandomRange(0, 1000) / 1000, RandomRange(0, 1000) / 1000, RandomRange(0, 1000) / 1000, 0.5);
  Pt.Size := 5;
  Pt.Position.X := RandomRange(-500, 500) / 1000;
  Pt.Position.Y := RandomRange(-500, 500) / 1000;
  Pt.Position.Z := RandomRange(-500, 500) / 1000;
  GLSceneViewer1.Camera.TargetObject.AddChild(Pt); // Вот, дописал наугад, теперь вроде работает.
  End;
End;
Но точки почему-то оказались снаружи, а не внутри объекта.
VolodyaBuzin вне форума Ответить с цитированием
Старый 21.09.2019, 04:24   #4
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Вот результаты:
Изображения
Тип файла: jpg результат-проекта-6.jpg (44.2 Кб, 37 просмотров)
Тип файла: jpg результат-проекта-7.jpg (78.0 Кб, 36 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 21.09.2019, 05:08   #5
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Видимо, с координатами всё-таки переборщил. Какой диапазон нужен для свойства Position, и на что делить?
VolodyaBuzin вне форума Ответить с цитированием
Старый 21.09.2019, 20:00   #6
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Я уменьшил диапазон,

Код:
RandomRange(-330, 330) / 1000;
но оказалось, что куб и сфера на самом деле "псевдопрозрачные". Хотя пересечения их осей видны, точки появляются лишь при очень сильном приближении, когда грани объектов "проламываются". Я попробовал сделать прозрачность по способам пользователя Fosgen, описанным здесь,
http://delphimaster.net/view/9-1120384424
но для моей видеокарты AMD Radeon R7 это не сработало. И вдобавок, во втором способе при изменении эмиссии голубого и зелёного цветов компилятор выдал окно с ошибкой, которая была очень назойливой, требовала отправить отчёт и программу закрыть не давала. Скорее всего, либо демоверсия рэд студии ограничена в правах, либо для моей "видюхи" это невозможно. Как выкрутиться, не знаю, ведь способов уйма в зависимости от типа видеокарты и нет универсального решения. Как сделать, чтобы и грани (поверхность) объекта были видны, и точки просвечивались?
Изображения
Тип файла: jpg диспетчер-устройств.jpg (86.0 Кб, 32 просмотров)
Тип файла: jpg окно-ошибки.jpg (91.7 Кб, 74 просмотров)
VolodyaBuzin вне форума Ответить с цитированием
Старый 22.09.2019, 09:07   #7
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Архив с проектом берите отсюда:
http://www.cyberforum.ru/delphi-mult...l#post13843381
Свойство NoZWrite для куба в инспекторе не было. Для какого объекта его вообще надо прописывать?
VolodyaBuzin вне форума Ответить с цитированием
Старый 23.09.2019, 13:30   #8
VolodyaBuzin
Пользователь
 
Регистрация: 10.11.2017
Сообщений: 56
По умолчанию

Препод сказал - вывести куб и выставить Ambient.Alpha во фронтах в 0,5. Я вернул первоначальный BlendingMode, а потом сделал это через инспектор объектов и через событие OnCreate для второй формы, но это не помогло.

Код:
procedure TForm2.FormCreate(Sender: TObject);
begin
Form2.GLCube1.Material.FrontProperties.Ambient.Alpha:=0.5;
Form2.GLSphere1.Material.FrontProperties.Ambient.Alpha:=0.5;
end;
То же самое через первую форму дало ошибку.
VolodyaBuzin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Из заданного мн-ва точек на плоскости выбрать 3 разные точки A,B,C так,чтобы внутри треугольника ABC было максимальное число точек Ronin94 Общие вопросы C/C++ 4 02.02.2015 18:31
Перевод кода с Delphi в С++. spectrum988 Помощь студентам 12 17.04.2014 12:13
Задаnm n точек. Найти m=3,4... точек и построить на них m-угольник: количество точек , лежащих внутри и вне его мин. различается L.Rain Помощь студентам 0 11.12.2011 22:19
Написание в Delphi программы для создания и прохождения теста. Fenrix Помощь студентам 2 15.11.2011 07:18
Написание кода в Delphi на создание матриц Chertenok666 Помощь студентам 9 30.11.2009 18:23