2012-05-18 41 views
9

Tôi đã tạo một lớp biểu diễn các hình ảnh video (trên máy Mac) thành đối tượng khung tìm kiếm tùy chỉnh. Khi đầu vào tôi có kết cấu YUV và tôi đã tạo thành công một trình đổ bóng phân đoạn, lấy làm đầu vào 3 kết cấu hình chữ nhật (một cho Y, U và V, mỗi dữ liệu được tải lên bởi glTexSubImage2D bằng GL_TEXTURE_RECTANGLE_ARB, GL_LUMINANCE và GL_UNSIGNED_BYTE) , trước khi kết xuất, tôi thiết lập các kết cấu hoạt động cho ba đơn vị kết cấu khác nhau (0, 1 và 2) và liên kết một kết cấu cho mỗi và vì lý do hiệu suất tôi đã sử dụng GL_APPLE_client_storage và GL_APPLE_texture_range. Sau đó, tôi trả lại nó bằng cách sử dụng glUseProgram (myProg), glBegin (GL_QUADS) ... glEnd().Kết xuất hình chữ nhật dựng hình với GLSL

Điều đó có hiệu quả và tôi đã nhận được kết quả mong đợi (ngoài hiệu ứng nhấp nháy, tôi đoán là tôi đã sử dụng hai ngữ cảnh GL khác nhau trên hai chủ đề khác nhau và tôi cho rằng tại một số điểm [đó là chủ đề cho một câu hỏi khác sau]). Dù sao, tôi quyết định tiếp tục cải thiện mã của tôi bằng cách thêm một bóng đổ đỉnh là tốt, vì vậy mà tôi có thể bỏ qua glBegin/glEnd - mà tôi đọc là lỗi thời và nên tránh anyway.

Vì vậy, như một bước tiếp theo tôi tạo ra hai đối tượng đệm, một cho các đỉnh và một cho các kết cấu phối:

 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); 

Sau đó, sau khi tải shaders tôi cố gắng để lấy lại vị trí của các thuộc tính trong đỉnh shader:

 m_attributeTexCoord = glGetAttribLocation(m_shaderProgram, "texCoord"); 
     m_attributePos = glGetAttribLocation(m_shaderProgram, "position"); 

cung cấp cho tôi 0 cho texCoord và 1 cho vị trí, điều này có vẻ ổn.

Sau khi nhận được các thuộc tính tôi cũng gọi

 glEnableVertexAttribArray(m_attributePos); 
     glEnableVertexAttribArray(m_attributeTexCoord); 

(Tôi đang làm điều đó một lần duy nhất, hoặc dùng nó phải được thực hiện trước mỗi glVertexAttribPointer và glDrawArrays? Liệu nó cần phải được thực hiện trên một đơn vị kết cấu? Hay ? trong khi đổ bóng của tôi được kích hoạt với glProgram Hoặc tôi có thể làm điều đó chỉ bất cứ nơi nào)

Sau đó tôi đã thay đổi mã vẽ để thay thế 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); 

Nhưng kể từ khi thay đổi mã này, tôi luôn luôn chỉ nhận được một màn hình màu đen như là kết quả. Vì vậy, tôi cho rằng tôi đang thiếu một số bước đơn giản, có thể một số glEnable/glDisable hoặc thiết lập một số điều đúng - nhưng nhưng như tôi đã nói tôi mới đến điều này, vì vậy tôi đã không thực sự có một ý tưởng. Để bạn tham khảo, dưới đây là trình đổ bóng đỉnh:

#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; 
} 

Tôi đoán là tôi thiếu điều gì đó rõ ràng ở đây, hoặc chỉ chưa hiểu sâu về các quy trình đang diễn ra tại đây. Tôi đã thử sử dụng OpenGLShaderBuilder, điều này đã giúp tôi lấy mã gốc cho phần đổ bóng đổ vỡ (đây là lý do tại sao tôi chưa đăng nó ở đây), nhưng kể từ khi thêm bóng đổ, nó không cho tôi bất kỳ đầu ra nào (tự hỏi làm thế nào nó có thể biết làm thế nào để sản xuất đầu ra, nếu nó không biết vị trí/texCoord thuộc tính nào?)

+1

Đối với hình chữ nhật kết cấu, tọa độ không được cho là chuẩn hóa, nhưng có vẻ như bạn đang truyền trong tọa độ chuẩn hóa. – harold

+0

Oh vì vậy cho texCoordData [] thay vì 0.0, 1.0 vv tôi vượt qua trong ví dụ 1920.0, 1080.0 (tức là kích thước thực tế của khung hình video)? – Bjoern

+0

Màn hình đen của cái chết rất phổ biến trong đồ họa.Tôi đoán bạn đã thử thay đổi màu sắc rõ ràng chỉ để đảm bảo rằng bạn đang thực sự vẽ bất cứ điều gì? Nếu bạn * là *, thì đó là vấn đề về đổ bóng, nếu không, vấn đề mảng đỉnh. – imallett

Trả lời

2

Tôi chưa nghiên cứu kỹ từng dòng, nhưng tôi nghĩ logic của bạn hầu như là chính xác. Những gì tôi thấy thiếu là glEnableVertexAttribArray. Bạn cần bật cả thuộc tính đỉnh trước cuộc gọi glDrawArrays.

+0

Cảm ơn bạn đã trả lời nhanh và xin lỗi về điều đó, nhưng tôi đã làm điều đó nhưng quên đề cập đến nó trong bài đăng trên (sẽ chỉnh sửa ngay bây giờ) và không, điều đó đã không giúp tôi thực sự – Bjoern

+0

Ok, tôi gọi là glEnableVertexAttribArray ở sai chỗ. Trước khi tôi gọi nó sau khi tôi nhận được các vị trí thuộc tính, vì vậy bây giờ tôi đã thay đổi nó để được gọi trên mọi khung hình, và cuối cùng nó hoạt động. Nhưng tôi không hiểu tại sao tôi cần phải gọi mọi khung hình, tôi nghĩ nó sẽ nhớ nó được kích hoạt? – Bjoern

+0

@Bên cạnh nó nên nhớ nó mà không cần phải được gọi là mỗi khung hình, bạn có thể vô hiệu hóa nó ở đâu đó? – Tim

Các vấn đề liên quan