ما هي أفضل طريقة لرسم رباعي الشاشة في OpenGL 3.2؟

StackOverflow https://stackoverflow.com/questions/2588875

  •  24-09-2019
  •  | 
  •  

سؤال

أنا أقوم بعمل راي في تظليل الشظية. أستطيع أن أفكر في طريقين لرسم رباعي الشاشة لهذا الغرض. إما ارسم رباعيًا في مساحة مقطع مع تعيين مصفوفة الإسقاط على مصفوفة الهوية ، أو استخدم تظليل الهندسة لتحويل نقطة إلى شريط مثلث. السابق يستخدم الوضع الفوري ، الذي تم إهماله في OpenGL 3.2. هذا الأخير الذي أستخدمه من الجدة ، لكنه لا يزال يستخدم الوضع الفوري لرسم نقطة.

هل كانت مفيدة؟

المحلول

يمكنك إرسال مثلثتين لإنشاء رباعي ، مع تعيين سمات قمة الرأس إلى -1/1 على التوالي.

لا تحتاج إلى ضربها مع أي مصفوفة في تظليل قمة الرأس/الشظية.

فيما يلي بعض عينات التعليمات البرمجية ، بسيطة كما هي :)

تظليل Vertex:

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

تظليل الشظايا:

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

نصائح أخرى

لإخراج تظليل هندسة رباعي الشاشة يمكن استخدامه:

#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 فارغ فقط:

#version 330 core

void main()
{
}

لاستخدام هذا التظليل ، يمكنك استخدام أمر Draw Draw مع VBO فارغ:

glDrawArrays(GL_POINTS, 0, 1);

تلميح من قبل Chistophe Riccio:

المثلث الكبير أكثر كفاءة لسبب توضح أنني في مقاطع الفيديو:

http://www.youtube.com/watch؟v=wfx6stqprdy

http://www.youtube.com/watch؟v=wnus8kza3di&feature=reled

لا حاجة لاستخدام تظليل الهندسة أو VBO أو أي ذاكرة على الإطلاق.

يمكن أن يولد قمة التظليل الرباعي.

layout(location = 0) out vec2 uv;

void main() 
{
    float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u); 
    float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u); 

    gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f);
    uv = vec2(x, y);
}

ربط VAO فارغ. إرسال استدعاء السحب ل 6 رؤوس.

ما يلي يأتي من وظيفة السحب للفئة التي ترسم قوام FBO إلى شاشة محاذاة رباعية.

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

يتم الحصول على الربع الفعلي نفسه والمنسق من:

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

ملزمة وإعداد VBO's أترك لك.

تظليل الرأس:

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

لأن الموضع الخام ، أي ، لا يتضاعف من قبل أي مصفوفة -1 ، -1 :: 1 ، 1 من رباعية تناسب في منفذ العرض. ابحث عن البرنامج التعليمي لفونس المرتبط بأي من مشاركاته على OpenGl.org.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top