2012-03-12 7 views
15

के त्रुटि कोड के साथ विफल रहता है मुझे एक वर्दी 4x4 मैट्रिक्स को बांधने की कोशिश करने में कुछ दुर्भाग्य है। मैं इस कार्यक्रम के साथ ओपनजीएल 3.3 को लक्षित कर रहा हूं, लेकिन मेरा पर्यावरण ओपनजीएल 4.2 है। मेरे पास एक ऐसा फ़ंक्शन है जो मेरे वर्टेक्स शेडर में एक वर्दी में पहचान मैट्रिक्स को बांधता है, लेकिन glUniformMatrix4fv पर कॉल GL_INVALID_OPERATION के साथ विफल रहता है।glUniformMatrix4fv GL_INVALID_OPERATION

यहाँ मेरी शीर्ष शेडर है:

#version 330 
in vec4 in_vertex; 
uniform mat4 mvMatrix; 
void main(void) { 
    gl_Position = mvMatrix * in_vertex; 
} 

मैं मैट्रिक्स स्थानांतरण और बाएँ/सही गुणा करने का नुकसान के बारे में पता है, लेकिन मैं समझ है कि जब मैं वास्तव में एक समान मैट्रिक्स पारित कर सकते हैं के लिए एक लड़ाई है।

यहां एक साधारण कार्य है जिसे उस कार्य में संदर्भित किया गया है जहां मुझे समस्याएं आ रही हैं। मैं केवल इस जगह का उपयोग कर रहा हूं जहां त्रुटि होती है, जहां त्रुटि होती है।

: चूंकि glUniformMatrix4fv के मूल्यांकन सभी सर्वर साइड पर है, मैं breakpoints उपयोग करने के लिए एक तरह से, आदि

inline void die_on_gl_error(const char* location) { 
    GLenum error = GL_NO_ERROR; 
    error = glGetError(); 
    if (GL_NO_ERROR != error) { 
     printf("GL Error %x encountered in %s.\n", error, location); 
     exit(1); 
    } 
} 

SDK docs कहना है कि कुछ कारणों से glMatrixUniform4fv GL_INVALID_OPERATION सेट कर सकते हैं कि नहीं है

  1. यदि कोई वर्तमान प्रोग्राम ऑब्जेक्ट नहीं है तो GL_INVALID_OPERATION उत्पन्न होता है।
  2. GL_INVALID_OPERATION उत्पन्न होता है यदि शेडर में घोषित वर्दी चर का आकार glUniform कमांड द्वारा इंगित आकार से मेल नहीं खाता है।
  3. GL_INVALID_OPERATION उत्पन्न होता है यदि इस फ़ंक्शन के पूर्णांक प्रकारों में से एक का उपयोग फ्लोट, वीसी 2, वीसी 3, वीसी 4, या इनमें से एक सरणी के समान चर लोड करने के लिए किया जाता है, या यदि इस फ़ंक्शन के फ़्लोटिंग-पॉइंट वेरिएंट में से एक है टाइप int, ivec2, ivec3, या ivec4, या इनमें से एक सरणी के एक समान चर लोड करने के लिए प्रयोग किया जाता है।
  4. GL_INVALID_OPERATION उत्पन्न होता है यदि स्थान वर्तमान प्रोग्राम ऑब्जेक्ट के लिए एक अवैध वर्दी स्थान है और स्थान -1 के बराबर नहीं है।
  5. गिनती VALID_OPERATION उत्पन्न होता है यदि गणना 1 से अधिक है और संकेतित वर्दी चर एक सरणी चर नहीं है।
  6. GL_INVALID_OPERATION उत्पन्न होता है यदि नमूना को glUniform1i और glUniform1iv के अलावा किसी अन्य कमांड का उपयोग करके लोड किया जाता है।
  7. GL_INVALID_OPERATION उत्पन्न होता है यदि glUniform को glbegin के निष्पादन और glEnd के संबंधित निष्पादन के बीच निष्पादित किया जाता है।

