2014-02-09 3 views
1

CPU에서 밉맵을 생성하는 기능을 만들고 있습니다. 제 목표는 많은 DXGI_FORMAT에서 작동하는 보편적 인 함수를 작성하는 것입니다. 함수는 모든 DXGI_FORMAT 조합에 대해 동일한 작업을 수행하며 유일한 차이는 데이터 유형이며이를로드하고 저장하는 XMMATH 함수입니다.이 유형을 템플릿 매개 변수로 사용하는 유형 및 기능을 정의합니다.

나는 좋은 방법으로 그것을 한 시도 - 템플릿 매개 변수에 의해, 그렇게 :

#define AVERAGE(p, q) (((p - q) * 0.5f) + q) 

template<typename XMATH_PIXEL_FORMAT, 
     typename XMVECTOR(*XMATH_LOAD_FUNC)(const XMATH_PIXEL_FORMAT*), 
     typename void(*XMATH_STORE_FUNC)(XMATH_PIXEL_FORMAT*, XMVECTOR)> 
void minifyMipMap(XMATH_PIXEL_FORMAT* dst, const XMATH_PIXEL_FORMAT* src, size_t src_x, size_t src_y) { 
    size_t x, y, x2, y2, dst_x = src_x >> 1, dst_y = src_y >> 1; 
    XMVECTOR out, p00, p10, p01, p11; // p:xy 

    for(y = 0; y < dst_y; ++y) { // for each dst line 
    y2 = y << 1; // y2 = y * 2 
    for(x = 0; x < dst_x; ++x) { // for each dst pixel 
     x2 = x << 1; // x2 = x * 2 

     // load 4 pixels 
     p00 = XMATH_LOAD_FUNC(src + y2 * src_x + x2); 
     p10 = XMATH_LOAD_FUNC(src + y2 * src_x + x2 + 1); 
     p01 = XMATH_LOAD_FUNC(src + (y2 + 1) * src_x + x2); 
     p11 = XMATH_LOAD_FUNC(src + (y2 + 1) * src_x + x2 + 1); 

     // blend 4 pixels into 1 
     out = AVERAGE(AVERAGE(p00, p10), AVERAGE(p01, p11)); 

     // store dest pixel 
     XMATH_STORE_FUNC(dst + y * dst_x + x, out); 
    } 
    } 
} 


void test() { 
    BYTE src[] = { 
    0, 0, 0, 255, // black 
    255, 255, 255, 255, // white 
    0, 0, 0, 255, // black 
    255, 255, 255, 255 // white 
    }; 
    XMUBYTE4 dst[1]; // gray ??? 

    minifyMipMap<XMUBYTE4, XMLoadUByte4, XMStoreUByte4>(dst, (const XMUBYTE4*)src, 2, 2); // 2x2 = > 1x1 
} 

MSVC는 말한다 : C2893 : 함수 템플릿 '무효 minifyMipMap (XMATH_PIXEL_FORMAT의 *, const를 XMATH_PIXEL_FORMAT의 *, size_t와 전문 못했습니다,이 size_t를) '다음 템플릿 인수가 : '다이렉트 :: PackedVector :: XMUBYTE4 '

나는 몇 가지 조합이 코드를 컴파일 시도했지만 성공하지 (또한 내가 정적 메서드 매개 변수로 클래스 템플릿 등의 유형 및 기능을 정의하는 시도 이 클래스의,하지만 그것은 또한 실패합니다). 어떻게 든 C++에서 #define을 사용하지 않고 좋은 방법으로 작성할 수 있기를 바랍니다.

+0

void (* XMMATH_STORE_FUNC) (XMATH_PIXEL_FORMAT *, XMVECTOR)는 XMVECTOR가 아닌 두 번째 매개 변수에서 FXMVECTOR 여야하므로 끔찍한 실수를했습니다.이 경고문은 msvc 2012에서 작동합니다. – crayze

답변

2

임의의 함수를 허용하려면이 방법을 사용하지 마십시오. 다른 기능마다 하나의 템플릿 매개 변수를 허용하십시오.

template<typename Func> 
void foo(Func f) { 
    // call f in any way you need 
    f(); 
} 

// can be used like this with functions 
void bla() {} 
f(&bla); 
// Functors 
struct X { void operator()() {} } 
f(X()); 

컴파일러는 코드가 호출하는 방식으로 호출 할 수없는 함수가 전달되면 불평합니다.

사용자에게 실제로 도움이되고 싶다면 static_assert 및 일부 메타 프로그래밍을 사용하여 제한된 개념 검사를 제공 할 수 있습니다.

+0

감사합니다. 대답, 지금은 종종 이런 펑터 클래스를 만듭니다. – crayze

관련 문제