2017-09-20 228 views
-1

我正在寫一個使用wxWidgets庫的openGL程序,我主要工作,但由於錯誤的字符被插入(我認爲),我得到着色器編譯錯誤,只有我找不到在哪裏字符是或導致它們的原因。錯誤是:OpenGL的着色器錯誤

error 0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>" 

我不知道爲什麼,因爲我看不到任何錯誤時,我cout字符串。這裏是正在被送入glshadersource():

#version 430 core 

layout(location =0) in vec3 vpos; 

out vec3 fragmentColor; 
uniform mat4 MVP; 

void main(void) 

{ 
    gl_Position = MVP * vec4(vpos,1); 
}; 

下面是我用的着色器編譯器功能:

void GL_set::compileAndLink() 
{ 

    GLint Result = GL_FALSE; 
    int InfoLogLength = 0; 

    // Create vertex shader, attach source code, compile 
    vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    const GLchar* adapter[1]; 
    adapter[0] = readShaderCode("Vshader.glsl").c_str(); 
    glShaderSource(vertexShader, 1, adapter, NULL); 
    glCompileShader(vertexShader); 

    // Check vertex shader for errors 
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    if (InfoLogLength > 0) 
    { 
     char vertexError[1000]; 
     glGetShaderInfoLog(vertexShader, InfoLogLength, NULL, &vertexError[0]); 
     std::cout << &vertexError[0]; 
    } 

    // Create fragment shader, attach source code, compile 
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    adapter[0] = readShaderCode("Fshader.glsl").c_str(); 
    glShaderSource(fragmentShader, 1, adapter, NULL); 
    glCompileShader(fragmentShader); 

    // Check fragment shader for errors 
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    if (InfoLogLength > 0) 
    { 
     char fragmentError[1000]; 
     glGetShaderInfoLog(fragmentShader, InfoLogLength, NULL, 
     &fragmentError[0]); 
     std::cout << &fragmentError[0]; 
    } 

    // Create program and attach shaders 
    program = glCreateProgram(); 
    glAttachShader(program, vertexShader); 
    glAttachShader(program, fragmentShader); 
    glLinkProgram(program); 

    //check program for errors 
    glGetProgramiv(program, GL_LINK_STATUS, &Result); 
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    if (InfoLogLength > 0) 
    { 
     char programError[1000]; 
     glGetProgramInfoLog(program, InfoLogLength, NULL, &programError[0]); 
     std::cout << &programError[0]; 
    } 

} 



std::string GL_set::readShaderCode(const char* fileName) 
{ 
    printf("passing %s to readShaderCode() \n", fileName); 
    std::ifstream input(fileName); 
    if(!input.good()) 
    { 
     std::cout << "failed to load file " << fileName; 
     exit(1); 
    } 

    std::string code = std::string(
    std::istreambuf_iterator<char>(input), 
    std::istreambuf_iterator<char>() 
    ); 

    // output the code to cout for error checking 
    std::cout << "Read shader input: \n" << code << "\n" << std::endl; 


    return code; 
} 

以下是完整的控制檯輸出:

normal display attribs are supported 
calling gl_init() 
gl_set construtor called 
setting buffers 
passing Vshader.glsl to readShaderCode() 
Read shader input: 
#version 430 core 

layout(location =0) in vec3 vpos; 

out vec3 fragmentColor; 
uniform mat4 MVP; 

void main(void) 
{ 
    //output position of the vertex in clip space MVP*position 
    gl_Position = MVP * vec4(vpos,1); 
}; 



0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>" 
passing Fshader.glsl to readShaderCode() 
Read shader input: 
#version 430 core 

in vec3 fragmentColor; 

out vec3 color; 

void main() 
{ 
    color = fragmentColor; 
}; 



0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>" 
Vertex info 
----------- 
0(1) : error C0000: syntax error, unexpected $undefined at token " 
<undefined>" 
(0) : error C2003: incompatible options for link 

Fragment info 
------------- 
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>" 
(0) : error C2003: incompatible options for link 
Loading OBJ file mod.obj... 

這裏其他同學:

#include "GL_set.h" 

GL_set::GL_set() 
{ 

    std::cout << "gl_set construtor called" << std::endl; 

    GL_set::setBuffers(); 

} 


void GL_set::setBuffers() 
{ 

    std::cout << "setting buffers" << std::endl; 

    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    //create shaders and attach them to the program object 
    GL_set::compileAndLink(); 

    loadOBJ("mod.obj", vdata); // use OBJ loader 

    glGenBuffers(1, &vertexbuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glBufferData(GL_ARRAY_BUFFER, vdata.size()*sizeof(glm::vec3), &vdata[0], GL_STATIC_DRAW); 

    //vertex buffer 
    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glVertexAttribPointer(
     0,   //index 
     3,   //size 
     GL_FLOAT, //type 
     GL_FALSE, //normalized? 
     0,   //stride 
     0   //array buffer offset 
    ); 

} 

void GL_set::draw() 
{ 

    glBindVertexArray(vao); 


    GLuint matrixID = glGetUniformLocation(program, "MVP"); 


    ////////////////////////////matrix operations///////////////////////////////////////// 

    //projection matrix 45 degree FoV, 4:3 ratio, display range 0.1 - 100 
    glm::mat4 projection = glm::perspective(45.0f, 4.0f/3.0f, 0.1f, 100.0f); 

    //camera matrix 
    glm::mat4 view = glm::lookAt(
       glm::vec3(8, 8, 8), //camera posiiton 
       glm::vec3(0, 1, 0), //camera looks at this point 
       glm::vec3(0, 1, 0) //head up position 
       ); 

    //model matrix identity matrix 
    glm::mat4 model = glm::mat4(1.0f); 

    //rotate 
    model = glm::rotate(model, 1.0f, glm::vec3(1,1,1)); 

    //model-view-projection 
    glm::mat4 MVP = projection * view * model; 



    ///////////////////////////////////////////////////////// 

    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]); 


    glDrawArrays(GL_TRIANGLES, 0, vdata.size()*sizeof(glm::vec3)); 


} 

我認爲我的wxWidgets相關代碼沒問題,窗口界面加載了一個空白的白屏,大概是由着色器錯誤引起的。如果需要,我可以發佈更多,謝謝。

+0

期望片段着色器如何獲得'fragmentColor'from?在頂點着色器中取消註釋「輸出」命令,爲其設置一些值並重試。 – Ripi2

回答

3

std::string返回的readShaderCode只在.c_str()呼叫期間有效。之後,允許std::string釋放內存,使您的adapter[0]指向剛被釋放的內存(免費使用)。

您應該將readShaderCode的結果分配給本地std::string變量,以便只在該函數結束時釋放內存。然後,您可以安全地將.c_str()的結果存儲到adapter中,知道內存尚未釋放。

+0

太好了,謝謝。這解決了這個問題。 – fomalhautgt86