2013-08-23 12 views
13

मैं एक साधारण 3 डी इंजन (एपीआई के किसी भी प्रयोग के बिना) विकसित करता हूं, सफलतापूर्वक अपने दृश्य को दुनिया में बदल देता हूं और अंतरिक्ष देखता हूं लेकिन परिप्रेक्ष्य का उपयोग करके मेरे दृश्य (दृश्य स्थान से) को प्रक्षेपित करने में परेशानी होती है प्रक्षेपण मैट्रिक्स (ओपनजीएल शैली)। मुझे एफओवी, पास और दूर मूल्यों के बारे में निश्चित नहीं है और मुझे जो दृश्य मिलता है वह विकृत हो जाता है। मुझे आशा है कि अगर कोई मुझे निर्देश दे सकता है कि उदाहरण कोड के साथ परिप्रेक्ष्य प्रक्षेपण मैट्रिक्स का निर्माण और उपयोग कैसे करें। किसी भी सहायता के लिए अग्रिम रूप से धन्यवाद।परिप्रेक्ष्य प्रोजेक्शन मैट्रिक्स (कोई एपीआई) कैसे बनाएं

मैट्रिक्स का निर्माण:

double f = 1/Math.Tan(fovy/2); 
return new double[,] { 

    { f/Aspect, 0, 0, 0 }, 
    { 0, f, 0, 0 }, 
    { 0, 0, (Far + Near)/(Near - Far), (2 * Far * Near)/(Near - Far) }, 
    { 0, 0, -1, 0 } 
}; 

मैट्रिक्स उपयोग:

foreach (Point P in T.Points) 
{  
    . 
    .  // Transforming the point to homogen point matrix, to world space, and to view space (works fine) 
    .  

    // projecting the point with getProjectionMatrix() specified in the previous code :  

    double[,] matrix = MatrixMultiply(GetProjectionMatrix(Fovy, Width/Height, Near, Far) , viewSpacePointMatrix); 

    // translating to Cartesian coordinates (from homogen): 

    matrix [0, 0] /= matrix [3, 0]; 
    matrix [1, 0] /= matrix [3, 0]; 
    matrix [2, 0] /= matrix [3, 0]; 
    matrix [3, 0] = 1; 
    P = MatrixToPoint(matrix); 

    // adjusting to the screen Y axis: 

    P.y = this.Height - P.y; 

    // Printing... 
} 
+0

http://www.scratchapixel.com/lessons/3d-basic-rendering:

यह एक/छोड़ दिया सही/ऊपर/नीचे// के पास अब तक मापदंडों (ओपन में प्रयोग किया जाता) पर आधारित है/परिप्रेक्ष्य-और-ऑर्थोग्राफिक-प्रोजेक्शन-मैट्रिक्स मैं पिछले पाठों (प्रोजेक्टिंग पॉइंट्स और 3 डी व्यूइंग) की भी सिफारिश करता हूं। – user18490

उत्तर

23

बाद परिप्रेक्ष्य प्रक्षेपण मैट्रिक्स का एक विशिष्ट implemenation है। और यहाँ सब कुछ OpenGL Projection Matrix

void ComputeFOVProjection(Matrix& result, float fov, float aspect, float nearDist, float farDist, bool leftHanded /* = true */) 
{ 
    // 
    // General form of the Projection Matrix 
    // 
    // uh = Cot(fov/2) == 1/Tan(fov/2) 
    // uw/uh = 1/aspect 
    // 
    // uw   0  0  0 
    // 0  uh  0  0 
    // 0   0  f/(f-n) 1 
    // 0   0 -fn/(f-n) 0 
    // 
    // Make result to be identity first 

    // check for bad parameters to avoid divide by zero: 
    // if found, assert and return an identity matrix. 
    if (fov <= 0 || aspect == 0) 
    { 
     Assert(fov > 0 && aspect != 0); 
     return; 
    } 

    float frustumDepth = farDist - nearDist; 
    float oneOverDepth = 1/frustumDepth; 

    result[1][1] = 1/tan(0.5f * fov); 
    result[0][0] = (leftHanded ? 1 : -1) * result[1][1]/aspect; 
    result[2][2] = farDist * oneOverDepth; 
    result[3][2] = (-farDist * nearDist) * oneOverDepth; 
    result[2][3] = 1; 
    result[3][3] = 0; 
} 
+0

बहुत उपयोगी, धन्यवाद –

+0

क्षमा करें, लेकिन यहां क्या है और आप यहां क्या हैं? उपयोगकर्ता चौड़ाई और उपयोगकर्ता ऊंचाई? – ReX357

+2

@ ReX357 uw = नज़दीक/दाएं, और uh = निकट/शीर्ष, जहां सही क्लिप योजना का समन्वय सही है और शीर्ष शीर्ष क्लिप प्लेन के निर्देशांक हैं। चूंकि उपर्युक्त परिप्रेक्ष्य प्रक्षेपण सममित है, इसलिए सही = आधा क्षैतिज चौड़ाई और ऊपरी ऊर्ध्वाधर ऊंचाई का आधा, फिर uw/uh = शीर्ष/दाएं = ऊंचाई/चौड़ाई = 1/पहलू –

0

एक अन्य समारोह है कि उपयोगी हो सकता है समझाने के लिए एक अच्छा कड़ी है।

static void test(){ 
    float projectionMatrix[16]; 

    // width and height of viewport to display on (screen dimensions in case of fullscreen rendering) 
    float ratio = (float)width/height; 
    float left = -ratio; 
    float right = ratio; 
    float bottom = -1.0f; 
    float top = 1.0f; 
    float near = -1.0f; 
    float far = 100.0f; 

    frustum(projectionMatrix, 0, left, right, bottom, top, near, far); 

} 

static void frustum(float *m, int offset, 
        float left, float right, float bottom, float top, 
        float near, float far) { 

    float r_width = 1.0f/(right - left); 
    float r_height = 1.0f/(top - bottom); 
    float r_depth = 1.0f/(far - near); 
    float x = 2.0f * (r_width); 
    float y = 2.0f * (r_height); 
    float z = 2.0f * (r_depth); 
    float A = (right + left) * r_width; 
    float B = (top + bottom) * r_height; 
    float C = (far + near) * r_depth; 
    m[offset + 0] = x; 
    m[offset + 3] = -A; 
    m[offset + 5] = y; 
    m[offset + 7] = -B; 
    m[offset + 10] = -z; 
    m[offset + 11] = -C; 
    m[offset + 1] = 0.0f; 
    m[offset + 2] = 0.0f; 
    m[offset + 4] = 0.0f; 
    m[offset + 6] = 0.0f; 
    m[offset + 8] = 0.0f; 
    m[offset + 9] = 0.0f; 
    m[offset + 12] = 0.0f; 
    m[offset + 13] = 0.0f; 
    m[offset + 14] = 0.0f; 
    m[offset + 15] = 1.0f; 

} 
संबंधित मुद्दे