2010-10-27 36 views
17

Tôi chỉ mới bắt đầu với OpenGL ES 2.0, những gì tôi muốn làm là tạo ra một số đầu ra 2D đơn giản. Với độ phân giải 480x800, tôi có thể vẽ kết cấu nền như thế nào?Làm cách nào để vẽ kết cấu dưới dạng nền 2D trong OpenGL ES 2.0?

[môi trường phát triển của tôi là Java/Android, vì vậy ví dụ liên quan trực tiếp đến đó sẽ là tốt nhất, nhưng các ngôn ngữ khác sẽ là tốt.]

Trả lời

29

Mặc dù bạn đang sử dụng Android, tôi đã tạo ra một ứng dụng mẫu iPhone thực hiện điều này cho các khung hình của video. Bạn có thể tải xuống mã cho mẫu này từ here. Tôi có một bản viết về ứng dụng này, theo dõi đối tượng dựa trên màu sắc bằng cách sử dụng video trực tiếp, mà bạn có thể đọc here.

Trong ứng dụng này, tôi vẽ hai tam giác để tạo ra một hình chữ nhật, sau đó tạo họa tiết cho rằng việc sử dụng các tọa độ sau đây:

static const GLfloat squareVertices[] = { 
     -1.0f, -1.0f, 
     1.0f, -1.0f, 
     -1.0f, 1.0f, 
     1.0f, 1.0f, 
    }; 

    static const GLfloat textureVertices[] = { 
     1.0f, 1.0f, 
     1.0f, 0.0f, 
     0.0f, 1.0f, 
     0.0f, 0.0f, 
    }; 

Để đi qua khung video như là một kết cấu, tôi sử dụng một chương trình đơn giản như sau vertex:

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 

varying vec2 textureCoordinate; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
} 

và shader đoạn sau đây:

varying highp vec2 textureCoordinate; 

uniform sampler2D videoFrame; 

void main() 
{ 
    gl_FragColor = texture2D(videoFrame, textureCoordinate); 
} 

Vẽ là một vấn đề đơn giản của việc sử dụng chương trình ngay:

glUseProgram(directDisplayProgram); 

thiết lập đồng bộ kết cấu:

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, videoFrameTexture); 

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0); 

thiết lập các thuộc tính:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); 
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

và sau đó vẽ hình tam giác:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
+2

Hãy nhớ rằng bạn cần phải thay đổi chỉ mục thuộc tính - điều này được thực hiện trong chương trình mẫu của bạn, nhưng không phải trong bài đăng. '// Chỉ mục thuộc tính. enum { ATTRIB_VERTEX, ATTRIB_COLOR, ATTRIB_TEXTUREPOSITON, NUM_ATTRIBUTES }; ' – appas

+0

Ý anh là gì bởi @dep đó? – kevlar

+0

ứng dụng của bạn cần một số cập nhật. Có một số chức năng không được chấp nhận và nó bị lỗi trên ios 8. Nhưng tôi thích nó :-) – Karsten

13

Bạn không thực sự vẽ một nền, thay vào đó bạn vẽ một hình chữ nhật (hoặc, chính xác hơn: hai hình tam giác tạo thành một hình chữ nhật) và thiết lập một kết cấu cho điều đó. Điều này hoàn toàn khác với việc vẽ bất kỳ đối tượng nào khác trên màn hình.

Có rất nhiều địa điểm cho biết cách thực hiện việc này, có thể thậm chí còn có một dự án ví dụ về Android cho thấy điều này.

Phần khó khăn là hiển thị nội dung nào đó trước hoặc sau nội dung khác. Để làm việc này, bạn cần phải thiết lập bộ đệm độ sâu và cho phép kiểm tra độ sâu (glEnable (GL_DEPTH_TEST)). Và đỉnh của bạn cần phải có một tọa độ Z (và nói với glDrawElements rằng đỉnh của bạn được tạo thành từ ba giá trị, không phải hai giá trị).

Nếu bạn không làm điều đó, các đối tượng sẽ được hiển thị theo thứ tự các hàm glDrawElements() của chúng được gọi (nghĩa là bất cứ điều gì bạn vẽ cuối cùng sẽ bị che khuất phần còn lại).

Lời khuyên của tôi là không có hình nền hoặc làm bất cứ điều gì ưa thích cho đến khi bạn bị treo nó. OpenGL ES 2.0 có một đường cong học tập dốc và hướng dẫn về ES 1.x không thực sự giúp 3D làm việc vì chúng có thể sử dụng các hàm trợ giúp như gluPerspective, mà 2.0 không có. Bắt đầu bằng việc tạo hình tam giác trên nền không có gì. Tiếp theo, biến nó thành hình vuông. Sau đó, nếu bạn muốn đi lạ mắt, thêm một kết cấu. Chơi với các vị trí. Xem điều gì xảy ra khi bạn thay đổi giá trị Z của các đỉnh của bạn. (Gợi ý: Không nhiều, nếu bạn không có kiểm tra độ sâu được kích hoạt.Và thậm chí sau đó, nếu bạn không có phép chiếu phối cảnh, các vật thể sẽ không nhỏ đi xa hơn, vì vậy nó sẽ vẫn có vẻ như không có gì xảy ra)

Sau một vài ngày, nó sẽ không gây phiền toái , và cuối cùng bạn "làm cho nó", chủ yếu.

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