Использую C# и Tao.Framework. Проблема в том, что не сохраняются данные в varying переменных. Пытаюсь записать в данные в вершинном шейдере, а считать в пиксельном - не работает. Вгоняю тотже код в RenderMonkey - всё заводится без проблем.
altk
> Использую C# и Tao.Framework. Проблема в том, что не сохраняются данные в
> varying переменных. Пытаюсь записать в данные в вершинном шейдере, а считать в
> пиксельном - не работает. Вгоняю тотже код в RenderMonkey - всё заводится без
> проблем.
Шейдер и код загрузки в студию.
private string[] vertex_shader = {/* "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main()", "{", "normal=normalize(gl_NormalMatrix*gl_Normal);", "lightDir=normalize(vec3(gl_LightSource[0].position));", "halfVector=normalize(gl_LightSource[0].halfVector.xyz);", "diffuse=gl_FrontMaterial.diffuse*gl_LightSource[0].diffuse;", "ambient=gl_FrontMaterial.ambient*gl_LightSource[0].ambient+gl_LightModel.ambient*gl_FrontMaterial.ambient;", "gl_Position=ftransform();", "}"*/ "varying vec4 color2=vec4(1.0,0.0,0.0,1.0);", "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main() {", "vec3 normal, lightDir;", "vec4 diffuse;", "float NdotL;", "normal = normalize(gl_NormalMatrix * gl_Normal);", "lightDir = normalize(vec3(gl_LightSource[0].position));", "NdotL = max(dot(normal, lightDir), 0.0);", "diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;", "gl_FrontColor = NdotL * diffuse;", "gl_Position = ftransform();", "}" }; private string[] fragment_shader = { /*"varying vec4 color2=vec4(1.0,0.0,0.0,1.0);", "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main()", "{", "vec3 n,halfV;", "float NdotL,NdotHV;", "vec4 color=vec4(0.0,0.0,0.0,1.0);", "n=normalize(normal);", "NdotL=max(dot(n,lightDir),0.0);", "if(NdotL>0.0){", "color+=diffuse*NdotL;", "halfV=normalize(halfVector);", "NdotHV=max(dot(n,halfV),0.0);", "color+=gl_FrontMaterial.specular*gl_LightSource[0].specular*pow(NdotHV,gl_FrontMaterial.shininess);", "}", "gl_FragColor=color2;", "}"*/ "varying vec4 color2; void main(){gl_FragColor=color2;}" }; private void InitShaders() { fs_object = Gl.glCreateShader( Gl.GL_FRAGMENT_SHADER); vs_object = Gl.glCreateShader( Gl.GL_VERTEX_SHADER); int[] status = new int[1]; Gl.glShaderSource( vs_object, vertex_shader.Length, vertex_shader, null); Gl.glCompileShader( vs_object); Gl.glGetShaderiv( vs_object, Gl.GL_COMPILE_STATUS, status); if ( status[0] != Gl.GL_TRUE) throw new Exception( "Could not compile fragment shader"); Gl.glShaderSource( fs_object, fragment_shader.Length, fragment_shader, null); Gl.glCompileShader( fs_object); Gl.glGetShaderiv( fs_object, Gl.GL_COMPILE_STATUS, status); if ( status[0] != Gl.GL_TRUE) throw new Exception( "Could not compile fragment shader"); vs_program = Gl.glCreateProgram( ); Gl.glAttachShader( vs_program, vs_object); //Gl.glAttachShader(vs_program, fs_object); fs_program = Gl.glCreateProgram( ); Gl.glAttachShader( fs_program, fs_object); Gl.glLinkProgram( vs_program); Gl.glLinkProgram( fs_program); //System.Diagnostics.Debug.WriteLine(string.Format("program={0}", fs_program)); }
Результат - рисуется черный объект(то есть все объекты на сцене черного цвета).
У varying-переменных нельзя указывать значение в инициализации, насколько я знаю. Убери "=vec4(1.0,0.0,0.0,1.0)" из инициализации и присвой значение переменной color2 внутри вершинного шейдера. Проверил в RenderMonkey - работает. А если сделать как у тебя - чёрный объект. :)
Просьба обратить внимание на то, что закомментировано. Это основный шейдеры. То что я сейчас оставил - это просто тест.
То есть косяк в том, что закомментировано? :)
Ну а тут у тебя уже две ошибки. Во-первых, не объявлена переменная color2 в вершинном шейдере, а во-вторых, во фрагментном шейдере она же инициализирована прям в объявлении, надо бы перенести инициализацию в функцию main, причём вершинного шейдера, так как фрагментный шейдер только принимает её значение, а не устанавливает. Исправляй и пробуй запустить. :)
Сделал всё, как посоветовали:
private string[] vertex_shader = { "varying vec4 color2;", "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main() {", "vec3 normal, lightDir;", "vec4 diffuse;", "float NdotL;", "color2=(1.0,0.0,0.0,1.0);", "normal = normalize(gl_NormalMatrix * gl_Normal);", "lightDir = normalize(vec3(gl_LightSource[0].position));", "NdotL = max(dot(normal, lightDir), 0.0);", "diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;", "gl_FrontColor = NdotL * diffuse;", "gl_Position = ftransform();", "}" }; private string[] fragment_shader = { "varying vec4 color2; void main(){gl_FragColor=color2;}" };
Реузльтат не изменился. Пока для выявления ошибки убрал комментарии.
altk
> Проблема в том, что не сохраняются данные в varying переменных.
Как ты это определил?
"varying vec4 color2;", "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main() {", "vec3 normal, lightDir;", "vec4 diffuse;", "float NdotL;", "color2=(1.0,0.0,0.0,1.0);",
Ерунда какаято... Сделай так:
"varying vec4 color2;", "varying vec4 diffuse,ambient;", "varying vec3 normal,lightDir,halfVector;", "void main() {", "color2=vec4(1.0,0.0,0.0,1.0);",
Точно! :) Куда конструктор-то девал? vec4. Executor оказался повнимательнее нас. :))
Вот совсем короткий вариант:
private string[] vertex_shader = { "varying vec4 color2;", "void main() {", "color2.r=1.0;", "gl_Position = ftransform();", "}" }; private string[] fragment_shader = { "varying vec4 color2; void main(){gl_FragColor=color2;}" };
Результат аналогичный. Может быть кто-нибудь приведет пример своих шейдеров(но только для Tao.Framework).
Пробовал и с конструктором, тоже не получается.
А что получается? У меня красный объект. :) меняешь компоненты color2, цвет меняется.
Слушай, а зачем тебе C# для графики? Это же вроде бы интерпретируемый язык. Или я не прав? :)
K.V.
> Или я не прав? :)
Не совсем.
Тема в архиве.
Тема закрыта.