Java OpenGL четырехмерный текстурный экран - PullRequest
0 голосов
/ 10 июня 2011

У меня есть приложение Java OpenGL (JOGL), и я пытаюсь создать квадратор с текстурой, который покрывает весь экран.Нарисуйте несколько пикселей в буфере, а затем я хочу прочитать эти пиксели в текстуру и перерисовать их на экране (с применением фрагментного шейдера).Мой код для сопоставления текстуры с окном просмотра:

        gl.glMatrixMode(GL.GL_PROJECTION);                                        
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();                                               
        gl.glOrtho( 0, width, height, 0, -1, 1 );                          
        gl.glMatrixMode(GL.GL_MODELVIEW);                                  
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();
        IntBuffer ib = IntBuffer.allocate(1);
        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glGenTextures(1, ib);
        gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
        //buff contains pixels read from glReadPixels
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);
        gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
        gl.glBegin(GL.GL_QUADS);
        gl.glTexCoord2f(0,1);
        gl.glVertex2f(0,0); 
        gl.glTexCoord2f(0,0);
        gl.glVertex2f(0,height);
        gl.glTexCoord2f(1,0);   
        gl.glVertex2f(width,height);
        gl.glTexCoord2f(1,1);      
        gl.glVertex2f(width,0);
        gl.glEnd();
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        gl.glPopMatrix();
        gl.glPopMatrix();

Конечным результатом является квадратор, который не покрывает весь видовой экран (он частично включен) и не содержит пикселей из буфера.Что я здесь делаю неправильно?

спасибо, Джефф

Ответы [ 3 ]

2 голосов
/ 11 июня 2011

Во-первых, вы должны только создать текстуру в вашем коде инициализации. Вы не должны вызывать glTexImage2D каждый кадр. Вызывайте glTexImage2D только в случае изменения размера текстуры; glTexSubImage2D можно использовать для загрузки данных в текстуру. Думайте о glTexImage2D как о «новом», а о glTexSubImage2D как о копии памяти.

Сделайте это один раз, после инициализации OpenGL.

IntBuffer ib = IntBuffer.allocate(1);  //Store this in your object
gl.glGenTextures(1, ib);
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
//buff contains pixels read from glReadPixels
gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

Затем в каждом кадре сделайте следующее:

gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPushMatrix();                                                 
gl.glLoadIdentity();                                               
gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPushMatrix();                                                 
gl.glLoadIdentity();

gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));  //Retrieved from your object
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);

gl.glBegin(GL.GL_QUADS);
    gl.glTexCoord2f(0,1);
    gl.glVertex2f(-1, -1); 
    gl.glTexCoord2f(0, 0);
    gl.glVertex2f(-1, 1);
    gl.glTexCoord2f(1, 0);   
    gl.glVertex2f(1, 1);
    gl.glTexCoord2f(1, 1);      
    gl.glVertex2f(1, -1);
gl.glEnd();

gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_MODELVIEW);                                  

Используя идентичность для проекции и просмотра модели, мы можем предоставить координаты вершины непосредственно в пространстве клипа. Диапазон [-1, 1] в пространстве клипа отображается на [0, ширина / высота] в пространстве окна. Поэтому нам не нужно знать или заботиться о том, насколько велико окно; до тех пор, пока glViewport был настроен правильно, это должно работать.

1 голос
/ 10 июня 2011

Возможно, это не проблема, но это не поможет: вы нажимаете матрицу вида модели дважды для одного нажатия.Вы вообще не отображаете матрицу проекции.

Я бы порекомендовал установить матрицу проекции один раз при запуске, не нажимая и не нажимая.Вам действительно не нужно нажимать и вставлять матрицу просмотра модели.(Вы также можете выполнить настройку текстуры один раз при запуске.)

0 голосов
/ 10 июня 2011

Я бы начал с проверки glError с кодом, подобным приведенному ниже. Обратите внимание, что я использовал объект GL2, потому что были некоторые проблемы с более старыми версиями JOGL и объектом GL, глупые вещи, такие как GL_QUADS, отсутствовали.

Если у вас включен шейдер с вышеуказанным кодом, вам нужно выполнить текстурирование, читая сэмплер. Если это так, пожалуйста, прикрепите код шейдера, который вы используете с этим кодом рендеринга.

private static void checkForGLErrors(GL2 gl) {
    int errno = gl.glGetError();
    switch (errno) {
        case GL2.GL_INVALID_ENUM:
            System.err.println("OpenGL Error: Invalid ENUM");
            break;
        case GL2.GL_INVALID_VALUE:
            System.err.println("OpenGL Error: Invalid Value");
            break;
        case GL2.GL_INVALID_OPERATION:
            System.err.println("OpenGL Error: Invalid Operation");
            break;
        case GL2.GL_STACK_OVERFLOW:
            System.err.println("OpenGL Error: Stack Overflow");
            break;
        case GL2.GL_STACK_UNDERFLOW:
            System.err.println("OpenGL Error: Stack Underflow");
            break;
        case GL2.GL_OUT_OF_MEMORY:
            System.err.println("OpenGL Error: Out of Memory");
            break;
        default:
            return;
    }
}

Я бы также старался избегать генерации текстуры каждый кадр, если это что-то, что не меняется. Вы можете сохранить textureId и связать его позже.

...