Я создал класс, который отображает видеокарты (на Mac) в пользовательский объект framebuffer. В качестве входных данных у меня есть текстура YUV, и я успешно создал фрагментарный шейдер, который принимает в качестве входных 3 текстуры прямоугольника (по одному для Y, U и V), данные для которых загружаются glTexSubImage2D с использованием GL_TEXTURE_RECTANGLE_ARB, GL_LUMINANCE и GL_UNSIGNED_BYTE) , перед рендерингом я устанавливал активные текстуры на три разных единицы текстуры (0, 1 и 2) и связывал текстуру для каждого, и по соображениям производительности я использовал GL_APPLE_client_storage и GL_APPLE_texture_range. Затем я отобразил его с помощью glUseProgram (myProg), glBegin (GL_QUADS) ... glEnd().Рендеринг текстуры прямоугольника с помощью GLSL
Это работало нормально, и я получил ожидаемый результат (помимо мерцающего эффекта, который, как я полагаю, связан с тем, что я использовал два разных контекста GL на двух разных потоках, и я полагаю, они попадают друг в друга путь в какой-то момент [это тема для другого вопроса позже]). Во всяком случае, я решил еще больше улучшить свой код, добавив вершинный шейдер, чтобы я мог пропустить glBegin/glEnd, который я прочитал, устарел и его следует избегать в любом случае.
Так как следующий шаг я создал два буфер объектов, один для вершин и один для координаты текстуры:
const GLsizeiptr posSize = 4 * 4 * sizeof(GLfloat);
const GLfloat posData[] =
{
-1.0f, -1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f
};
const GLsizeiptr texCoordSize = 4 * 2 * sizeof(GLfloat);
const GLfloat texCoordData[] =
{
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
};
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, posSize, posData, GL_STATIC_DRAW);
glGenBuffers(1, &m_texCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, texCoordSize, texCoordData, GL_STATIC_DRAW);
Затем после загрузки шейдеров я стараюсь, чтобы получить расположение атрибутов в вершине shader:
m_attributeTexCoord = glGetAttribLocation(m_shaderProgram, "texCoord");
m_attributePos = glGetAttribLocation(m_shaderProgram, "position");
, который дает мне 0 для texCoord и 1 для позиции, что кажется прекрасным.
После получения атрибутов я также называю
glEnableVertexAttribArray(m_attributePos);
glEnableVertexAttribArray(m_attributeTexCoord);
(я делаю это только один раз, или это должно быть сделано перед каждым glVertexAttribPointer и glDrawArrays? Нужно ли это сделать за единицу текстуры? Или ? в то время как мой шейдер активируется с glProgram Или я могу сделать это где-нибудь)
После этого я изменил код рендеринга, чтобы заменить glBegin/glEnd:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_Y);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_U);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texID_V);
glUseProgram(myShaderProgID);
// new method with shaders and buffers
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(m_attributePos, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glVertexAttribPointer(m_attributeTexCoord, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_QUADS, 0, 4);
glUseProgram(0);
Но, изменив код, я всегда получаю только черный экран. Поэтому я предполагаю, что у меня отсутствуют простые шаги, возможно, некоторые glEnable/glDisable или настройка некоторых вещей правильно, но, как я уже сказал, я новичок в этом, поэтому у меня пока нет идеи. Для справки, вот вершинные шейдеры:
#version 110
attribute vec2 texCoord;
attribute vec4 position;
// the tex coords for the fragment shader
varying vec2 texCoordY;
varying vec2 texCoordUV;
//the shader entry point is the main method
void main()
{
texCoordY = texCoord;
texCoordUV = texCoordY * 0.5; // U and V are only half the size of Y texture
gl_Position = gl_ModelViewProjectionMatrix * position;
}
Я думаю, что я пропускаю что-то очевидное здесь, или просто не имеют достаточно глубокого понимания процессов, происходящих здесь еще. Я также попытался использовать OpenGLShaderBuilder, который помог мне правильно получить исходный код для фрейдирующего шейдера (вот почему я его здесь не публиковал), но с добавлением вершинного шейдера он тоже не дает мне никакого результата (было интересно как он мог знать, как производить вывод, если он вообще не знает атрибутов position/texCoord?)
Для текстурных прямоугольников координаты не должны быть нормализованы, но вы, кажется, проходите в нормализованных координатах. – harold
О, так для texCoordData [] вместо 0.0, 1.0 и т. Д. Я прохожу, например, 1920.0, 1080.0 (т.е. фактический размер видео кадра)? – Bjoern
Черный экран смерти настолько распространен в графике.Я полагаю, вы пытались изменить четкий цвет, чтобы убедиться, что вы на самом деле рисуете что-нибудь? Если вы * *, то это проблема с шейдером, если нет, проблема с массивом вершин. – imallett