Архивировано

Эта тема находится в архиве и закрыта для публикации сообщений.

edweiser

пересечение объектов в OpenGL

Рекомендованные сообщения

Всем доброго времени суток.

у меня вопрос по использованию openGL в Delphi 7. мне нужно отобразить пятно пересечения двух фигур, иными словами есть полупрозрачные пролётный канал(серый) и коллектор(жёлтый) и есть пучёк электронов (синий, построенный в виде огромного числа цилиндров, изменяющих свой радиус в зависимости от координаты), когда пучёк вываливается за пределы коллектора все эти выступающие части необходимо отсечь.

 

(!)не пугайтесь размеров кода, просто там много повторяющихся элементов

 

рисунок для наглядности

 

 

 

пытался реализовать с помощью буфера трафарета, но получается ровно тоже что и до использования этого метода, может где ошибка? правда я не нашёл

подходит ли вообще этот метод к такой реализации?

 

procedure TForm1.FormPaint(Sender: TObject);
const pos:array [0..3] of double=(0.1,0.1,1,1);
FogColor:array [0..3] of double=(0.9,0.9,0.9,1);
var i,k,j,h:integer;
quad,quadDisc:GLUquadricObj;
begin
SetLength(k1,Form8.SG1.RowCount-1,1);
for j:=1 to Form8.SG1.RowCount-1 do
for h:=0 to 1 do
begin
k1[h,j]:=strtofloat(Form8.SG1.Cells[h,j]);
end;
if ProblemSolved then
begin
 wglMakeCurrent (Form1.Canvas.Handle, hrc );
 glViewport(0,0,Form1.ClientWidth,Form1.ClientHeight);
 glDisable(GL_LIGHTING);
 glDisable(GL_FOG);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_BLEND);
 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
 glClearColor ( 0 , 0 , 0,1);
 glClear ( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 glPushMatrix;
 gluPerspective(20.0, ClientWidth/ClientHeight, Scale-1.1, Scale+1.1);
 glTranslate (0,0,-Scale);
 glTranslate(Dx,0,0);
 glTranslate(0,Dy,0);
 if Light then
  begin
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_POSITION,@pos);
  end;
 if Fog Then
  begin
glEnable(GL_FOG);
glFog(GL_FOG_MODE,GL_EXP2);
glFog(GL_FOG_DENSITY,0.7);
  end;
 glRotate(RotX,1,0,0);
 glRotate (RotY,0,1,0);
 glScale(1/10/Rkan,1/10/Rkan,1/(eZ[length-1]-eZ[0]));
 glTranslate(0,0,-1);
 glBegin(GL_LINES);
 glColor3d(1,0,0);
 glVertex3d(-2,0,0);
 glVertex3d (2,0,0);
 glVertex3d(0,-2,0);
 glVertex3d (0,2,0);
 glEnd;
 glColor3d(0,1,1.2);
 glEnable(GL_CULL_FACE);
 quad:=gluNewQuadric;
 quadDisc:=gluNewQuadric;
 Zkan:=StrToFloat(form3.LabeledEdit13.Text);

 glColorMask (false, false, false, false);
 glClear (GL_STENCIL_BUFFER_BIT);
 glEnable (GL_STENCIL_TEST);
 glEnable (GL_CULL_FACE);
 glCullFace (GL_BACK);
 glStencilFunc (GL_ALWAYS, 1, 1);
 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);

  //kollektor
  glColor4d(0.9,0.7,0.2,0.5);
  glPushMatrix;
  glTranslate(0,0,Zkan);
  for j:=1 to Form8.SG1.RowCount-1 do
begin
glTranslate(0,0,k1[1,j]);
gluCylinder(quad,k1[0,j]/10,k1[0,j+1]/10,k1[1,j+1],50,1);
end;
  glPopMatrix;

 glStencilFunc (GL_EQUAL, 1, 1);
 glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);

 //puchek
 for k:=0 to Floor((length-2)/100) do
  begin
  i:=100*k;
  glPushMatrix;
  glTranslate(0,0,(eZ[i]-eZ[0]));
  glPushMatrix;
  glTranslate(eX[i],eY[i],0);
  gluQuadricOrientation(quadDisc,GLU_INSIDE);
  gluDisk(quaddisc,0,R[i+100],35,1);
  gluQuadricOrientation(quad,GLU_INSIDE);
  gluCylinder(quad,R[i],R[i],eZ[i+100]-eZ[i],50,10);
  gluQuadricOrientation(quad,GLU_OUTSIDE);
  glPushMatrix;
  glTranslate(eX[i+10]-eX[i],eY[i+100]-eY[i],eZ[i+10]-eZ[i]);
  gluQuadricOrientation(quadDisc,GLU_OUTSIDE);
  gluDisk(quadDisc,0,R[i+100],35,1);
  glPopMatrix;
  glPopMatrix;
  glPopMatrix;
  end;

 glClear (GL_STENCIL_BUFFER_BIT);
 glEnable (GL_STENCIL_TEST);
 glEnable (GL_CULL_FACE);
 glCullFace (GL_FRONT);
 glStencilFunc (GL_ALWAYS, 1, 1);
 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);

  //kollektor
  glColor4d(0.9,0.7,0.2,0.5);
  glPushMatrix;
  glTranslate(0,0,Zkan);
  for j:=1 to Form8.SG1.RowCount-1 do
