Introducción a Opengles GL_OVR_multiview2

Recientemente, el proyecto necesita estudiar GL_OVR_multiview. El
requisito es hacer una representación secundaria de GL_TEXTURE_2D_ARRAY completada por la unidad, y dibujar diferentes texturas para diferentes capas de GL_TEXTURE_2D_ARRAY a través de una llamada de dibujo.

Primero, presente GL_OVR_multiview y brinde una introducción más detallada a GL_OVR_multiview en OpenGL ES SDK para Android .
Se puede entender que GL_OVR_multiview es una tecnología que convierte un objeto framebuffer (framebuffer Object) en una matriz de textura 2D (GL_TEXTURE_2D_ARRAY) a través de una llamada de dibujo

Primero inicialice el entorno de renderizado

bool setupFBO(int width, int height)
{
    
    
	// Create array texture
	GL_CHECK(glGenTextures(1, &frameBufferTextureId));
	GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, frameBufferTextureId));
	GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
	GL_CHECK(glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
	GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, 2));
	/* Initialize FBO. */
	GL_CHECK(glGenFramebuffers(1, &frameBufferObjectId));
	/* Bind our framebuffer for rendering. */
	GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferObjectId));
	/* Attach texture to the framebuffer. */
	GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
	                              frameBufferTextureId, 0, 0, 2));
	/* Create array depth texture */
	GL_CHECK(glGenTextures(1, &frameBufferDepthTextureId));
	GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, frameBufferDepthTextureId));
	GL_CHECK(glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT24, width, height, 2));
	/* Attach depth texture to the framebuffer. */
	GL_CHECK(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
	                              frameBufferDepthTextureId, 0, 0, 2));
	/* Check FBO is OK. */
	GLenum result = GL_CHECK(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
	if (result != GL_FRAMEBUFFER_COMPLETE)
	{
    
    
	LOGE("Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__);
	/* Unbind framebuffer. */
	GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
	return false;
	}
	return true;
}

El método anterior se utiliza en el hilo de renderizado de unidad, la unidad renderizará frameBufferObjectId en la matriz de textura 2D frameBufferTextureId.
Una vez que unity termine de renderizarse, pasará la matriz de textura 2D frameBufferTextureId al SDK, y el SDK hará la renderización secundaria.
Primero, el SDK debe verificar si la textura enlazada actualmente es renderTexture2DArrayId, de lo contrario, es necesario volver a enlazar renderTexture2DArrayId y configurar el
código GL_OVR_multiview de la siguiente manera:

GLint defaultActiveTextureArray = 0;
GL(glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &defaultActiveTextureArray));

GLint renderTexture2DArrayId = frameBufferTextureId;
glBindTexture(GL_TEXTURE_2D_ARRAY, renderTexture2DArrayId);
//相当于glFramebufferTexture2D
glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,renderTexture2DArrayId, 0, 0, 2);

GLint defaultFbId;
GL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbId));
//postprocess renderTexture2DArrayId only by on draw call
postprocess(renderTexture2DArrayId);
glBindTexture(GL_TEXTURE_2D_ARRAY, defaultActiveTextureArray);

La función GL_OVR_multiview debe estar activada en el sombreador (debido a la matriz de textura 2D dibujada, si diferentes capas no solo tienen diferente gl_Position, sino también diferentes texturas y coordenadas de textura, se requiere la función GL_OVR_multiview2). El
sombreador de punto fijo es el siguiente

+char multiviewVs[] =
+    "#version 300 es\n"
+    "#extension GL_OVR_multiview2 : require\n"
+    "layout(num_views = 2) in;\n"
+    "in  vec2 position[2];\n"
+    "in  vec2 texcoord[2];\n"
+    "out vec3 vTexcoord0;\n"
+    "uniform mat4 mvpMatrix[2];\n"
+    "void main()\n"
+    "{\n"
+    "    vec2 vposition = position[gl_ViewID_OVR];\n"
+    "    vec2 vtexcoord = texcoord[gl_ViewID_OVR];\n"
+    "    mat4 currentmvp= mvpMatrix[gl_ViewID_OVR];\n"
+    "    gl_Position    = currentmvp*vec4(vposition .x, vposition y, 0.0, 1.0);\n"
+    "    vTexcoord0     = vec3(vtexcoord .x,vtexcoord .y,gl_ViewID_OVR);\n"
+    "}\n";

El código de sombreado de fragmentos es el siguiente

+char multiviewFs[] =
+    "#version 300 es\n"
+    "in vec3 vTexcoord0;\n"
+    "uniform sampler2DArray srcTex;\n"
+    "//uniform sampler2D srcTex;\n"
+    "out  vec4 outColor;\n"
+    "void main()\n"
+    "{\n"
+    "    outColor = texture(srcTex, vTexcoord0);\n"
+    "}\n";

El efecto final es que la textura renderTexture2DArrayId se procesa dos veces y el contenido de sampler2DArray se dibuja en renderTexture2DArrayId. El efecto es el siguiente
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/u010116586/article/details/103148752
Recomendado
Clasificación