संदर्भ के लिए, जिस ऑब्जेक्ट से इस फ़ंक्शन को बुलाया जाता है वह एक पैरामीटर है जिसे सक्रिय_प्रोग्राम कहा जाता है जो वर्तमान में सक्रिय जीएलएसएल प्रोग्राम की संख्या संग्रहीत करता है। identity_matrix के रूप में घोषित किया जाता है:

float identity_matrix[16]; 

और के रूप में परिभाषित: आगे की हलचल के बिना

identity_matrix = { 
      1.0f, 0.0f, 0.0f, 0.0f, 
      0.0f, 1.0f, 0.0f, 0.0f, 
      0.0f, 0.0f, 1.0f, 0.0f, 
      0.0f, 0.0f, 0.0f, 1.0f 
}; 

, यहाँ क्या मुझे परेशानी दे रही है:

void VSGL::load_identity_matrix() { 
// GL_INVALID_OPERATION is generated if there is no current program object. 
if (!glIsProgram(active_program)) { 
    printf("Active program is not valid.\n"); 
    exit(1); 
} 

// ... active_program is a program, but is it valid? 
GLint program_valid = 0; 
glValidateProgram(active_program); 
glGetProgramiv(active_program, GL_VALIDATE_STATUS, &program_valid); 
if (GL_TRUE != program_valid) { 
    printf("Program validation failed.\n"); 
    exit(1); 
} 
die_on_gl_error("GetProgram (Validate Status)"); 

// ... makes sure there is a program active, and the current program matches 
// the value stored in active_program. 
GLint current_program = 0; 
glGetIntegerv(GL_CURRENT_PROGRAM, &current_program); 
if (0 == current_program) { 
    printf("Error, no current program is set.\n"); 
    exit(1); 
} else if (current_program != active_program) { 
    printf("Error, current program doesn't match active_program!\n"); 
} 
die_on_gl_error("GetInteger"); 

// ... ensures the program actually has an active uniform, as the docs 
// say that uniforms can be optimized out if they don't contribute to 
// out results. 
GLint num_active_uniforms = 0; 
glGetProgramiv(active_program, GL_ACTIVE_UNIFORMS, &num_active_uniforms); 
if (0 == num_active_uniforms) { 
    printf("There are 0 uniforms active in program %d.\n", active_program); 
    exit(1); 
} else { 
    printf("There are %d uniform(s) active in program %d.\n", num_active_uniforms, active_program); 
} 
die_on_gl_error("GetProgram (Active Uniforms)"); 

// GL_INVALID_OPERATION is generated if the size of the uniform variable 
// declared in the shader does not match the size indicated by the glUniform 
// command. 

// GL_INVALID_OPERATION is generated if location is an invalid uniform location 
// for the current program object and location is not equal to -1. 

// ... gets some basic information about the active uniforms, of which there 
// should be only one, a FLOAT_MAT4 of size 1. 
const GLchar *uniform_name = "mvMatrix"; 
GLint location = glGetUniformLocation(active_program, uniform_name); 
die_on_gl_error("GetUniformLocation"); 

GLchar *message; 
GLint max_uniform_length; 
glGetProgramiv(active_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_length); 
message = new GLchar[max_uniform_length]; 
GLint size; 
GLenum type; 
glGetActiveUniform(active_program, location, max_uniform_length, NULL, &size, &type, message); 
printf("Uniform %s:\tType:%x\tSize:%d\n", message, type, size); 
if (GL_FLOAT_MAT4 != type) { 
    printf("Active uniform at location is not a 4x4 float matrix.\n"); 
} 
die_on_gl_error("GetActiveUniform"); 

// GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated 
// uniform variable is not an array variable. 

// GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than 
// glUniform1i and glUniform1iv. 

// GL_INVALID_OPERATION is generated if glUniform is executed between the execution 
// of glBegin and the corresponding execution of glEnd. 

// None of the above are true, and yet the following dies with GL_INVALID_OPERATION? 
glUniformMatrix4fv(location, 1, false, identity_matrix); 
die_on_gl_error("UniformMatrix4f"); 
} 

सब उसके बाद, यहां उत्पादन है:

There are 1 uniform(s) active in program 3. 
Uniform mvMatrix: Type:8b5c Size:1 
GL Error 502 encountered in UniformMatrix4f. 

टाइप 8b5c निश्चित रूप से GL_FLOAT_MAT4 है, और आकार 1 है, इसलिए मैं नहीं देख सकता कि अमान्य ऑपरेशन स्थितियों में से कौन सा मुझे काट रहा है!

संपादित करें:

while (wm->update()) { 
     wm->poll_input(); 
     handle_input(viewingmatrix); 
     if (!gl->use_program(program)) 
      exit(-1); 
     gl->load_identity_matrix(); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glDrawArrays(GL_TRIANGLES, 0, bananaNumVerts); 
     glFlush(); 
     usleep(16667); 
    } 

gl->use_program(program) सिर्फ एक आवरण है कि में और अद्यतन पारित कर दिया पूर्णांक की वैधता की जाँच करता है है:

यहां मुख्य में पाश जहां UseProgram और इस समारोह कहा जाता है है ऑब्जेक्ट का सक्रिय_प्रोग्राम पैरामीटर।

संपादित करें 2: मेरे gDEBugger, जो जीएल त्रुटि के रूप में अच्छी तरह से पता चला मुझे इशारा कर के लिए luke के लिए धन्यवाद। जीडीईबगर में कॉल जानकारी में, मैंने नोट किया कि केवल तीन तर्क सूचीबद्ध थे। जबकि मुझे लगता है कि यह हो सकता है क्योंकि चौथाई एक सरणी के लिए एक सूचक था (क्या वह क्लाइंट पक्ष पर रहता है, या क्या यह हर बार ग्लूनिफॉर्म कहलाता है सर्वर सर्वर के पास जाता है?), यह मुझे सोच रहा है कि और क्या हो सकता है कारण।

मामले में यह प्रमाण है, glUniformMatrix4fv जाहिर है, है, वास्तव में एक समारोह सूचक कि इतने की तरह इसका पता प्राप्त करता है:

घोषणा:

PFNGLUNIFORMMATRIX4FV glUniformMatrix4fv; 

असाइनमेंट:

glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte*)"glUniform4fv"); 

यह वह जगह है मैं अकादमिक कारणों से GLEW से परहेज करता हूं। हालांकि, जब मैं glext.h देख रहा था, मैंने देखा कि भी एक PFNGLUNIFORMMATRIX4FVARBPROC है, जो मुझे लगता है कि इस फ़ंक्शन को कोर में अपनाया जाने से पहले लिखा गया कोडबेस के लिए बस वहां है। यदि ऐसा नहीं है, तो कृपया मुझे बताएं।

+0

मुझे लगता है कि यह प्रश्न 4000+ समीक्षाओं के साथ इतना स्थानीय नहीं है। –

उत्तर

8

अपने glXGetProcAddress कॉल पर एक नज़र डालें:

glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glXGetProcAddress((const GLubyte*)"glUniform4fv"); 

आप glUniform4fv बजाय glUniformMatrix4fv अनुरोध कर रहे हैं!

मुझे पता है कि आपने कहा है कि आप अकादमिक कारणों से विस्तार रैपर पुस्तकालयों का उपयोग नहीं कर रहे हैं, लेकिन मैं अभी भी अत्यधिक अनुशंसा करता हूं।

+1

आपकी मदद के लिए बहुत बहुत धन्यवाद। यहां तक ​​कि यदि समस्या एक टाइपो (अहम) होने के समाप्त हो गई है, तो भी मैं gDEbugger और glsldevil के बारे में जानने की सराहना करता हूं! मैं चीजों को कठिन तरीके से करना चाहता था, और अब मैं देखता हूं कि क्यों हर पुस्तक, ब्लॉग पोस्ट, ट्यूटोरियल इत्यादि। –

+1

मेरी खुशी। मैंने इस सामान के साथ अनगिनत बार संघर्ष किया है, और मुझे पता है कि आंखों की एक अतिरिक्त जोड़ी कितनी उपयोगी है। – luke

+0

बस एक त्वरित अपडेट: एक नया टूल रेंडरडोक है, https://github.com/baldurk/renderdoc जो एक बेहद उपयोगी ग्राफिक्स डीबगर है। – luke

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