begin
glTranslate(0,0,k1[1,j]);
gluCylinder(quad,k1[0,j]/10,k1[0,j+1]/10,k1[1,j+1],50,1);
end;
  glPopMatrix;

 glClear (GL_DEPTH_BUFFER_BIT);
 glDepthFunc (GL_GREATER);
 glStencilFunc (GL_EQUAL, 2, 3);
 glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);

 //puchek
 for k:=0 to Floor((length-2)/100) do
  begin
  i:=100*k;
  glPushMatrix;
  glTranslate(0,0,(eZ[i]-eZ[0]));
  glPushMatrix;
  glTranslate(eX[i],eY[i],0);
  gluQuadricOrientation(quadDisc,GLU_INSIDE);
  gluDisk(quaddisc,0,R[i+100],35,1);
  gluQuadricOrientation(quad,GLU_INSIDE);
  gluCylinder(quad,R[i],R[i],eZ[i+100]-eZ[i],50,10);
  gluQuadricOrientation(quad,GLU_OUTSIDE);
  glPushMatrix;
  glTranslate(eX[i+10]-eX[i],eY[i+100]-eY[i],eZ[i+10]-eZ[i]);
  gluQuadricOrientation(quadDisc,GLU_OUTSIDE);
  gluDisk(quadDisc,0,R[i+100],35,1);
  glPopMatrix;
  glPopMatrix;
  glPopMatrix;
  end;

 glColorMask (true, true, true, true);
 glClear (GL_STENCIL_BUFFER_BIT);
 glDepthFunc (GL_LESS);
 glDisable (GL_CULL_FACE);
 glStencilFunc (GL_EQUAL, 3, 3);
 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);

 //puchek
 glColor3d(0,1,1.2);
 for k:=0 to Floor((length-2)/100) do
  begin
  i:=100*k;
  glPushMatrix;
  glTranslate(0,0,(eZ[i]-eZ[0]));
  glPushMatrix;
  glTranslate(eX[i],eY[i],0);
  gluQuadricOrientation(quadDisc,GLU_INSIDE);
  gluDisk(quaddisc,0,R[i+100],35,1);
  gluQuadricOrientation(quad,GLU_INSIDE);
  gluCylinder(quad,R[i],R[i],eZ[i+100]-eZ[i],50,10);
  gluQuadricOrientation(quad,GLU_OUTSIDE);
  glPushMatrix;
  glTranslate(eX[i+10]-eX[i],eY[i+100]-eY[i],eZ[i+10]-eZ[i]);
  gluQuadricOrientation(quadDisc,GLU_OUTSIDE);
  gluDisk(quadDisc,0,R[i+100],35,1);
  glPopMatrix;
  glPopMatrix;
  glPopMatrix;
  end;

 glDisable(GL_STENCIL_TEST);

 //kanal
 glColor4d(0.9,0.9,0.9,0.5);
 gluQuadricOrientation(quadDisc,GLU_INSIDE);
 gluDisk(quadDisc,0,Rkan,20,1);
 gluQuadricOrientation(quadDisc,GLU_OUTSIDE);
 Zkan:=StrToFloat(form3.LabeledEdit13.Text);
 gluCylinder(quad,Rkan,Rkan,Zkan,20,1);
 glPushMatrix;
 glTranslate(0,0,Zkan);
 gluDisk(quadDisc,0,Rkan,20,1);
 glPopMatrix;

 //kollektor
 glColor4d(0.9,0.7,0.2,0.5);
 glPushMatrix;
 glTranslate(0,0,Zkan);
 for j:=1 to Form8.SG1.RowCount-1 do
begin
glTranslate(0,0,k1[1,j]);
gluCylinder(quad,k1[0,j]/10,k1[0,j+1]/10,k1[1,j+1],50,1);
end;
 glPopMatrix;

 gluDeleteQuadric(quad);
 gluDeleteQuadric(quadDisc);
 SwapBuffers(Form1.Canvas.Handle);
 glPopMatrix;
 wglMakeCurrent ( 0 , 0 );
end;
end;

 

 

 

и ещё один рисунок после применения трафаретов(стрелки указывают на линию между "передней" и "задней" частью объекта)

 

 

 

и вот ещё какая идея возникла, есть ли способ сделать прозрачным ту часть которую нужно отсечь?

 

p.s. да, это не совсем игра, но студентам - электронщикам иногда приходится и такими вещами заниматься;) и огромная просьба давать подробные ответы что и как делать, это мой первый опыт использования OpenGL:) и очень прошу без ссылок, особенно на англоязычные ресурсы, много уже пытался найти по этой теме, но что то всё впустую.....

спасибо за внимание и заранее спасибо за дельные советы:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах