PMG
https://forum.pmg.org.ru/

Буфер трафарета + буфер глубины
https://forum.pmg.org.ru/viewtopic.php?f=1&t=7246
Страница 1 из 1

Автор:  globus10 [ 19 ноя 2009 21:34 ]
Заголовок сообщения:  Буфер трафарета + буфер глубины

Доброго времени суток. Моделируется процесс обработки детали на токарном станке. Заготовка является сплошным телом цилиндрической формы. Необходимо показать процесс снятия припуска, т.е. очередного слоя, подлежащего удалению. Сразу отмечу, что не имею опыта работы с OpenGL, поэтому буду благодарен любой критике касательно логики программы. Мой алгоритм такой:

1) Заполнил в цикле заготовку как сплошное тело, т.е. в буквальном смысле винтовой линией чертил вершину, установив для нее (вершины) крупный размер (glPointSize). Естественно, уменьшал радиус винтовой линии после каждого прохода. Весь этот цикл писал в буфер трафарета, как бы заполняя всю сплошную область единичками.

2) Снял припуск, т.е. прошел винтовой линией в цикле часть заготовки, заполняя данную область в буфере трафарета двойками. Таким образом, получил в буфере трафарета обработанную деталь (т.е. то, что осталось от заготовки), заполненную единицами, а слой припуска - двойками.

Теперь вопрос. Как показать область в буфере трафарета, заполненную единицами?
Понятно, что очищал буферы цвета и глубины и настраивал вывод glStencilFunc(GL_EQUAL, 1, 255). Пробовал проходить винтовой линией в цикле, как будто заново рисуя заготовку, надеясь, что останется область, где только единицы. Однако облать, заполненная двойками, не позволяет просматривать то, что осталось за ней, т.е. часть области, заполненную единицами. Экспериментировал с буфером глубины, однако результата не добился.

Код:
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#include <windows.h>

#include <stdlib.h>
#include <math.h>

#include "gl\gl.h"
#include "gl\glu.h"
#include "gl\glut.h"
#include "gl\glaux.h"

// Определяется константа со значением PI
#define GL_PI 3.1415f
void SetupRC (void)
    {
     glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
     glClearStencil(0);
    }
// Вызывается для рисования сцены
void RenderScene (void)
    {
     GLfloat x, y, z, angle; // Здесь хранятся координаты и углы
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
     glPushMatrix ();
     glRotatef ( 45.0, 1.0f, 0.0f, 0.0f );
     glRotatef ( 60.0, 0.0f, 1.0f, 0.0f );
     glTranslated (0, 0, -70);     
     glEnable(GL_POINT_SMOOTH);

        glEnable( GL_STENCIL_TEST );        // разрешаем тест трафарета
        glStencilFunc( GL_ALWAYS, 1, 0 );
        glStencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );

        glColor4f( 0.75f, 0.75f, 0.75f, 1.0f );
        GLfloat a = 120.0f, r = 30.0f, l = 25.0f, ang = 0.0f;
        glPointSize(10.0);
        z     = 0.0f;
        angle = 0.0f;
        while ( r > 0 ) {

         while ( z <= a ) {
            x = ( r ) * sin( angle );
            y = ( r ) * cos( angle );
           glBegin( GL_POINTS );
            glVertex3f( x, y, z );
           glEnd();
            angle += 0.017f;
            // торец 1
            if ( angle <= 2*GL_PI ) {
               z = 0.0f;
               continue;
            }
            z = 0.3 * angle;
            // торец 2
            if ( z >= a && ang <= 2*GL_PI ) {
               z = a;
               ang += 0.017f;
               continue;
              }
         }
         z     = 0.0f;
         angle = 0.0f;
         ang = 0.0f;
         r -= 1.0f;
        }

        glStencilFunc(GL_ALWAYS, 2, 0);
        glStencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );

        glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
           // снимаем припуск
           z     = 0.0f;
           angle = 0.0f;
           r     = 30.0f;
         while ( z <= l ) {
            x = ( r ) * sin( angle );
            y = ( r ) * cos( angle );
           glBegin( GL_POINTS );
            glVertex3f( x, y, z );
           glEnd();
            angle += 0.017f;
            z = 0.3 * angle;
         }

         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

         glStencilFunc(GL_EQUAL, 1, 255);



        glColor4f( 0.75f, 0.75f, 0.75f, 1.0f );
        a = 120.0f, r = 30.0f, l = 25.0f, ang = 0.0f;
        z     = 0.0f;
        angle = 0.0f;
        while ( r > 0 ) {
             /*
          glDepthFunc( GL_ALWAYS );
          //glDepthMask(GL_TRUE);
         if ( r == 30.0f ) {
            glDepthFunc( GL_NEVER );
            //glDepthMask(GL_FALSE);
          };                                 */

         while ( z <= a ) {

            x = ( r ) * sin( angle );
            y = ( r ) * cos( angle );
           glBegin( GL_POINTS );
            glVertex3f( x, y, z );
           glEnd();
            angle += 0.017f;
            // торец 1
            if ( angle <= 2*GL_PI ) {
               z = 0.0f;
               continue;
            }
            z = 0.3 * angle;
            // торец 2
            if ( z >= a && ang <= 2*GL_PI ) {
               z = a;
               ang += 0.017f;
               continue;
              }
         }
         z     = 0.0f;
         angle = 0.0f;
         ang = 0.0f;
         r -= 1.0f;
        }

        glutSwapBuffers();
        glPopMatrix();
       
  }
//---------------------------------------------------------------------//
void ChangeSize(GLsizei w, GLsizei h)
{
   GLfloat nRange = 100.0f;
   if (h == 0) {
     h = 1;
   }
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   if (w <= h) {
      glOrtho (-nRange, nRange, -nRange * h / w, nRange * h / w,
      -nRange, nRange);
   }
   else
      glOrtho (-nRange * w / h, nRange * w / h, -nRange, nRange,
      -nRange, nRange);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

}
//--------------------------------------------------------------------//
void Keyboard(unsigned char key, int x, int y)
{
#define ESCAPE '\033'

   if (key == ESCAPE)
      exit(0);
}
//-------------------------------------------------------------------//
void main(int argc, char* argv[])
{

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STENCIL | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(380, 170);
    glutCreateWindow("Process");

    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize);
    glutKeyboardFunc(Keyboard);
    SetupRC ();

    glEnable(GL_DEPTH_TEST);

    glutMainLoop();
}

Автор:  MagicWolf [ 20 ноя 2009 11:58 ]
Заголовок сообщения:  Re: Буфер трафарета + буфер глубины

Не знаю зачем здесь трафарет. Мне кажется надо иметь одну модель заготовки и по мере снятия припуска делать ее трансформирование, добавляя или удаляя грани. Можно морфингом. Имеем две модели без припуска и с припуском с одинаковым количеством точек. Каждой точке модели без припуска ставим в соответствие модель с припуском и по мере снятия припуска рассчитываем промежуточную модель, где положение точек припуска задается на прямой проведенной между точкой без припуска и с припуском.

Автор:  globus10 [ 20 ноя 2009 13:43 ]
Заголовок сообщения:  Re: Буфер трафарета + буфер глубины

Большое спасибо. Почитал про морфинг, все на свои места встало:)

Страница 1 из 1 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/