728x90
728x90
728x90

Proland(https://proland.inrialpes.fr/)는 C++, OpenGL로 만들어진 3D Rendering Library이다.


안에 있는 동영상 및 스크린샷등을 보면 이것을 공부해 볼만 한 것 같다.


라이센스는 BSD3 이므로, 그냥 사용하면 될 듯 하다.



728x90

'Visualization Programming > OpenGL' 카테고리의 다른 글

OpenGL - GLM 설치하기.  (0) 2018.08.10
OpenGL - 설치하기  (0) 2018.08.10
728x90

OpenCV에서의 HelloWorld 급 코드를 한번 빌드해보자.


rgba 이미지를 gray 이미지로 변환하는 기본 예제이다.







728x90

'Visualization Programming > OpenCV' 카테고리의 다른 글

OpenCV - 설치하기  (0) 2018.09.01
OpenCV - 개요  (0) 2018.09.01
728x90

다운로드 : https://opencv.org/releases.html


들어가서 원하는 버전을 받으면 된다.


설치하고자 하는 폴더에 설치를 한다.


설치후 환경 변수의 Path에 설치한 경로를 추가해준다.


설치는 완료되었으니 이제 프로그래밍을 시작하면 된다.


728x90

'Visualization Programming > OpenCV' 카테고리의 다른 글

OpenCV - Helloworld  (0) 2018.09.01
OpenCV - 개요  (0) 2018.09.01
728x90

Image Processing은 컴퓨터를 이용하여 입력영상을 보다 질 좋은 출력영상으로 얻는 과정이다. 예를 들면 포토샵을 이용하여 입력영상에 포함된 noise를 제거하거나, 영상의 대비를 개선하여 더욱 선명하게 하는 과정, 영상의 특정 부분을 강조하거나, 관심영역을 분할 하고 영상 파일로 압축하여 저장하는 과정등을 모두 영상처리라고 한다.


Computer Vision은 카메라에 의해 획득되는 입력영상으로부터 의미 있는 정보를 추출해 내는 분야로 주로 실시간 응용프로그램에서 많이 다루고 있다. 예를 들면, 산업현장에서 자동으로 제품의 결함을 검사하거나, 스캐너 또는 카메라로 획득한 영상에서 문자인식, 얼굴인식, 지문인식, 사람 또는 자동차 등과 같은 움직이는 물체 검출 및 물체 추적 등을 모두 컴퓨터 비전이라고 한다.


영상처리와 컴퓨터 비전은 모두 영상을 처리하기 때문에 많은 내용이 중복될 수 밖에 없다. 대략적인 구분으로는 컴퓨터를 사용하여 영상을 처리하는 모든 분야를 영상처리라고 하고, 인간의 눈 대신 카메라에 의한 영상을 입력하고 인간의 뇌 대신에 컴퓨터를 사용하여 영상으로부터 의미 있는 정보를 추출하는 분야를 컴퓨터 비전이라고 생각하면 된다.


OpenCV(Open Computer Vision)은 컴퓨터 비전용 무료 라이브러리이다.


즉, OpenCV는 영상처리, 비디오처리, 기계학습, 컴퓨터 비전 관련 라이브러리로 소스가 공개되어 있고, BSD 라이선스를 따르며, 교육 및 상업 목적의 사용이 모두 무료인 라이브러리이다.



728x90

'Visualization Programming > OpenCV' 카테고리의 다른 글

OpenCV - Helloworld  (0) 2018.09.01
OpenCV - 설치하기  (0) 2018.09.01
728x90

OpenGL 은 기본적으로 Math Class가 없다. (DirectX는 있는데...)


OpenGL 자체가 원래는 시뮬레이션을 위해 만들어진 라이브러리이기 때문에, 이것을 사용하는 개발자들은 기본적으로 엄청

난 수학적 능력을 가졌다고 가정하고 안만들었다는데... 맞나모르겠네 ㅋ


그래서 Math Class를 사용하기 위해 GLM(OpenGL Mathematics)를 설치해야 한다.


1. GLM 다운로드하기

https://glm.g-truc.net/0.9.9/index.html 에 가서 Download를 눌러서 받는다.


2. unzip 압축풀기


3. glm 폴더 복사

압축을 풀면 다음과 같은 폴더들이 있는데, 이 중에서 glm 폴더를 "복사"한다.

glm 폴더를 원하는 곳에 "붙여넣기" 한다.


4. 이제 Visual Studio에서 폴더를 등록하고 사용하자.


출처 : http://justdoitproject.tistory.com/16

728x90

'Visualization Programming > OpenGL' 카테고리의 다른 글

OpenGL - Proland  (0) 2018.11.20
OpenGL - 설치하기  (0) 2018.08.10
728x90

OpenGL을 사용하기 위해서... 설치하려고 사이트들을 다 뒤져보니... 


GLUT를 모두들 설치하라고한다. 하지만 GLUT는 Windows에서는 64bit를 지원하지 않는 듯하다 !!


그래서 GLUT 설치는 하지 않고, Windows 10을 설치할 때 원래 있는 OpenGL 을 이용하기로 마음 먹었다.


현재 버전을 확인해보니 4.5.0 버전이다. 뒤에 버전이 어떻게 될지 모르겠지만 이렇게 공부해야지... ㅎㅎ


공부는 어떻게하지 ㅎㅎ...

728x90

'Visualization Programming > OpenGL' 카테고리의 다른 글

OpenGL - Proland  (0) 2018.11.20
OpenGL - GLM 설치하기.  (0) 2018.08.10
728x90

1. Bounding Box

3D World에서 교차 검사는 매우 중요한 이슈이다. 게임을 예로 들자면, 캐릭터끼리 충돌 검출도 해야하고 마우스 Picking도 해야되고 타격 판정도 해야된다. 이외에도 많이 사용되고 있다.

그래서 캐릭터 모델의 특정 범위, 지형 구조물 등에 충돌 판정을 위한 박스나 단순한 모양의 Bounding Volume을 씌운다.

그렇게 복잡한 메쉬끼리 교차 검사를 하는 것이 아니라 단순한 Volume들 끼리 교차 검사를 하는 것이다.

가장 많이 쓰이는 모양이 box이고, 이 box에는 2가지의 종류가 있다.


2. AABB (Axis-Aligned Bounding Box)


기저 축에 정렬된 충돌 박스로 박스를 이루는 면의 노말 벡터들이 곧 X, Y, Z 축과 일치하는 모양이다.

모델을 이루는 다각형의 X, Y, Z 좌표의 최소 최대를 각 박스의 버텍스로 생성한다.

따라서 회전함에 따라 크기가 계속 변하게 된다.

축에 일치된 모양이기 때문에 AABB끼리의 충돌 검출은 매우 간편하다.



void CheckAABB(BoundingBox targetBox)
{
 if (boundingBox.minPos[0] <= targetBox.maxPos[0] && boundingBox.maxPos[0] >= targetBox.minPos[0] &&
 boundingBox.minPos[1] <= targetBox.maxPos[1] && boundingBox.maxPos[1] >= targetBox.minPos[1] &&
 boundingBox.minPos[2] <= targetBox.maxPos[2] && boundingBox.maxPos[2] >= targetBox.minPos[2])
 {
  aabbCollide = true;
  return;
 }
 aabbCollide = false;
}



3. OBB (Oriented Bounding Box)


AABB와 마찬가지로 박스를 이루는 세 면은 서로 수직이지만 해당 면의 노말 벡터가 X, Y, Z와 일치하지 않는 박스이다.

X, Y, Z와 일치하지 않기 때문에 AABB보다 충돌 검출의 시간 복잡도는 높지만 충돌 박스가 XYZ 좌표를 기준으로 최대, 최소로 계속 변하는 AABB보다 항상 좀 더 fit한 바운딩 박스를 만들 수 있다.


void CheckOBB(BoundingBox targetBox)
{
 double c[3][3];
 double absC[3][3];
 double d[3];
 double r0, r1, r;
 int i;
 const double cutoff = 0.999999;
 bool existsParallelPair = false;
 D3DXVECTOR3 diff = boundingBox.centerPos - targetBox.centerPos;
 
 
 for (i = 0; i < 3; ++i)
 {
  c[0][i] = D3DXVec3Dot(&boundingBox.axis[0], &targetBox.axis[i]);
  absC[0][i] = abs(c[0][i]);
  if (absC[0][i] > cutoff)
   existsParallelPair = true;
 }
 
 
 d[0] = D3DXVec3Dot(&diff, &boundingBox.axis[0]);
 r = abs(d[0]);
 r0 = boundingBox.axisLen[0];
 r1 = targetBox.axisLen[0]* absC[0][0] + targetBox.axisLen[1]* absC[0][1] + targetBox.axisLen[2]* absC[0][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 for (i = 0; i < 3; ++i)
 {
  c[1][i] = D3DXVec3Dot(&boundingBox.axis[1], &targetBox.axis[i]);
  absC[1][i] = abs(c[1][i]);
  if (absC[1][i] > cutoff)
   existsParallelPair = true;
 }
 d[1] = D3DXVec3Dot(&diff, &boundingBox.axis[1]);
 r = abs(d[1]);
 r0 = boundingBox.axisLen[1];
 r1 = targetBox.axisLen[0] * absC[1][0] + targetBox.axisLen[1] * absC[1][1] + targetBox.axisLen[2] * absC[1][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 for (i = 0; i < 3; ++i)
 {
  c[2][i] = D3DXVec3Dot(&boundingBox.axis[2], &targetBox.axis[i]);
  absC[2][i] = abs(c[2][i]);
  if (absC[2][i] > cutoff)
   existsParallelPair = true;
 }
 d[2] = D3DXVec3Dot(&diff, &boundingBox.axis[2]);
 r = abs(d[2]);
 r0 = boundingBox.axisLen[2];
 r1 = targetBox.axisLen[0] * absC[2][0] + targetBox.axisLen[1] * absC[2][1] + targetBox.axisLen[2] * absC[2][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[0]));
 r0 = boundingBox.axisLen[0] * absC[0][0] + boundingBox.axisLen[1] * absC[1][0] + boundingBox.axisLen[2] * absC[2][0];
 r1 = targetBox.axisLen[0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[1]));
 r0 = boundingBox.axisLen[0] * absC[0][1] + boundingBox.axisLen[1] * absC[1][1] + boundingBox.axisLen[2] * absC[2][1];
 r1 = targetBox.axisLen[1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[2]));
 r0 = boundingBox.axisLen[0] * absC[0][2] + boundingBox.axisLen[1] * absC[1][2] + boundingBox.axisLen[2] * absC[2][2];
 r1 = targetBox.axisLen[2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 if (existsParallelPair == true)
 {
  obbCollide = true;
  return;
 }
 
 
 r = abs(d[2] * c[1][0] - d[1] * c[2][0]);
 r0 = boundingBox.axisLen[1] * absC[2][0] + boundingBox.axisLen[2] * absC[1][0];
 r1 = targetBox.axisLen[1] * absC[0][2] + targetBox.axisLen[2] * absC[0][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[2] * c[1][1] - d[1] * c[2][1]);
 r0 = boundingBox.axisLen[1] * absC[2][1] + boundingBox.axisLen[2] * absC[1][1];
 r1 = targetBox.axisLen[0] * absC[0][2] + targetBox.axisLen[2] * absC[0][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[2] * c[1][2] - d[1] * c[2][2]);
 r0 = boundingBox.axisLen[1] * absC[2][2] + boundingBox.axisLen[2] * absC[1][2];
 r1 = targetBox.axisLen[0] * absC[0][1] + targetBox.axisLen[1] * absC[0][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][0] - d[2] * c[0][0]);
 r0 = boundingBox.axisLen[0] * absC[2][0] + boundingBox.axisLen[2] * absC[0][0];
 r1 = targetBox.axisLen[1] * absC[1][2] + targetBox.axisLen[2] * absC[1][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][1] - d[2] * c[0][1]);
 r0 = boundingBox.axisLen[0] * absC[2][1] + boundingBox.axisLen[2] * absC[0][1];
 r1 = targetBox.axisLen[0] * absC[1][2] + targetBox.axisLen[2] * absC[1][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][2] - d[2] * c[0][2]);
 r0 = boundingBox.axisLen[0] * absC[2][2] + boundingBox.axisLen[2] * absC[0][2];
 r1 = targetBox.axisLen[0] * absC[1][1] + targetBox.axisLen[1] * absC[1][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][0] - d[0] * c[1][0]);
 r0 = boundingBox.axisLen[0] * absC[1][0] + boundingBox.axisLen[1] * absC[0][0];
 r1 = targetBox.axisLen[1] * absC[2][2] + targetBox.axisLen[2] * absC[2][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][1] - d[0] * c[1][1]);
 r0 = boundingBox.axisLen[0] * absC[1][1] + boundingBox.axisLen[1] * absC[0][1];
 r1 = targetBox.axisLen[0] * absC[2][2] + targetBox.axisLen[2] * absC[2][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][2] - d[0] * c[1][2]);
 r0 = boundingBox.axisLen[0] * absC[1][2] + boundingBox.axisLen[1] * absC[0][2];
 r1 = targetBox.axisLen[0] * absC[2][1] + targetBox.axisLen[1] * absC[2][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 obbCollide = true;
 return;
}


출처 : http://hoodymong.tistory.com/8

728x90

+ Recent posts