在OpenGL ES中绘制一个球体

我想绘制一个球体,我知道如何在OpenGL中使用诸如glBegin()和glEnd()之类的调用。

但ES中没有任何东西。

build议/教程链接?

既然你已经用OpenGL ES 2.0标记了这个标记,让我build议一个创build平滑球体的替代方法,那就是把它们作为光线追踪的冒名顶替者。 与其计算需要复制平滑球体的许多顶点,您可以利用这样一个事实:从任何angular度看,球体看起来都差不多。

要做到这一点,你需要采用如下的过程:

领域冒名顶替的一代

您将四个顶点代表两个三angular形发送给顶点着色器,然后将它们移位以创build一个始终面向用户的正方形。 在这个正方形中,使用片段着色器来对每个像素进行光栅处理,并提供如果通过这个方形窗口查看球体,那么该球体将具有的颜色。

这种方法的优势在于球体与显示器支持的分辨率一样平滑,并且球体很容易从小到大缩放,而不需要重新计算几何体。 它确实将渲染的负担从顶点处理器转移到碎片处理器,但是对于我所使用的OpenGL ES 2.0设备来说,这并不是什么大问题。

我在这个iOS应用程序中使用了这种技术,在这个页面上可以find源代码, 在这里再多谈一下。 我使用的顶点着色器的简化版本如下所示:

attribute vec4 position; attribute vec4 inputImpostorSpaceCoordinate; varying mediump vec2 impostorSpaceCoordinate; varying mediump vec3 normalizedViewCoordinate; uniform mat4 modelViewProjMatrix; uniform mediump mat4 orthographicMatrix; uniform mediump float sphereRadius; void main() { vec4 transformedPosition; transformedPosition = modelViewProjMatrix * position; impostorSpaceCoordinate = inputImpostorSpaceCoordinate.xy; transformedPosition.xy = transformedPosition.xy + inputImpostorSpaceCoordinate.xy * vec2(sphereRadius); transformedPosition = transformedPosition * orthographicMatrix; normalizedViewCoordinate = (transformedPosition.xyz + 1.0) / 2.0; gl_Position = transformedPosition; } 

而简化的片段着色器是这样的:

 precision mediump float; uniform vec3 lightPosition; uniform vec3 sphereColor; uniform mediump float sphereRadius; uniform sampler2D depthTexture; varying mediump vec2 impostorSpaceCoordinate; varying mediump vec3 normalizedViewCoordinate; const mediump vec3 oneVector = vec3(1.0, 1.0, 1.0); void main() { float distanceFromCenter = length(impostorSpaceCoordinate); // Establish the visual bounds of the sphere if (distanceFromCenter > 1.0) { discard; } float normalizedDepth = sqrt(1.0 - distanceFromCenter * distanceFromCenter); // Current depth float depthOfFragment = sphereRadius * 0.5 * normalizedDepth; // float currentDepthValue = normalizedViewCoordinate.z - depthOfFragment - 0.0025; float currentDepthValue = (normalizedViewCoordinate.z - depthOfFragment - 0.0025); // Calculate the lighting normal for the sphere vec3 normal = vec3(impostorSpaceCoordinate, normalizedDepth); vec3 finalSphereColor = sphereColor; // ambient float lightingIntensity = 0.3 + 0.7 * clamp(dot(lightPosition, normal), 0.0, 1.0); finalSphereColor *= lightingIntensity; // Per fragment specular lighting lightingIntensity = clamp(dot(lightPosition, normal), 0.0, 1.0); lightingIntensity = pow(lightingIntensity, 60.0); finalSphereColor += vec3(0.4, 0.4, 0.4) * lightingIntensity; gl_FragColor = vec4(finalSphereColor, 1.0); } 

目前这些着色器的优化版本有点难以遵循,我也使用环境遮挡照明,这是不存在的。 同样未示出的是该球体的纹理,这可以通过适当的映射函数在球体表面坐标和矩形纹理之间进行转换来完成。 这就是我如何为我的球体表面提供预先计算的环境遮挡值。

参观以上线程的人可以看看下面提供的链接,在OpenGLES2.0中创build包括“Sphere”在内的各种形状。

https://github.com/regar007/ShapesInOpenGLES2.0

形状的类实现使得与代码集成非常容易。

实例化对象并使用渲染function绘制对象。

Interesting Posts