opengl 은 임의의 두 점 사이 에 원기둥 을 그립 니 다.
1.문제 제기
두 시 사이 에 선 을 그 는 것 은 간단 하 다.
glBegin(GL_LINES); //주의 하 세 요.LINES 입 니 다.LINE 이 아 닙 니 다.이 잘못 은 반드시 주의해 야 합 니 다.
glVertexf(x1, y1, z1);
glVertexf(x2, y2, z2);
glEnd();
화 선 함 수 는 opengl 의 행렬 스 택 에 영향 을 주지 않 습 니 다.
그러나 라인 효과 가 비교적 좋 지 않 을 때 가 많 습 니 다.예 를 들 어 저 는 뼈 애니메이션 을 하려 고 합 니 다.관절 점 간 의 뼈 는 라인 을 사용 하 는 것 이 너무 보기 싫 습 니 다.glLine Width 로 선 폭 을 설정 하 더 라 도 시각 적 효 과 는 엉망 입 니 다.그리고 분 형 을 이용 해 3D 트 리 를 그 릴 때 도 줄기 가 선(와 이 드 라인)으로 그 려 져 효과 가 좋 지 않 았 다.그래서 이때 하나의 함 수 를 실현 해 야 합 니 다.3D 공간 에서 임의의 두 점 사 이 를 기하학 적 으로 그립 니 다.저 는 다음 에 방향 을 소개 하 겠 습 니 다.
2.원리 소개
A(x1,y1,z1),B(x2,y2,z2)사이 에 원통 체 를 그 리 려 면 먼저 원점 에서 Y 축 방향 을 따라 기하학 적 그리 기 를 완성 한 다음 AB 벡터 방향 으로 회전 한 다음 A 점 으로 평평 하 게 이동 합 니 다.관건 은 회전 행렬 의 계산 에 있어 벡터 차 승:AB 벡터 와 Y 축 단위 벡터 차 승 으로 오른손 side 벡터 를 계산 한 다음 에 side 단위 화,side 와 AB 차 승 으로 최종 up 방향 을 계산한다.
코드 는 다음 과 같 습 니 다:
void RenderBone(float x0, float y0, float z0, float x1, float y1, float z1 )
{
GLdouble dir_x = x1 - x0;
GLdouble dir_y = y1 - y0;
GLdouble dir_z = z1 - z0;
GLdouble bone_length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
static GLUquadricObj * quad_obj = NULL;
if ( quad_obj == NULL )
quad_obj = gluNewQuadric();
gluQuadricDrawStyle( quad_obj, GLU_FILL );
gluQuadricNormals( quad_obj, GLU_SMOOTH );
glPushMatrix();
//
glTranslated( x0, y0, z0 );
//
double length;
length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
if ( length < 0.0001 ) {
dir_x = 0.0; dir_y = 0.0; dir_z = 1.0; length = 1.0;
}
dir_x /= length; dir_y /= length; dir_z /= length;
GLdouble up_x, up_y, up_z;
up_x = 0.0;
up_y = 1.0;
up_z = 0.0;
double side_x, side_y, side_z;
side_x = up_y * dir_z - up_z * dir_y;
side_y = up_z * dir_x - up_x * dir_z;
side_z = up_x * dir_y - up_y * dir_x;
length = sqrt( side_x*side_x + side_y*side_y + side_z*side_z );
if ( length < 0.0001 ) {
side_x = 1.0; side_y = 0.0; side_z = 0.0; length = 1.0;
}
side_x /= length; side_y /= length; side_z /= length;
up_x = dir_y * side_z - dir_z * side_y;
up_y = dir_z * side_x - dir_x * side_z;
up_z = dir_x * side_y - dir_y * side_x;
//
GLdouble m[16] = { side_x, side_y, side_z, 0.0,
up_x, up_y, up_z, 0.0,
dir_x, dir_y, dir_z, 0.0,
0.0, 0.0, 0.0, 1.0 };
glMultMatrixd( m );
//
GLdouble radius= 20; //
GLdouble slices = 8.0; //
GLdouble stack = 3.0; //
gluCylinder( quad_obj, radius, radius, bone_length, slices, stack );
glPopMatrix();
}
위의 코드 는 원기둥 을 그립 니 다.glu 기하학 적 라 이브 러 리 를 사 용 했 습 니 다.다른 기하학 적 라 이브 러 리 를 그립 니 다.예 를 들 어 사각 뿔 이나 다른 기하학 적 라 이브 러 리 는 아래 의 프레임 만 수정 해 야 합 니 다.
void RenderBone(float x0, float y0, float z0, float x1, float y1, float z1 )
{
GLdouble dir_x = x1 - x0;
GLdouble dir_y = y1 - y0;
GLdouble dir_z = z1 - z0;
GLdouble bone_length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
glPushMatrix();
//
glTranslated( x0, y0, z0 );
//
double length;
length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
if ( length < 0.0001 ) {
dir_x = 0.0; dir_y = 0.0; dir_z = 1.0; length = 1.0;
}
dir_x /= length; dir_y /= length; dir_z /= length;
GLdouble up_x, up_y, up_z;
up_x = 0.0;
up_y = 1.0;
up_z = 0.0;
double side_x, side_y, side_z;
side_x = up_y * dir_z - up_z * dir_y;
side_y = up_z * dir_x - up_x * dir_z;
side_z = up_x * dir_y - up_y * dir_x;
length = sqrt( side_x*side_x + side_y*side_y + side_z*side_z );
if ( length < 0.0001 ) {
side_x = 1.0; side_y = 0.0; side_z = 0.0; length = 1.0;
}
side_x /= length; side_y /= length; side_z /= length;
up_x = dir_y * side_z - dir_z * side_y;
up_y = dir_z * side_x - dir_x * side_z;
up_z = dir_x * side_y - dir_y * side_x;
//
GLdouble m[16] = { side_x, side_y, side_z, 0.0,
up_x, up_y, up_z, 0.0,
dir_x, dir_y, dir_z, 0.0,
0.0, 0.0, 0.0, 1.0 };
glMultMatrixd( m );
// Y
renderGeometryInYAxis();
glPopMatrix();
}
위의 renderGeometry InYaxis()에 주의 하 십시오.Y 축 에 기 하 체 를 그 려 야 합 니 다.3.테스트 코드:
#include <gl/glut.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
void init(void);
void reshape(int w,int h);
void display(void);
void RenderBone(float x0, float y0, float z0, float x1, float y1, float z1 );
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow("Sphere");
init ();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glClearDepth(1);
glShadeModel(GL_SMOOTH);
GLfloat _ambient[]={1.0,1.0,1.0,1.0};
GLfloat _diffuse[]={1.0,1.0,0.0,1.0};
GLfloat _specular[]={1.0,1.0,1.0,1.0};
GLfloat _position[]={200,200,200,0};
glLightfv(GL_LIGHT0,GL_AMBIENT,_ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,_diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,_specular);
glLightfv(GL_LIGHT0,GL_POSITION,_position);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 500, 0.0, 500, -500, 500);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void display(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
{
RenderBone(100, 100, 100, 200, 300, 500);
} glPopMatrix();
glFlush();
glutPostRedisplay();
}
void RenderBone(float x0, float y0, float z0, float x1, float y1, float z1 )
{
GLdouble dir_x = x1 - x0;
GLdouble dir_y = y1 - y0;
GLdouble dir_z = z1 - z0;
GLdouble bone_length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
static GLUquadricObj * quad_obj = NULL;
if ( quad_obj == NULL )
quad_obj = gluNewQuadric();
gluQuadricDrawStyle( quad_obj, GLU_FILL );
gluQuadricNormals( quad_obj, GLU_SMOOTH );
glPushMatrix();
//
glTranslated( x0, y0, z0 );
//
double length;
length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
if ( length < 0.0001 ) {
dir_x = 0.0; dir_y = 0.0; dir_z = 1.0; length = 1.0;
}
dir_x /= length; dir_y /= length; dir_z /= length;
GLdouble up_x, up_y, up_z;
up_x = 0.0;
up_y = 1.0;
up_z = 0.0;
double side_x, side_y, side_z;
side_x = up_y * dir_z - up_z * dir_y;
side_y = up_z * dir_x - up_x * dir_z;
side_z = up_x * dir_y - up_y * dir_x;
length = sqrt( side_x*side_x + side_y*side_y + side_z*side_z );
if ( length < 0.0001 ) {
side_x = 1.0; side_y = 0.0; side_z = 0.0; length = 1.0;
}
side_x /= length; side_y /= length; side_z /= length;
up_x = dir_y * side_z - dir_z * side_y;
up_y = dir_z * side_x - dir_x * side_z;
up_z = dir_x * side_y - dir_y * side_x;
//
GLdouble m[16] = { side_x, side_y, side_z, 0.0,
up_x, up_y, up_z, 0.0,
dir_x, dir_y, dir_z, 0.0,
0.0, 0.0, 0.0, 1.0 };
glMultMatrixd( m );
//
GLdouble radius= 20; //
GLdouble slices = 8.0; //
GLdouble stack = 3.0; //
gluCylinder( quad_obj, radius, radius, bone_length, slices, stack );
glPopMatrix();
}
최종 효과 도:이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
3D 게임 엔진 학습 2 (HelloWorld 소스 분석)프로젝트 구조 box에서.gpb 마운트 장면 장면 카메라의 화면 비율 설정 마운트된 장면에서 방향광 노드 발견 라이트 객체 확보 불러오는 장면에서box라는 모델 노드 가져오기 노드 모델 대상 획득 설정 모형의 재질은...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.