Geek's mimic!/OpenGL2018.10.15 13:30


Linux에서 QT Creator를 이용한 OpenGL 프로그래밍에 대해 글을 올릴 예정이다.


한참을 삽질하다가 좋은 강의 영상을 발견하였고, 해당 저작권자에게 허락을 맡았기에 그 영상을 기초로 OpenGL 프로그래밍에 대해 설명할 예정이다.


총 17개의 강의가 준비되어 있기에 해당 내용을 모두 실습해보고 차근차근 올리도록 하겠다.


아래 URL은 제1강의 URL이다. 글이 올라오기전 탐독하고 싶은 독자들을 위해 남겨둔다.


https://www.youtube.com/watch?v=HgoKrrf4iks


I would like to thank Dmitry Tikhonkikh for sharing the lesson.





'Geek's mimic! > OpenGL' 카테고리의 다른 글

QT Creator를 이용한 OpenGL  (0) 2018.10.15
QT - OpenGL ES , QT Widget과 Shader  (0) 2018.10.12
Posted by kasaku
Geek's mimic!/OpenGL2018.10.12 23:19

QOpenGLWidget

 QT에서 OpenGL 그래픽을 렌더링하기 위한 위젯 클래스로써 QOpenGLWidget은 OpenGL 작업을 수행하기 위해 클래스에서 다시 구현할 수 있는 세 가지 편리한 가상 함수를 제공합니다( paintGL(), resizeGL(), initializeGL() ).

paintGL 

 - OpenGL 화면을 렌더링해주는 함수이며 위젯이 업데이트될 때마다 호출된다.

  * paintGL 함수 외에 다른 곳에서 렌더링 과정을 수정해야할 경우 update() 함수를 이용하여 paint 함수를 호출해주어야 한다. ( QT widget 의 update 함수를 호출하게 되면 결과적으로 QT의 Widget 클래스를 상속하고 있는 QOpenglWidget의 paintGL 함수가 호출되는 것을 의미 )


resizeGL

 - OpenGL 뷰포트, 프로젝션 드을 설정하며 위제싀 크기를 조정할때마다 호출된다. 또한 위젯의 resize 함수와 같이 처음 실행될때도 호출된다.

initialzeGL

 - OpenGL 리소스와 상태를 설정하는 함수이다. resizeGL 또는 paintGL이 처음 호출되기 전에 단 한번 호출된다.


 QOpenGLWidget의 보다 자세한 설명이 필요하다면 아래 링크를 참고하기 바란다.

 - http://doc.qt.io/qt-5/qopenglwidget.html#details


**(Added 181129)

 개인 프로젝트를 만드는 도중 initializeGL(), paintGL() 이 서로 다른 스레드에 의해 동시호출이 된다는 것을 알게 되었다. ( QT Version 4.x )

 정확하게는 initializeGL()를 먼저 호출하지만, initializeGL() 함수를 수행한흔 도중 paintGL() 함수 내용이 실행되었고 그로 인해 충돌이 일어나는 현상을 겪게 되었다.


Shader

 OpenGL에서 Shader는 아래 그림과 같이 Vertex와 Fragment 두가지 형태로 나뉘어져 있다.

각각의 Shader는 결과물을 저장하기 위한 전역 변수인 gl_Position과 gl_FragColor가 존재한다,


gl_Position

 - Vertex Shader에서 자동으로 선언되는 내장변수로, 뷰포트 위치를 지정하는 변수이다.


gl_FragColor

 - Fragment Shader에서 자동으로 선언되는 내장변수로 GLSL 3.1 이후엔 사라졌다. 픽셀의 결과값을 저장하는 변수이다.


이 외에도 Shader에서 자동으로 선언되는 내장변수들이 있지만 기초 강의에서는 사용될 일이 없기에 차후 언급될때 설명을 붙일 예정이며, 참고자료가 필요한 독자분들은 아래 링크를 참고하시기 바란다

 Vertex Shader - https://www.khronos.org/opengl/wiki/Vertex_Shader

 Fragment Shader - https://www.khronos.org/opengl/wiki/Fragment_Shader


'Geek's mimic! > OpenGL' 카테고리의 다른 글

QT Creator를 이용한 OpenGL  (0) 2018.10.15
QT - OpenGL ES , QT Widget과 Shader  (0) 2018.10.12
Posted by kasaku
Geek's mimic!/Algorithm2018.10.05 13:23

Hash와 Hash Function



Hash?

 [U, C] 해시(고기와 감자를 잘게 다져 섞어 요리하여 따뜻하게 차려 낸 것)


고기와 감자를 잘게 다져 섞어 요리하여 따듯하게 차려낸것

즉, 원 재료를 잘게 다져 섞은 뒤 요리한 음식을 의미한다.


이와 같이 Hash function은 데이터를 잘게 다져 섞은 뒤 해쉬 값을 출력하는 함수라고 볼 수 있다.


그렇다면 Hash Table은 무엇일까?


Hash Table



Hash Table은 이름 그대로 Hash(Hash function)을 이용한 Table(자료구조)이다.


앞에서 간략히 설명한 Hash Function을 좀 더 상세히 살펴보자.

Hash Function은 임의의 데이터를 입력받아 고정된 크기의 데이터로 매핑해주는 함수로써

아래 그림은 Hash Function을 간략히 설명한 그림이다.


< 출처, 위키백과 https://ko.wikipedia.org/wiki/해시_함수 >


그림을 보면 알 수 있듯이 "keys"라는 임의의 데이터를 hash function을 거쳐 hashes라는 고정된 크기의 데이터로 변경되는 것을 알 수 있다.


Hash Table은 Hash Function의 특성을 이용하여 입력된 key로 얻어낸 hash 값을 index로 사용하여 Table에 매핑시킴으로써 key에 대한 get function 을 다른 알고리즘보다 빠르게 수행할 수 있게 된다.


