OpenGL数据可视化(6)绘制三维球面

对本系列绘制三维曲面的代码稍作修改,可实现三维球面的绘制,系列代码已开源。

开源链接:opengl_practice (github.com)

从二维平面到三维曲面

 按照下图所示,将二维图片映射到三维球面上。图中数字表示经度和纬度。

 着色器

片段着色器与绘制二维平面时区别不大,重点在于顶点着色器。

给顶点着色器传入两个值,维度和经度,顶点着色器由经纬度计算出纹理坐标和空间坐标。

顶点着色器:

#version 330 core
#define PI 3.1416

layout (location = 0) in vec2 uv;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
vec3 aPos;

void main()
{
	aPos.z = cos(uv.x)*cos(uv.y);
	aPos.x = cos(uv.x)*sin(uv.y);
	aPos.y = sin(uv.x);
	TexCoord = vec2(0.5*uv.y/PI, uv.x/PI + 0.5);
	gl_Position = projection * view * model * vec4(aPos, 1.0f);
}

顶点数组与索引数组

每个顶点只用【维度,经度】两个值表示,启用图元重启,球面由多个三角条带构成。

// 纬度
float du = 1.0f;
int nu = (int)180 / du+1;
for (i = 0; i < nu; i++) {
	u_arr[i] = (i*du - 90)/180.0f*PI;
}

// 经度
float dv = 1.0f;
int nv = (int)360 / dv + 1;
for (j = 0; j < nv; j++) {
	v_arr[j] = j*dv/180.0f*PI;
}

// 二维经纬度数组分别转为一维数组
float* plt_u = calloc1d_float(nv * nu);
float* plt_v = calloc1d_float(nv * nu);
for (j = 0; j < nu; j++) {
	for (i = 0; i < nv; i++) {
		plt_v[j* nv+i] = v_arr[i];
		plt_u[j* nv+i] = u_arr[j];
	}
}

// 构建顶点数组
float* vertices = calloc1d_float(nv*nu*2);
for (i = 0; i < nv * nu; i += 1) {
	vertices[2*i] = plt_u[i];
	vertices[2*i+1] = plt_v[i];
}

// 构建索引数组,启用图元重启
int now_id, indices_n = (nu - 1) * (2* nv +1);
unsigned int* indices = calloc1d_uint(indices_n);
for (j = 0; j < nu - 1; j++) {
	for (i = 0; i < nv; i++) {
		now_id = 2 * (j * nv + i) + j;
		indices[now_id] = j * nv + i;
		indices[now_id + 1] = (j + 1) * nv + i;
		if (i== nv -1)
			indices[now_id + 2] = 0xFFFF;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值