当我使用RTT时,非常小的颗粒是否可能消失?

时间:2014-09-05 01:13:26

标签: macos opengl render-to-texture

我使用OpenGL ES 2.0开发了20多个移动应用程序。但是,我试图让渲染器在OSX中使用我的应用程序,所以现在我使用OpenGL v3.3与GLSL v130。昨天,我遇到了一个问题,我无法使用纹理(RTT),我在屏外FBO上绘制了GL_LINES 1.0大小的粒子(它是OpenGL 3.3中的最大值为什么?)

当我在Off Screen FBO上绘制几何体并将其用作屏幕上的纹理时,我能够看到 如果我在屏幕上绘制小颗粒,我可以清楚地看到那些,但如果我尝试绘制粒子线并尝试在主屏幕上使用它作为纹理,我只能看到黑色纹理。

我已经检查过GL ERROR并支持FBO'状态和GL混合选项,但我仍在努力解决它。

任何人都有想法解决它?

即使我认为我的代码没问题,我还附上了一些代码

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

这是在BACK 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);

2 个答案:

答案 0 :(得分:2)

如果渲染图像的分辨率远大于大小(以像素为单位),最终会被渲染,那么小特征肯定可能完全消失。

想象一下极端情况。假设您将一些细线渲染为1000x1000纹理,从而照亮了总1,000,000像素中的一小部分。现在,您将此纹理映射到显示时大小为10x10像素的四边形。片段着色器为每个像素调用一次(假设没有MSAA),这使得100个着色器调用。这100次调用中的每一次都对纹理进行采样。使用线性采样而不进行mipmapping,每次采样操作将读取4个纹素。在渲染多边形时,总共读取100 * 4 = 400个纹素。从总1,000,000中读取这400个纹素很可能会完全错过你在纹理中渲染的所有线条。

减少此问题的一种方法是使用mipmapping。这通常会阻止功能完全消失。但是小的功能仍然会消失,因为越来越多的纹素在较高的mipmap级别中被平均,其中大多数纹素都是黑色的。

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

仅仅注意你没有使纹理太大也可能是足够好的。或者通过将它们绘制为多边形而不是使用线基元来创建自己的宽线。

答案 1 :(得分:0)

     Student.findOne({
    "phone._id": mongoose.Types.ObjectId('587e6409e06170ba1708dc21')
},
{
    _id: 0,
    phone: 1
},
function(err,
phone){
    if(err){
        console.log(err)
    }if(phone.Home==phone.Cell||phone.secondary===undefined){
        Student.update({
            'Student._id': mongoose.Types.ObjectId('587e6409e06170ba1708dc22'),
            'phone._id': mongoose.Types.ObjectId('587e6409e06170ba1708dc21')
        },
        {
            "$set": {
                'phone.$.number': 453454554
            }
        }
    })
});

GL_UNSIGNED_INT不能用于OpenGL ES与OpenGL。奇怪的是,它适用于IOS,但不适用于Android。

参数在OpenGL ES中必须为 GL_UNSIGNED_BYTE GL_UNSIGNED_SHORT