2010-04-06 71 views
20

Tôi đang thực hiện phép đúc tia trong trình đổ bóng phân đoạn. Tôi có thể nghĩ ra một vài cách để vẽ một quad toàn màn hình cho mục đích này. Hoặc vẽ một hình vuông trong không gian clip với ma trận chiếu được đặt thành ma trận nhận dạng hoặc sử dụng trình đổ bóng hình học để biến một điểm thành một dải tam giác. Các cựu sử dụng chế độ ngay lập tức, không được chấp nhận trong OpenGL 3.2. Sau này tôi sử dụng ra khỏi tính mới, nhưng nó vẫn sử dụng chế độ ngay lập tức để vẽ một điểm.Cách tốt nhất để vẽ quad toàn màn hình trong OpenGL 3.2 là gì?

+3

Hình học đổ bóng để tạo ra một quad từ một điểm âm thanh như overkill nếu bạn chỉ cần một quad. Chỉ cần vẽ hai hình tam giác hoặc một dải tam giác. Bốn đỉnh đó sẽ không làm bạn tổn thương, ít nhất cũng không khó như một bóng đổ hình học đặc biệt cho một cái gì đó đơn giản. –

Trả lời

16

Bạn có thể gửi hai tam giác tạo tứ giác, với thuộc tính đỉnh của chúng được đặt thành -1/1 tương ứng.

Bạn không cần nhân chúng với bất kỳ ma trận nào trong trình đổ bóng/phân đoạn đỉnh.

Dưới đây là một số mẫu mã, đơn giản vì nó là :)

Vertex Shader:

const vec2 madd=vec2(0.5,0.5); 
attribute vec2 vertexIn; 
varying vec2 textureCoord; 
void main() { 
    textureCoord = vertexIn.xy*madd+madd; // scale vertex attribute to [0-1] range 
    gl_Position = vec4(vertexIn.xy,0.0,1.0); 
} 

Fragment Shader:

varying vec2 textureCoord; 
void main() { 
    vec4 color1 = texture2D(t,textureCoord); 
    gl_FragColor = color1; 
} 
+3

Nhân tiện, điều này theo ý tưởng cũ của bạn, nhưng nó chắc chắn không được chấp nhận trong OpenGL 3.2.Bạn vẫn có thể gửi các thuộc tính đỉnh thông qua một mảng/bộ đệm đỉnh, vv OpenGL vẫn là một API hiển thị chế độ ngay lập tức. – AdilYalcin

2

Sau đây xuất phát từ chức năng vẽ của lớp vẽ các kết cấu fbo đến một quad được căn chỉnh trên màn hình.

Gl.glUseProgram(shad);  

Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo);   
Gl.glEnableVertexAttribArray(0); 
Gl.glEnableVertexAttribArray(1); 
Gl.glVertexAttribPointer(0, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, voff); 
Gl.glVertexAttribPointer(1, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, coff); 

Gl.glActiveTexture(Gl.GL_TEXTURE0); 
Gl.glBindTexture(Gl.GL_TEXTURE_2D, fboc); 
Gl.glUniform1i(tileLoc, 0); 

Gl.glDrawArrays(Gl.GL_QUADS, 0, 4); 

Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); 
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0); 

Gl.glUseProgram(0); 

Các quad thực tế bản thân và coords đang nhận được từ:

private float[] v=new float[]{ -1.0f, -1.0f, 0.0f, 
           1.0f, -1.0f, 0.0f, 
           1.0f, 1.0f, 0.0f, 
           -1.0f, 1.0f, 0.0f, 

           0.0f, 0.0f, 
           1.0f, 0.0f, 
           1.0f, 1.0f, 
           0.0f, 1.0f 
}; 

Các ràng buộc và thiết lập của của VBO tôi để lại cho bạn.

Các vertex:

#version 330 

layout(location = 0) in vec3 pos; 
layout(location = 1) in vec2 coord; 

out vec2 coords; 

void main() { 
    coords=coord.st; 
    gl_Position=vec4(pos, 1.0); 
} 

Bởi vì vị trí là nguyên, có nghĩa là, không phải nhân với bất kỳ ma trận các -1, -1 :: 1, 1 trong những quad phù hợp với khung nhìn. Tìm hướng dẫn của Alfonse liên kết với bất kỳ bài đăng nào của anh ấy trên openGL.org.

+0

ngôn ngữ nào? java? python? –

+2

Ngôn ngữ lập trình D. Xuất sắc! Các con trỏ đúng với cú pháp Java/C# – ste3e

5

Một gợi ý bởi Chistophe Riccio:

Một tam giác lớn là hiệu quả hơn vì lý do tôi đã minh họa trong video:

http://www.youtube.com/watch?v=WFx6StqpRdY

http://www.youtube.com/watch?v=WnUS8kzA3dI&feature=related

+1

Tại sao tốt hơn là vẽ một hình tam giác? Ai đó có thể giải thích bằng những từ đơn giản? Có bất kỳ mẫu mã nguồn nào ở đâu đó không? – fen

+4

Chrostophe sẽ có thể giải thích tốt hơn, nhưng sự hiểu biết của tôi là cạnh chéo trong trường hợp của một quad làm cho thực thi PS không mạch lạc trên nó, mà ít nhất là làm hại hiệu suất một chút. – kvark

+1

Mọi thứ trong các video đó đều không giải thích được gì. – Robinson

11

Để ra một độ toàn màn hình Bạn có thể sử dụng trình tạo hình tứ giác:

#version 330 core 

layout(points) in; 
layout(triangle_strip, max_vertices = 4) out; 

out vec2 texcoord; 

void main() 
{ 
    gl_Position = vec4(1.0, 1.0, 0.5, 1.0); 
    texcoord = vec2(1.0, 1.0); 
    EmitVertex(); 

    gl_Position = vec4(-1.0, 1.0, 0.5, 1.0); 
    texcoord = vec2(0.0, 1.0); 
    EmitVertex(); 

    gl_Position = vec4(1.0,-1.0, 0.5, 1.0); 
    texcoord = vec2(1.0, 0.0); 
    EmitVertex(); 

    gl_Position = vec4(-1.0,-1.0, 0.5, 1.0); 
    texcoord = vec2(0.0, 0.0); 
    EmitVertex(); 

    EndPrimitive(); 
} 

Vertex Shader chỉ là trống rỗng:

#version 330 core 

void main() 
{ 
} 

Để sử dụng shader này bạn có thể sử dụng lệnh rút thăm dummy với trống VBO:

glDrawArrays(GL_POINTS, 0, 1); 
+1

Tại sao không gian clip Z 0.5 thay vì 0.0? Và tại sao bạn sẽ sử dụng điều này khi vẽ một quad thực tế (hoặc như những người khác đã chỉ ra, một hình tam giác lớn) dễ dàng hơn và ít tốn kém hơn? –

+0

Z tọa độ có thể là 0.0, bạn nói đúng. Đối với câu hỏi thứ hai, nó thực sự ít tốn kém cho CPU, và là linh hoạt hơn, như là một trong những có thể thay đổi shader không có chương trình xây dựng lại. –

+0

Ít tốn kém hơn bao nhiêu? Có phải cái gì đó thực sự đáng chú ý và có thể đo lường được không? –

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