예를 들어 트리, 리스트, 그래프, 맵 등 여러 자료구조에서 John Smith라는 값에 대응되는 값(value)를 찾으려고 할 경우 key 값에 J를 먼저 찾게 되고 그 이후 ohn Smith 라는 문자열을 매칭하여 동일한 key의 값(value)를 반환할 것이다.


하지만 Hash Table은 key 값을 index로 사용하게 되므로 단순히 getHashValue("John Smith") 와 같은 함수를 호출하게 되면 John Smith로 생성된 hash index로 Table을 접근하여 value를 반환하게 되므로 다른 알고리즘보다 빠른 결과를 수행하게 된다는 것이다. ( O(n) )


이러한 Hash Table에도 장단점이 있으니 그 부분은 다음 글에 설명하도록 하겠다.


아래는 간단히 만들어본 Hash Table의 예제코드로써 Hash Table의 장단점을 설명할때 사용할 예정이다.


Hash Table 예제



#include "stdafx.h"
#include 

/**@def G_HASH_INDEX_MAX g_hashTable 해시 테이블의 크기*/
#define G_HASH_INDEX_MAX 1000

/**@def M_HASH_INDEX_MAX hashTestSet 해시 테이블의 크기*/
#define M_HASH_INDEX_MAX 5

/**@struct hash 해시 테이블의 노드 구조체 */
struct hash {
	unsigned int key;	/**@var 해시 노드를 접근하기 위한 키 */
	int value;			/**@var value  해시 노드의 값 */
}typedef hash_t;

/**@var g_hashTable 해시 테이블 구현을 위한 해시 배열*/
hash_t g_hashTable[G_HASH_INDEX_MAX];


/**
*@brief 해시 테이블에 접근하기 위한 해시 값을 생성하는 함수
*@details 기초적인 해시 함수로써 입력된 키를 해시 테이블의 크기로 나눈 나머지를 해시 값으로 반환
*@param key 해시테이블에 접근하기 위한 키
*@return 키 값을 통해 도출된 해시 테이블에 접근할 인덱스(해시)
*/
unsigned int hashFunction(unsigned int key) {

	printf("input key[%8d] return hash[%d]\n", key, key % G_HASH_INDEX_MAX);
	return key % G_HASH_INDEX_MAX;
}

/**
*@brief 해시 테이블에 값을 저장하기 위한 함수
*@details 입력된 키와 대응되는 값(value)를 해시 테이블에 저장하는 함수
*@param key 해시테이블에 접근하기 위한 키
*@param value 해시테이블에 저장될 값
*/
void setHash(unsigned int key, int value) {
	unsigned int index = hashFunction(key);

	g_hashTable[index].key = key;
	g_hashTable[index].value = value;

	printf("input key[%8d] set table index[%3d] set table value[%8d] \n", key, index, value);
}

/**
*@brief 해시 테이블에 값을 가져오기 위한 함수
*@details 입력된 키와 대응되는 값(value)를 해시 테이블에서 가져오는 함수
*@param key 해시테이블에 접근하기 위한 키
*@return 입려된 키(key)에 대응되는 값(hash.value)를 반환
*/
int getHash(unsigned int key) {
	unsigned int index = hashFunction(key);

	printf("input key[%8d] get table index[%3d] get table value[%8d] \n", key, index, g_hashTable[index].value);
	return g_hashTable[index].value;
}

int main()
{
	/*@var hashTestSet 해쉬 테이블 변수, M_HASH_INDEX_MAX 만큼 선언*/
	hash_t hashTestSet[M_HASH_INDEX_MAX];

	// 해쉬 테이블 멤버변수를 초기화해주는 과정, 키와 대응되는 값을 알기 쉽게 같은 값으로 설정하였다
	hashTestSet[0].key	 = 65525;
	hashTestSet[0].value = 65525;

	hashTestSet[1].key	 = 34534;
	hashTestSet[1].value = 34534;

	hashTestSet[2].key	 = 633;
	hashTestSet[2].value = 633;

	hashTestSet[3].key	 = 56;
	hashTestSet[3].value = 56;

	hashTestSet[4].key	 = 3234645;
	hashTestSet[4].value = 3234645;

	printf("================= Start setHash Function =================\n");
	for (int i = 0; i < M_HASH_INDEX_MAX; i++) {
		setHash(hashTestSet[i].key, hashTestSet[i].value);
	}
	printf("=================  End  setHash Function =================\n\n");

	printf("================= Start getHash Function =================\n");
	for (int i = 0; i < M_HASH_INDEX_MAX; i++) {
		getHash(hashTestSet[i].key);
	}
	printf("=================  End  getHash Function =================\n");

    return 0;
}



여담. . .



hash table과 hash map 네이밍에 대한 고찰

 사실 인터넷상에 나와있는 hash table 구조들을 보면 key -> index -> value 의 자료구조를 가지고 있는 것을 알 수 있다. 식자는 이 부분에 대해 table이란 index -> value의 구조인 array형태라고 생각하며 map은 key -> index -> value의 형태로 생각하고 있었다.


 다만 흔히 알고 있는 hash table과 hash map은 모두 key -> index -> value의 형태이며 정적이냐 동적이냐의 차이와 자바에서는 동기화냐 비동기화냐에 대한 개념을 가지고 분류를 하고 있는 것으로 보인다.


 만약 이 글을 읽고 있는 독자분들 중 hash table과 hash map에 대한 정확한 분류 기준에 대해 아시는 분이 있다면 정보를 공유를 부탁하는 바이다.



'Geek's mimic! > Algorithm' 카테고리의 다른 글

Hash Table  (0) 2018.10.05
Posted by kasaku