Macos 当我使用RTT时,很小的粒子会消失吗?

Macos 当我使用RTT时,很小的粒子会消失吗?,macos,opengl,render-to-texture,Macos,Opengl,Render To Texture,我已经使用OpenGL ES 2.0开发了20多个移动应用程序。不过,我正在尝试制作一个渲染器,以便在OSX中使用我的应用程序,所以现在我使用的是带有GLSL v130的OpenGL v3.3。昨天,我遇到了一个问题,我不能使用一个纹理(RTT),我在屏幕外的FBO上绘制了大小为GL_LINES 1.0的粒子(这是OpenGL 3.3中的最大值,为什么??) 当我在非屏幕FBO上绘制几何体并将其用作屏幕上的纹理时,我能够看到这一点 而且,如果我在屏幕上画小粒子,我可以清楚地看到它们,但如果我尝试

我已经使用OpenGL ES 2.0开发了20多个移动应用程序。不过,我正在尝试制作一个渲染器,以便在OSX中使用我的应用程序,所以现在我使用的是带有GLSL v130的OpenGL v3.3。昨天,我遇到了一个问题,我不能使用一个纹理(RTT),我在屏幕外的FBO上绘制了大小为GL_LINES 1.0的粒子(这是OpenGL 3.3中的最大值,为什么??)

当我在非屏幕FBO上绘制几何体并将其用作屏幕上的纹理时,我能够看到这一点 而且,如果我在屏幕上画小粒子,我可以清楚地看到它们,但如果我尝试画粒子线,并尝试将其用作主屏幕上的纹理,我只能看到黑色纹理

我已经检查了总账错误并返回FBO的状态和总账混合选项,但我仍在努力解决它

有人有办法解决这个问题吗

尽管我认为我的代码还可以,我还是在下面附加了一个小代码

// AFTER generate and bind FBO, generate RTT 
StarTexture fboTex;
fboTex.texture_width = texture_width;
fboTex.texture_height = texture_height;
glGenTextures(1, &fboTex.texture_id);
glBindTexture(GL_TEXTURE_2D,fboTex.texture_id);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex.texture_id, 0);
这是在后面的FBO上绘制粒子

glUniformMatrix4fv( h_Uniforms[UNIFORMS_PROJECTION], 1, GL_FALSE, g_proxtrans.s);
glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_PARTICLE]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3)*ParticleNumTotal*2, &p_particle_lc_xy[0]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION], 3, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION]);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_COLOR]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_COLOR], 4, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_COLOR]);

glLineWidth(Thickness); // 1.0 because it is maxium

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_OFF1]);
glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0); // 200 lines
当我在主屏幕上画的时候

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear( GL_COLOR_BUFFER_BIT);

starfbo->bindingVAO1();

glViewport(0, 0, ogl_Width, ogl_Height);
glUseProgram(h_Shader_Program[Shader_Program_FINAL]);

glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_TEXCOORD2]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_UV2], 2, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_UV2]);

glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_SQCOORD2]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION3], 2, GL_FLOAT, 0, 0,0 );
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION3]);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_ON]);
glDrawElements(GL_TRIANGLES,sizeof(squareIndices)/sizeof(squareIndices[0]), GL_UNSIGNED_INT ,(void*)0);

  glUniformMatrix4fv( h_Uniforms[UNIFORMS_PROJECTION], 1, GL_FALSE, g_proxtrans.s);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_PARTICLE]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3)*ParticleNumTotal*2, &p_particle_lc_xy[0]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION], 3, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION]);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_COLOR]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_COLOR], 4, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_COLOR]);

glLineWidth(Thickness);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_OFF1]);
glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0);

如果渲染图像的分辨率远大于其最终渲染的大小(以像素为单位),则小特征很可能完全消失

想象一个极端的例子。假设您将几条细线渲染成1000x1000纹理,照亮了1000000像素总数的一小部分。现在,您可以将此纹理映射到显示时大小为10x10像素的四边形上。片段着色器对每个像素调用一次(假设没有MSAA),这将导致100次着色器调用。这100次调用中的每一次都会对纹理进行采样。在线性采样和无mipmapping的情况下,它将为每个采样操作读取4个texel。渲染多边形时,总共读取100*4=400 texel。读取1000000个纹理中的这400个纹理很可能会完全丢失渲染到纹理中的所有线条

减少此问题的一种方法是使用mipmapping。这通常可以防止功能完全消失。但小特征仍然会褪色,因为越来越多的纹理在更高的mipmap级别中平均,其中大多数纹理是黑色的

一种更好但稍微复杂的方法是,不使用自动生成的mipmap,而是手动创建mipmap,方法是将相同的内容呈现到每个mipmap级别

这可能足够好,只是要小心不要使纹理太大。或者通过将宽线绘制为多边形而不是使用线基本体来创建自己的宽线

glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0);
GL_UNSIGNED_INT不能在OpenGL ES和OpenGL中使用。奇怪的是,它适用于IOS,但不适用于Android


在OpenGL ES中,参数必须是GL\u UNSIGNED\u BYTEGL\u UNSIGNED\u SHORT

作为一个实验,你可以尝试用黑色以外的东西清除FBO。这将显示纹理是否成功用作渲染目标,以及在第二次渲染过程中从纹理进行采样是否有效。@Reto Koradi如我所述,FBO已成功使用,但粒子消失