2014-01-14 4 views
2

Я использую OpenGL с LWJGL и свою собственную небольшую структуру для тривиальных задач. Я следую книге OpenGL SuperBible: всеобъемлющий учебник и справочник (6-е издание).GL_INVALID_OPERATION на Tesselation Shader

Я перечислю наиболее важные части моей программы:

public class GameController extends Controller { 
    private Program test1Program; 
    private int vaoId; 

    @Override 
    protected void init() { 
     glViewport(0, 0, 800, 600); 
     test1Program = new Program(
       new VertexShader("src/shaders/test.vert.glsl").create(), 
       new ControlShader("src/shaders/test.cont.glsl").create(), 
       new EvaluationShader("src/shaders/test.eval.glsl").create(), 
       new FragmentShader("src/shaders/test.frag.glsl").create() 
       ).create(); 
     vaoId = glGenVertexArrays(); 
     glBindVertexArray(vaoId); 
    } 

    @Override 
    protected void draw(double msDelta) { 
     glClearColor((float)Math.sin(currentTime/1000f) * 0.5f + 0.5f, (float)Math.cos(currentTime/1000f) * 0.5f + 0.5f, 0.0f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT);   
     test1Program.use(); 
     glVertexAttrib4f(0, (float)Math.sin(currentTime/1000f) * 0.5f, (float)Math.cos(currentTime/1000f) * 0.5f, 0.0f, 0.0f); 
     glVertexAttrib4f(1, (float)Math.sin(currentTime/1000f * 2f) * 0.5f + 0.5f, (float)Math.cos(currentTime/1000f * 2f) * 0.5f + 0.5f, 0.0f, 1.0f); 
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
    } 

    @Override 
    protected void shutdown() { 
     test1Program.delete(); 
     glDeleteVertexArrays(vaoId); 
    } 

    public static void main(String[] args) { 
     Controller controller = new GameController(); 
     controller.start(); 
    } 
} 

Мой пользовательский VertexShader, ControlShader, EvaluationShader и FragmentShader работают, и если шейдер не компилируется правильно или не получить связаны правильно, тогда исключение будет выброшено, и я заметил бы это. Поэтому я подтвердил, что те и Program работают правильно.

Ошибка (Exception in thread "main" org.lwjgl.opengl.OpenGLException: Invalid operation (1282)) получает бросок по вызову glDrawArrays.

test.vert.glsl:

#version 440 core 

layout(location = 0) in vec4 offset; 
layout(location = 1) in vec4 color; 

out VS_OUT { 
    vec4 color; 
} vs_out; 

void main() { 
    const vec4 vertices[3] = vec4[3](
     vec4(0.25, -0.25, 0.5, 1.0), 
     vec4(-0.25, -0.25, 0.5, 1.0), 
     vec4(0.25, 0.25, 0.5, 1.0) 
    ); 
    gl_Position = vertices[gl_VertexID] + offset; 
    vs_out.color = color; 
} 

test.cont.glsl:

#version 440 core 

layout(vertices = 3) out; 

void main() { 
    if (gl_InvocationID == 0) { 
     gl_TessLevelInner[0] = 5.0; 
     gl_TessLevelOuter[0] = 5.0; 
     gl_TessLevelOuter[1] = 5.0; 
     gl_TessLevelOuter[2] = 5.0; 
    } 
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 
} 

test.eval.glsl:

#version 440 core 

layout(triangles, equal_spacing, cw) in; 

void main() { 
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position); 
} 

#version 440 core 

in VS_OUT { 
    vec4 color; 
} fs_in; 

out vec4 color; 

void main() { 
    color = fs_in.color; 
} 

У меня есть тройной проверил весь мой код и перекрестился с книгой, но понятия не имею, почему он не работает. Я был бы признателен за любую помощь, и я собираюсь предоставить дополнительную информацию, если это необходимо.

+0

To the downvoter: Дайте ** причину ** для downvote.К какой части стандартов проводки я не придерживаюсь? – skiwi

+0

Работает ли код с конвейером по умолчанию (т. Е. Без test1Program)? Также просто для того, чтобы быть в безопасности, свяжите VAO еще раз перед его рендерингом. – Njol

+0

@Njol Код работал только с «VertexShader» и «FragmentShader». Просто убедитесь, что он работает с конвейером по умолчанию. – skiwi

ответ

5

Я нашел ответ только сейчас:

glDrawArrays(GL_TRIANGLES, 0, 3); 

должно быть:

glDrawArrays(GL_PATCHES, 0, 3); 

Некоторые больше усилий с OpenGL, чтобы показать, что было неправильным было бы оценено.

Также нигде в книге не упоминалось, что мне нужно использовать GL_PATCHES, я просто вычислил его, посмотрев исходный код компилируемых примеров из книги.

+0

Иди в ту же проблему. Спасибо, что поделился. У меня были другие проблемы. Мне пришлось игнорировать интерфейсный блок, в котором хранятся данные о цвете, и жестко закодировать значение в шейдере фрагмента, чтобы он вообще отображал что-либо. Надеюсь, я пойму, почему дальше. – broncoAbierto

0

После более тщательного изучения ваших шейдеров, я подозреваю, что часть проблемы состоит в том, что в вашей программе нет атрибута вершины 1 (layout(location = 1) in vec4 color) после того, как все этапы связаны. Вероятно, это не ваша проблема, но поскольку она стоит прямо сейчас, ваша программа GLSL не будет вести себя так, как вы хотите.

Вы должны передать данные, переданные в шейдерный шейдер, через стадии шейдера тесселяции, чтобы получить его в этап шейдера фрагмента - если вы этого не сделаете, то компилятор/компоновщик GLSL определяет, что этот атрибут вершины не используется когда программа выполняет и не назначает ей местоположение. Это относится и к униформам.

Посмотрите на другой ответ, который я написал на SO для explanation on how to do this.

Смежные вопросы