기본적으로 minGW 를 설치 하면 포함 되어 있는 OpenGL header 버젼은 1.2 대 버젼으로 현재 4.0 헤더가 크로노스 그룹에서 공개 된 걸 생각하면 한참이나 구시대의 유물인 상태 이다. 사실 이걸로는 GeForce2 나 RadeonX 시절의 pixel shader 없는 심심한 그래픽이나 그리는거 말곤 할수 있는게 없다.
이번엔 FLTK 에서 OpenGL shader programming 을 통한 YUV422 이미지를 Programming Object ARB 를 이용하여 texture 1+2+3 을 겹쳐 하나의 완성된 이미지로 만들어 내는걸 해 보기로 하면서 기본 MinGW 에서 수정 되어야 할 점과, OpenGL 프로그래밍을 할때 추가 해야 하는 부분들을 정리 해 보도록 하겠다.
먼저 기본 minGW 를 설치 한 상태에서 다음 URL 에서 4개의 header 파일을 받는다.
https://www.opengl.org/registry/#headers
<GL/glext.h> - OpenGL 1.2 and above compatibility profile and extension interfaces.
<GL/glcorearb.h> - OpenGL core profile and ARB extension interfaces, as described in appendix G.2 of the OpenGL 4.3 Specification. Does not include interfaces found only in the compatibility profile.
<GL/glxext.h> - GLX 1.3 and above API and GLX extension interfaces.
<GL/wglext.h> - WGL extension interfaces.
이제 이것을 minGW 가 설치 되어 있는 위치를 참조 하여 include/gl 안에 모두 덮어 쒸어 준다. (혹시나 하면 기존의 header 들은 모두 압축 해 둔다)
예) C:\MinGW 에 설치 된 것이라면 다음과 같음 : C:\MinGW\include
이걸로 준비는 끝.
혹시나 lib 안에 있는 libopengl32.a 를 변경 해야 하거나 할것 같지만 ... 안해도 된다.
다만, OpenGL 확장의 ARB 뭐시기 들어가는 함수들은 모두 동적인 할당을 해서 써야 한다.
예를 들어 다음과 같은 함수들.
glActiveTexture() 나, glCreateProgramObjectARB() 와 같은걸 쓰려면 이걸 먼저 할당하고 wglGetProcAddress() 로 함수 포인터를 지정해 주어야 한다.
고로 다음과 같은 코드를 만들어 쓰자.
#include <FL⁄gl.h>
#include <GL⁄gl.h>
#include <GL⁄glu.h>
#include <GL⁄glext.h>
⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄
PFNGLACTIVETEXTUREPROC glActiveTexture = NULL;
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL;
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
PFNGLUNIFORM4FARBPROC glUniform4fARB = NULL;
PFNGLUNIFORM3FARBPROC glUniform3fARB = NULL;
PFNGLUNIFORM1FARBPROC glUniform1fARB = NULL;
PFNGLUNIFORM1IARBPROC glUniform1iARB = NULL;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB = NULL;
PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB = NULL;
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB = NULL;
⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄
static bool loadGLShaderExt = false;
⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄⁄
void initShaderExtentions()
{
if ( loadGLShaderExt == true )
return;
char* glverstr = (char*)glGetString( GL_VERSION );
if ( glverstr == NULL )
return;
char* glextstr = (char*)glGetString( GL_EXTENSIONS );
if ( glextstr == NULL )
return;
if ( strstr( glextstr, "GL_ARB_shading_language_100") == NULL )
{
return;
}
glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)wglGetProcAddress("glUniform4fARB");
glUniform3fARB = (PFNGLUNIFORM3FARBPROC)wglGetProcAddress("glUniform3fARB");
glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)wglGetProcAddress("glGetAttribLocationARB");
glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)wglGetProcAddress("glVertexAttrib3fARB");
glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)wglGetProcAddress("glVertexAttribPointerARB");
glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)wglGetProcAddress("glEnableVertexAttribArrayARB");
glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)wglGetProcAddress("glDisableVertexAttribArrayARB");
loadGLShaderExt = true;
}
이렇게 할 경우 iniShaderExtentions(); 를 main 등에서 최초 호출 하게 되면 Shader programming 에 써야 할 기본적인 함수들을 할당해서 쓸 수 있게 된다. 단, 이걸 먼저 하려면 wglCreateContext(); 나 wglMakeCurrent(); 를 먼저 불러 줘야 한다.
FLTK 를 쓸 경우 Fl_Gl_Window 를 상속받아 만들어 지는 부분에선 이걸 절대 생성자에서 호출 할 수 없는 문제가 있다 (내부적으로 wgl 초기화 함수 등이 호출이 안되므로 glGetString() 에서 항상 NULL 이 돌아 옴 ... )