2016-09-14 3 views
1

Этот фрагмент шейдер компилируется и работает без проблем:glCompileShader выдаёт ошибку сегментации из, если заявление

#version 330 core 
uniform sampler2D sampler; 
uniform vec3 clr; 
vec2 pos; 
void main(void) { 
    pos.x = gl_FragCoord.x/960.0; 
    pos.y = gl_FragCoord.y/540.0; 
    gl_FragColor = vec4(clr,1) * texture(sampler, pos.st); 
} 

Это бросает ошибку сегментации где-то внутри glCompileShader:

#version 330 core 
uniform sampler2D sampler; 
uniform vec3 clr; 
vec2 pos; 
void main(void) { 
    pos.x = gl_FragCoord.x/960.0; 
    pos.y = gl_FragCoord.y/540.0; 
    if (texture(sampler, pos.st).r > 0.5) { 
     gl_FragColor = vec4(clr, 1) * 0.5; 
    } 
    else { 
     gl_FragColor = vec4(clr, 1); 
    } 
} 

Все остальное идентично. Кто-нибудь знает причину этого?

+0

Да, извините за это. –

+0

glCompileShader не должен segfault из-за неверного кода; Существует либо проблема с вашим драйвером, либо с кодом, который создает и компилирует шейдер. – pleluron

+0

У вас есть контекст opengl, когда вы пытаетесь скомпилировать шейдер? Попробуйте проверить возвращаемое значение glGetString (GL_VERSION), чтобы проверить, есть ли у вас контекст или нет. – Zouch

ответ

0

Код ниже должен работать нормально. Проблема в вашем коде сложна, так как это может быть проблемой во время оптимизации.

Кроме того, разве это не «текстура2D» вместо «текстуры»?

#version 330 core 
uniform sampler2D sampler; 
uniform vec3 clr; 
vec2 pos; 
void main(void) { 
    pos.x = gl_FragCoord.x/960.0; 
    pos.y = gl_FragCoord.y/540.0; 

    float rValue = texture(sampler, pos.st).r; 

    gl_FragColor = vec4(clr, 1.0) * mix(1.0, 0.5, rValue > 0.5); 
} 
+0

Это было всего лишь «текстура» с тех пор, как GLSL-1.20. https://www.opengl.org/sdk/docs/man/html/texture.xhtml – datenwolf

+0

В профиле 'core' это определенно не должно быть' texture2D' (если драйвер разрешает это, он ошибочен). Вы можете использовать старый материал texture2D, если хотите, если вы удалите «core» из директивы shader version ... но зачем вам это нужно? Размеры текстур довольно неважны, когда выясняется, какова цель поиска, и поэтому существуют перегрузки, чтобы позаботиться об этом; единственный раз, когда вы используете иначе названную функцию текстуры в GLSL 1.30+, это когда вы делаете что-то принципиально иное, например, отображение теней, проекция, явный выбор LOD и т. д. –

+0

Хорошо, спасибо за информацию. Я больше из фона GLSL es, поэтому «texture2D» - это то, что мы используем там. – codetiger

1

Это бросает ошибку сегментации где-то внутри glCompileShader

Такие проблемы, как они, как правило, вызваны недоступный доступа к памяти. API из glShaderSource указан (версия 4.5) следующим образом (курсив мной):

команды

void glShaderSource(
    GLuint shader, 
    GLsizei count, 
    const GLchar *const *string, 
    const GLint *length); 

загружает исходный код в объектный шейдер имени шейдера. string - массив с указателями количества до , необязательно с нулевым завершением символ строки, составляющие исходный код. длина аргумент - массив с номером количество символов в каждой строке (длина строки). Если длина элемента отрицательна, его сопровождающая строка равна с нулевой остановкой. Если длина равна NULL, все строки в аргументе строки считаются нулевыми.

Это означает, что если вы не завершите нулевую строку своих шейдерных строк, OpenGL ожидает, что вы передадите ей информацию о длине или наоборот.

Почему это важно для вашего случая? Важным отличием двух источников шейдеров является длина строки источника шейдера. И вполне возможно, что после окончания более короткого источника может появиться пара нулевых байтов¹. И небольшая смена того, что ваша строка источника шейдера будет немного длиннее, может оказать огромное влияние на то, где она закончится в памяти и что произойдет после нее.

Итак, почему ваша строка источника шейдера не может быть завершена с нулевым значением? Например, если вы прочитали его из файла и выделите память как размер файла. В этом случае не будет символа нулевого завершения.

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


1: Может быть, остатки от предыдущего распределения на то же место памяти, или, возможно, исходная строка была достаточно короткой, чтобы оно уместилось в одну страницу и реализацию таНоса решил, что запрос на новую странице будет уместно (и свежие страницы обычно читают ноль, если только явно не запрашивается их инициализация).