2016-10-11 5 views
0

현재 OpenGL 쉐이더 클래스를 작성 중입니다. 각각의 유니폼 타입을 설정하는 기능을 사용하는 대신, 유니폼 함수 (예 : glUniform1f)를 매개 변수로 전달하려고합니다. 그것을 할 수glUniform 함수를 매개 변수로 전달 (C++)

cannot convert argument 1 from 'void (__stdcall *)(GLint,GLfloat)' to 'void (__cdecl *)(GLint,GLfloat)' 

:

template <typename T1> 
void Shader::setUniform(void (* fnc)(GLint, T1), const GLchar *name, const T1 value1) 
{ 
    fnc(getUniformLocation(name), value1); 
} 

그러나, 나는 끊임없이 받고 있어요 변환 오류

shader.setUniform<GLfloat>(*glUniform1f, "test", 5); 

호출 같은 :

나의 현재의 시도는 다음과 같이 보입니다 의도 한대로 작동합니까?

감사

참고 :이 가끔 주석됩니다

+0

OpenGL에 익숙하지 않지만 함수 포인터 대신'std :: function'을 통해 함수를 전달하려고 시도한 적이 있습니까? – Exagon

+0

아직 없습니다. –

+2

더 나은 질문은 ... 왜하고 싶습니까? 당신의 목표는'glUniform' 계열의 함수를위한 템플릿 래퍼를 갖는 것 같습니다. 그러나 그것을하기위한 당신의 방법은 사용자가 타입 (''GLfloat'')와 함수 포인터를 전달할 것을 요구합니다. 당신이하려고하는 것처럼 보이는 것을하는 우수한 방법이 있어야합니다. –

답변

3

기능 포인터 (DLL에서 직접로드 기능을 반환하는 사람들 특히) OpenGL을 로딩 라이브러리에서 중요하다면 내가 GLEW를 사용 glfw 해요 일반 함수 포인터에서 다른 호출 규칙.

이러한 함수 포인터는 이 아니고 전환 할 수 없습니다.

두 가지 방법으로 문제를 해결할 수 있습니다. 다른 OpenGL 로딩 라이브러리를 사용할 수 있습니다.이 라이브러리는 표준 호출 규칙을 사용하는 함수 포인터를 처리합니다 (본질적으로로드하는 실제 포인터를 숨김). 예를 들어 my glLoadGen loader에서 func_cpp 생성기 스타일을 사용하면 모든 함수가 일반 C++ 함수가됩니다.

그렇지 않으면 로더 작동 방식에 맞게 인터페이스에서 함수 포인터가 선언 된 방법을 변경해야합니다. 당신이 GLEW를 사용하는 경우 예를 들어, 당신은 이런 식으로 뭔가를해야 할 것 :

void Shader::setUniform(void (GLAPIENTRY* fnc)(GLint, T1), const GLchar *name, const T1 value1) 
1

당신은 등이 규칙을 호출, 함수 포인터 구문을 다루는로부터 자신을 살려주는뿐만 아니라 펑터의 형태에 기능을 템플리트 수 버전은 문서화 된 인수 (함수, 함수 객체, 람다 등)로 호출 할 수있는 모든 것을 허용합니다. 그것은 동시에 주요 강점과 약점입니다. 컨셉을 통한 타입 제한은 다음 버전의 C++ 표준에서 소개 될 것입니다.

template <typename F, typename T1> 
// requires: F callable with parameter types GLint, T1 
void Shader::setUniform(F fnc, const GLchar* name, const T1 value1) { 
    fnc(getUniformLocation(name), value1); 
} 

int main() { 
    ... 
    shader.setUniform(glUniform1f, "foo", 3.14f); 
} 

나는 여전히 종류의 이름과 모든 매개 변수를 기능이 정말 사용자로 많이 변경되지 않습니다, 의견에 동의합니다. 더 많은 "객체 지향"접근법은 유니폼에 템플릿 기반 클래스를 도입하고 인수 유형별로 특수화하는 것일 수 있습니다 (많지 않음).

관련 문제