Не удается загрузить шейдер OpenGL - PullRequest
3 голосов
/ 07 января 2012

У меня проблема с кодом загрузки моего шейдера. Странная вещь, которая меня смущает, это то, что она работает, может быть, один раз в 5 раз, но только в некотором роде. Например, он загрузит фрагментный шейдер, но затем текстурирование не будет работать должным образом (вместо этого будет отображаться странное подобие текстуры поверх геометрии). Я думаю, что проблема с загрузкой кода, вот о чем мой вопрос. Кто-нибудь может обнаружить ошибку, которую я не нашел в коде ниже?

char* vs, * fs;

vertexShaderHandle   = glCreateShader(GL_VERTEX_SHADER);
fragmentShaderHandle = glCreateShader(GL_FRAGMENT_SHADER);

long sizeOfVShaderFile = getSizeOfFile(VERTEX_SHADER_FILE_NAME);
long sizeOfFShaderFile = getSizeOfFile(FRAGMENT_SHADER_FILE_NAME);

if(sizeOfVShaderFile == -1)
{
    cerr << VERTEX_SHADER_FILE_NAME<<" is null!  Exiting..." << endl;
    return;
}
if(sizeOfFShaderFile == -1)
{
    cerr << FRAGMENT_SHADER_FILE_NAME<<" is null!  Exiting..." << endl;
    return;
}

vs = readFile(VERTEX_SHADER_FILE_NAME);
fs = readFile(FRAGMENT_SHADER_FILE_NAME);

const char* vv = vs, *ff = fs;

glShaderSource(vertexShaderHandle  , 1, &vv, NULL);

cout << "DEBUGGING SHADERS" << endl;
cout << "VERTEX SHADER:  ";
printShaderInfoLog(vertexShaderHandle);
cout << endl;

glShaderSource(fragmentShaderHandle, 1, &ff, NULL);

cout << "FRAGMENT SHADER:  ";
printShaderInfoLog(fragmentShaderHandle);
cout << endl;


glCompileShader(vertexShaderHandle);

cout << "VERTEX SHADER:  ";
printShaderInfoLog(vertexShaderHandle);
cout << endl;

glCompileShader(fragmentShaderHandle);

cout << "FRAGMENT SHADER:  ";
printShaderInfoLog(fragmentShaderHandle);
cout << endl;


programHandle = glCreateProgram();

cout << "DEBUGGING PROGRAM" << endl;

glAttachShader(programHandle, vertexShaderHandle);

printProgramInfoLog(programHandle);

glAttachShader(programHandle, fragmentShaderHandle);

printProgramInfoLog(programHandle);


glLinkProgram(programHandle);

printProgramInfoLog(programHandle);

glUseProgram(programHandle);

printProgramInfoLog(programHandle);


delete[] vs; delete[] fs;

Вот функция readFile:

char* readFile(const char* path)
{
    unsigned int fileSize = getSizeOfFile(path);

    char* file_data = new char[fileSize];

    ifstream input_stream;

    input_stream.open(path, ios::binary);

    input_stream.read(file_data, fileSize);

    input_stream.close();
    //this is deleted at the end of the shader code
    return file_data;
}

Все приведенные ниже сообщения взяты из одного и того же исполняемого файла (без перестройки).

Вот первое возможное сообщение об ошибке:

BallGLWidget::initializeGL called
DEBUGGING SHADERS
VERTEX SHADER:  
FRAGMENT SHADER:  
VERTEX SHADER:  ERROR: 0:17: '<' : syntax error syntax error


FRAGMENT SHADER:  
DEBUGGING PROGRAM
ERROR: One or more attached shaders not successfully compiled

ERROR: One or more attached shaders not successfully compiled

glGetError enum value:  GL_NO_ERROR

Еще одно возможное сообщение об ошибке:

BallGLWidget::initializeGL called
DEBUGGING SHADERS
VERTEX SHADER:  
FRAGMENT SHADER:  
VERTEX SHADER:  ERROR: 0:17: 'tt' : syntax error syntax error


FRAGMENT SHADER:  ERROR: 0:33: '?' : syntax error syntax error


DEBUGGING PROGRAM
ERROR: One or more attached shaders not successfully compiled

ERROR: One or more attached shaders not successfully compiled

Вот вывод, когда он работает (возможно, 1 из 5 или 6 раз)

BallGLWidget::initializeGL called
DEBUGGING SHADERS
VERTEX SHADER:  
FRAGMENT SHADER:  
VERTEX SHADER:  
FRAGMENT SHADER:  
DEBUGGING PROGRAM
Image format is GL_RGB
Checking textures...
glGetError enum value:  GL_NO_ERROR

Я серьезно сомневаюсь в самих шейдерах, так как они иногда работают ... и сообщения об ошибках являются мусором.

Если будет полезна какая-либо дополнительная информация, я с удовольствием предоставлю ее.

РЕДАКТИРОВАТЬ: Вот шейдеры

Вершинный шейдер:

attribute vec2 a_v_position;
attribute vec2 a_tex_position;

varying   vec2 tex_coord_output;


void main()
{
    tex_coord_output = a_tex_position;

    gl_Position = vec4(a_v_position, 0.0, 1.0);
}

Фрагмент шейдера:

varying vec2 tex_coord_output;

uniform sampler2D ballsampler;


void main()
{
        gl_FragColor = texture2D(ballsampler, tex_coord_output);
}

Ответы [ 2 ]

4 голосов
/ 07 января 2012

Ваш вопрос является дубликатом Получение символов мусора при чтении файлов GLSL , и вот мой ответ на него:


Вы используете C ++, поэтому я предлагаю вам использовать это. Вместо чтения в самостоятельно выделенный массив символов я предлагаю вам прочитать в std :: string:

#include <string>
#include <fstream>

std::string loadFileToString(char const * const fname)
{
    std::ifstream ifile(fname);
    std::string filetext;

    while( ifile.good() ) {
        std::string line;
        std::getline(ifile, line);
        filetext.append(line + "\n");
    }

    return filetext;
}

Это автоматически берет на себя все выделение памяти и правильное разграничение - ключевое слово RAII: распределение ресурсов - инициализация. Позже вы можете загрузить исходный код шейдера, например,

void glcppShaderSource(GLuint shader, std::string const &shader_string)
{
    GLchar const *shader_source = shader_string.c_str();
    GLint const shader_length = shader_string.size();

    glShaderSource(shader, 1, &shader_source, &shader_length);
}

void load_shader(GLuint shaderobject, char * const shadersourcefilename)
{
    glcppShaderSource(shaderobject, loadFileToString(shadersourcefilename));
}
2 голосов
/ 07 января 2012

Вы читаете файлы, но, насколько я вижу, вы не завершаете текст нулямиПопробуйте выделить размер файла + 1 и установить последний символ на ноль.

...