• 理论：球的参数方程 ... 不过我这里是y 与z的参数方程交换了关系式。即y=Rcos(φ)，注意我这里代码没有实现计算法向量数组，如果后期我用到了再加。（个人笔记，不喜勿喷） 效果： ...//H x-z平面圆分成多少...
理论：球的参数方程

https://baike.baidu.com/item/%E7%90%83%E9%9D%A2/5889102?fr=aladdin

不过我这里是y 与z的参数方程交换了关系式。即y=Rcos(φ)，注意我这里代码没有实现计算法向量数组，如果后期我用到了再加。（个人笔记，不喜勿喷）

效果：

画球代码：

int H=40, V=40;//H x-z平面圆分成多少份，V是y轴分成多少份
const float PI = 3.141592653;
float HR =2*PI / H;
float VR = PI / V;

float R = 0.5;   //圆半径
int vSize = (V - 1)*H + 2;    //顶点数量
int indexSize = (2 * (V - 2)*H + 2 * H) * 3;//索引 ，glDrawElements使用

struct VertexM
{
float X;
float Y;
float Z;
};

vector<VertexM> vertexs;//顶点数组
vector<unsigned int> indexs; //索引 ，glDrawElements使用

void drawSphere() {
vertexs.clear();
indexs.clear();

for (size_t i = 0; i <= V; i++)
{
if (i==0)
{
VertexM vertex;
vertex.X = 0;
vertex.Y = R;
vertex.Z = 0;
vertexs.push_back(vertex);
continue;
}
else if (i==V)
{
VertexM vertex;
vertex.X = 0;
vertex.Y = -R;
vertex.Z = 0;
vertexs.push_back(vertex);

for (int t = H-1; t>=0 ; t--)
{
//球次最后各顶点与最后一个顶点的三角形索引
indexs.push_back(vSize - 1);
unsigned int temIndex = ((i - 2) * H + 1 + t);
indexs.push_back(temIndex);

if (t == 0)
{
indexs.push_back(temIndex + H - 1);
}
else
{
indexs.push_back(temIndex - 1);
}

}

continue;
}

float theta = VR*i;
for (size_t j = 0; j < H; j++)
{
float temX, temY, temZ,beta;
beta = HR*j;

temX = R*sin(theta)*sin(beta);
temY = R*cos(theta);
temZ = R*sin(theta)*cos(beta);

VertexM vertex;
vertex.X = temX;
vertex.Y = temY;
vertex.Z = temZ;

vertexs.push_back(vertex);

//index
if (i==1)
{
indexs.push_back(0);
indexs.push_back(j + 1);
if (j==H-1)
{
indexs.push_back(1);
}
else
{
indexs.push_back(j + 2);
}
}
else
{
//三角形1
unsigned int tem1 = H*(i - 2) + 1 + j;
unsigned int tem2 = H*(i - 1) + 1 + j;
unsigned int tem3 = H*(i - 2) + 2 + j;
unsigned int tem4 = H*(i - 2) + 1;

indexs.push_back(tem1);
indexs.push_back(tem2);
if (j == H - 1)
{
indexs.push_back(tem4);
}
else
{
indexs.push_back(tem3);
}
//三角形2
unsigned int tem5 = tem2;
unsigned int tem6 = H*(i - 1) + 2 + j;
unsigned int tem7 = tem3;
unsigned int tem8 = H*(i - 1) + 1;
unsigned int tem9 = H*(i - 2) + 1;

indexs.push_back(tem5);

if (j == H - 1)
{
indexs.push_back(tem8);
indexs.push_back(tem9);
}
else
{
indexs.push_back(tem6);
indexs.push_back(tem7);
}

}

}
}
unsigned int ad1 = vertexs.size();
unsigned int ad2= indexs.size();
}

VA0,VB0,EBO:

unsigned VAO, VBO, EBO;
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,vertexs.size()* sizeof(VertexM),&vertexs[0],GL_STATIC_DRAW);
glGenBuffers(1,&EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indexs.size()* sizeof(unsigned int),&indexs[0],GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);

draw:

        glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLE_STRIP, indexSize, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);


展开全文
• OpenGL球体绘制与球体贴图
• OpenGL球体的Phong渲染先上图，再解答。完整主要的源代码源代码剖析 先上图，再解答。 完整主要的源代码 #include <stdio.h> #include "GL/glus.h" struct LightProperties { GLfloat direction[3]; ...
OpenGL球体的Phong渲染先上图，再解答。完整主要的源代码源代码剖析
先上图，再解答。

完整主要的源代码
#include <stdio.h>
#include "GL/glus.h"
struct LightProperties
{
GLfloat direction[3];
GLfloat ambientColor[4];
GLfloat diffuseColor[4];
GLfloat specularColor[4];
};
struct MaterialProperties
{
GLfloat ambientColor[4];
GLfloat diffuseColor[4];
GLfloat specularColor[4];
GLfloat specularExponent;
};

struct LightLocations
{
GLint directionLocation;
GLint ambientColorLocation;
GLint diffuseColorLocation;
GLint specularColorLocation;
};

struct MaterialLocations
{
GLint ambientColorLocation;
GLint diffuseColorLocation;
GLint specularColorLocation;
GLint specularExponentLocation;
};

static GLUSprogram g_program;

static GLint g_projectionMatrixLocation;

static GLint g_modelViewMatrixLocation;

static GLint g_normalMatrixLocation;

static struct LightLocations g_light;

static struct MaterialLocations g_material;

static GLint g_vertexLocation;

static GLint g_normalLocation;

static GLuint g_verticesVBO;

static GLuint g_normalsVBO;

static GLuint g_indicesVBO;

static GLuint g_vao;

static GLuint g_numberIndicesSphere;

GLUSboolean init(GLUSvoid)
{
GLfloat viewMatrix[16];
GLfloat normalMatrix[9];

struct LightProperties light = { { 1.0f, 1.0f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } };

struct MaterialProperties material = { { 0.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, 20.0f };

GLUStextfile vertexSource;
GLUStextfile fragmentSource;

GLUSshape sphere;

glusFileLoadText("../Example05/shader/phong.vert.glsl", &vertexSource);
glusFileLoadText("../Example05/shader/phong.frag.glsl", &fragmentSource);

glusProgramBuildFromSource(&g_program, (const GLUSchar**) &vertexSource.text, 0, 0, 0, (const GLUSchar**) &fragmentSource.text);

glusFileDestroyText(&vertexSource);
glusFileDestroyText(&fragmentSource);

g_projectionMatrixLocation = glGetUniformLocation(g_program.program, "u_projectionMatrix");
g_modelViewMatrixLocation = glGetUniformLocation(g_program.program, "u_modelViewMatrix");
g_normalMatrixLocation = glGetUniformLocation(g_program.program, "u_normalMatrix");

g_light.directionLocation = glGetUniformLocation(g_program.program, "u_light.direction");
g_light.ambientColorLocation = glGetUniformLocation(g_program.program, "u_light.ambientColor");
g_light.diffuseColorLocation = glGetUniformLocation(g_program.program, "u_light.diffuseColor");
g_light.specularColorLocation = glGetUniformLocation(g_program.program, "u_light.specularColor");

g_material.ambientColorLocation = glGetUniformLocation(g_program.program, "u_material.ambientColor");
g_material.diffuseColorLocation = glGetUniformLocation(g_program.program, "u_material.diffuseColor");
g_material.specularColorLocation = glGetUniformLocation(g_program.program, "u_material.specularColor");
g_material.specularExponentLocation = glGetUniformLocation(g_program.program, "u_material.specularExponent");

g_vertexLocation = glGetAttribLocation(g_program.program, "a_vertex");
g_normalLocation = glGetAttribLocation(g_program.program, "a_normal");

glusShapeCreateSpheref(&sphere, 0.5f, 32);

g_numberIndicesSphere = sphere.numberIndices;

glGenBuffers(1, &g_verticesVBO);
glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO);
glBufferData(GL_ARRAY_BUFFER, sphere.numberVertices * 4 * sizeof(GLfloat), (GLfloat*) sphere.vertices, GL_STATIC_DRAW);

glGenBuffers(1, &g_normalsVBO);
glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO);
glBufferData(GL_ARRAY_BUFFER, sphere.numberVertices * 3 * sizeof(GLfloat), (GLfloat*) sphere.normals, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &g_indicesVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sphere.numberIndices * sizeof(GLuint), (GLuint*) sphere.indices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glusShapeDestroyf(&sphere);

glUseProgram(g_program.program);

glGenVertexArrays(1, &g_vao);
glBindVertexArray(g_vao);

glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO);
glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(g_vertexLocation);

glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO);
glVertexAttribPointer(g_normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(g_normalLocation);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO);

glusMatrix4x4LookAtf(viewMatrix, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

glusMatrix4x4ExtractMatrix3x3f(normalMatrix, viewMatrix);

glUniformMatrix4fv(g_modelViewMatrixLocation, 1, GL_FALSE, viewMatrix);
glUniformMatrix3fv(g_normalMatrixLocation, 1, GL_FALSE, normalMatrix);

glusVector3Normalizef(light.direction);

glusMatrix4x4MultiplyVector3f(light.direction, viewMatrix, light.direction);

glUniform3fv(g_light.directionLocation, 1, light.direction);
glUniform4fv(g_light.ambientColorLocation, 1, light.ambientColor);
glUniform4fv(g_light.diffuseColorLocation, 1, light.diffuseColor);
glUniform4fv(g_light.specularColorLocation, 1, light.specularColor);

glUniform4fv(g_material.ambientColorLocation, 1, material.ambientColor);
glUniform4fv(g_material.diffuseColorLocation, 1, material.diffuseColor);
glUniform4fv(g_material.specularColorLocation, 1, material.specularColor);
glUniform1f(g_material.specularExponentLocation, material.specularExponent);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glClearDepth(1.0f);

glEnable(GL_DEPTH_TEST);

glEnable(GL_CULL_FACE);

return GLUS_TRUE;
}

GLUSvoid reshape(GLUSint width, GLUSint height)
{
GLfloat projectionMatrix[16];

glViewport(0, 0, width, height);

glusMatrix4x4Perspectivef(projectionMatrix, 40.0f, (GLfloat) width / (GLfloat) height, 1.0f, 100.0f);

glUniformMatrix4fv(g_projectionMatrixLocation, 1, GL_FALSE, projectionMatrix);
}

GLUSboolean update(GLUSfloat time)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glDrawElements(GL_TRIANGLES, g_numberIndicesSphere, GL_UNSIGNED_INT, 0);

return GLUS_TRUE;
}

GLUSvoid terminate(GLUSvoid)
{
glBindBuffer(GL_ARRAY_BUFFER, 0);

if (g_verticesVBO)
{
glDeleteBuffers(1, &g_verticesVBO);

g_verticesVBO = 0;
}

if (g_normalsVBO)
{
glDeleteBuffers(1, &g_normalsVBO);

g_normalsVBO = 0;
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

if (g_indicesVBO)
{
glDeleteBuffers(1, &g_indicesVBO);

g_indicesVBO = 0;
}

glBindVertexArray(0);

if (g_vao)
{
glDeleteVertexArrays(1, &g_vao);

g_vao = 0;
}

glUseProgram(0);

glusProgramDestroy(&g_program);
}

int main(int argc, char* argv[])
{
EGLint eglConfigAttributes[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 0,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE
};

EGLint eglContextAttributes[] = {
EGL_CONTEXT_MAJOR_VERSION, 3,
EGL_CONTEXT_MINOR_VERSION, 2,
EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE, EGL_TRUE,
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_NONE
};

glusWindowSetInitFunc(init);

glusWindowSetReshapeFunc(reshape);

glusWindowSetUpdateFunc(update);

glusWindowSetTerminateFunc(terminate);

if (!glusWindowCreate("it_xiangqiang  Example Window", 640, 480, GLUS_FALSE, GLUS_FALSE, eglConfigAttributes, eglContextAttributes, 0))
{
printf("Could not create window!\n");
return -1;
}

glusWindowRun();

return 0;
}


源代码剖析
struct LightProperties light = { { 1.0f, 1.0f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } };//这是白光。
struct MaterialProperties material = { { 0.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, 20.0f };//具有白色镜面反射颜色的蓝色材料。
glusShapeCreateSpheref(&sphere, 0.5f, 32);//具有白色镜面反射颜色的蓝色材料。
glusMatrix4x4ExtractMatrix3x3f(normalMatrix, viewMatrix); //计算是在相机/视图空间中完成的。 因此，传递视图矩阵，这是一个刚体变换。
glusMatrix4x4MultiplyVector3f(light.direction, viewMatrix, light.direction);//将光转换为摄影机空间，就像目前在世界空间中一样
glUniform3fv(g_light.directionLocation, 1, light.direction);//设置灯glUniform4fv(g_material.ambientColorLocation, 1, material.ambientColor);//材质的值
glUniformMatrix4fv(g_projectionMatrixLocation, 1, GL_FALSE, projectionMatrix);//只需传递投影矩阵即可。 最终矩阵在着色器中计算。


展开全文
• 一、类似公自转 二、核心代码 //图形渲染 void RenderScene() ... //清楚缓存区：颜色缓存区、深度缓存区、模版缓存区 ... glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER... //设置颜色：地板、甜甜圈、球体 GLflo...

一、类似公自转
二、核心代码
//图形渲染

void RenderScene()
{
//清楚缓存区：颜色缓存区、深度缓存区、模版缓存区
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

//设置颜色：地板、甜甜圈、球体
GLfloat vFloorColor[] = {0.0f, 1.0f, 0.0f, 1.0f};
GLfloat vTorusColor[] = {1.0f, 0.0f, 0.0f, 1.0f};
GLfloat vSphereColor[] = {0.0f, 0.0f, 1.0f, 1.0f};

//基于当前时间动画：当前时间*60s
static CStopWatch rotTime;
float yRot = rotTime.GetElapsedSeconds()*60.0f;

//获取观察者矩阵并入栈
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.PushMatrix(mCamera);

//设置光源矩阵
M3DVector4f vLightPos = {0.0f, 10.0f, 5.0f, 1.0f};
M3DVector4f vLightEyePos;
//将光源矩阵和观察者矩阵相乘的结果放在vLightEyePos中
m3dTransformVector4(vLightEyePos, vLightPos, mCamera);

//使用管线控制器，平面着色器进行渲染
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor);
floorBatch.Draw();

//在模型视图矩阵堆栈中绘制以下图形：先压栈，绘制完毕后再出栈——始终对栈顶矩阵图形渲染

//绘制随机球体
for (int i = 0; i < NUM_SPHERES; i++) {
modelViewMatrix.PushMatrix();
//模型视图矩阵堆栈栈顶矩阵与随机球体矩阵相乘的结果放入栈顶
modelViewMatrix.MultMatrix(spheres[i]);
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightEyePos, vSphereColor);
//可与公转球体使用同一个容器类对象
sphereBatch.Draw();

modelViewMatrix.PopMatrix();
}

//设置甜甜圈平移距离（z轴负方向2.5）和旋转角度；
modelViewMatrix.Translate(0.0f, 0.0f, -2.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot, 0.0f, 0.1f, 0.0f);
//使用点光源着色器渲染
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vLightEyePos, vTorusColor);
torusBatch.Draw();
modelViewMatrix.PopMatrix();

//设置公转球体：反方向旋转，在x轴上平移0.8
modelViewMatrix.Rotate(yRot *-2.0f, 0.0f, 1.0f, 0.0f);
modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vSphereColor);
sphereBatch.Draw();

modelViewMatrix.PopMatrix();

//后台渲染完成后交给前台
glutSwapBuffers();
//基于时间动画：实时刷新窗口
glutPostRedisplay();
}

//图形定位

void SetupRC()
{
//设置窗口背景颜色
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//初始化管线控制器
shaderManager.InitializeStockShaders();
//开启深度测试：图形间重叠部分无须重复绘制
glEnable(GL_DEPTH_TEST);

//提交甜甜圈数据：三角形批次类对象、外圈半径、内圈半径、主半径三角形对数x、小半径三角形对数y(尽量：x=2*y,更圆滑)
gltMakeTorus(torusBatch, 0.4f, 0.15f, 30, 15);
//提交公转球体数据：三角形批次类对象、半径、底部到顶部三角形带的数量、一条三角形带中的三角形对数（一般指球体中间那条，为最大数）
gltMakeSphere(sphereBatch, 0.1f, 26, 20);

//线段模式，325个顶点
floorBatch.Begin(GL_LINES, 325);
for (GLfloat x = -20.0f; x <= 20.0f; x+=0.5f) {
/*
1.一个格子四个顶点，格子方向朝屏幕里面；
2.只绘制x和z轴方向上的顶点；
3.y轴坐标保持不变，负值，展示随机球体悬浮效果；
*/
floorBatch.Vertex3f(x, -0.55f, 20.0f);
floorBatch.Vertex3f(x, -0.55f, -20.0f);
floorBatch.Vertex3f(20.0f, -0.55f, x);
floorBatch.Vertex3f(-20.0f, -0.55f, x);
}
floorBatch.End();

//随机悬浮球体：y值不变，x、z值随机
for (int i = 0; i < NUM_SPHERES; i++) {
GLfloat x = (GLfloat)(((rand()%400)-200)*0.1f);
GLfloat z = (GLfloat)(((rand()%400)-200)*0.1f);
spheres[i].SetOrigin(x, 0.0f, z);
}
}

三、效果

GitHub

转载于:https://www.cnblogs.com/lybSkill/p/10021965.html
展开全文
• 球体贴图是老生常谈的东西了，很多时候都会遇到。选择什么方式去进行贴图，有时候也还是要考虑一番的。——ZwqXin.com第一次接触球体贴图这玩意，是课程的第三次作业的时候做的Demo(LostHeaven)。那时候恰逢汶川的...
球体贴图是老生常谈的东西了，很多时候都会遇到。选择什么方式去进行贴图，有时候也还是要考虑一番的。——ZwqXin.com第一次接触球体贴图这玩意，是课程的第三次作业的时候做的Demo(LostHeaven)。那时候恰逢汶川的地震，自己就选择了那么个祈祷与人类破坏自然的主题，一开始的场景是一个下坠并“破碎”的地球。这个地球就是最初的我的球体贴图应用物了。怀念一下，贴图参考的是NEHE第二十多课那个，记不太清了，大致是直接用一张长方形纹理贴上去，然后设置一下纹理的生成方式（glTexGeni）之类的吧。其实哪怕是现在，这种贴图方式也是很平常的，就是Cylinder Map，把贴向一个柱体的纹理直接贴上球体上，让它包裹球体。确实简单，问题是球体的两极会因为过采样而出现褶皱。如果那两个点完全不暴露给观看者的话，那还好，不然就真的颇难看了。本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明      原文地址：http://www.zwqxin.com/archives/opengl/sphere-mapping-cubemap-stuff.html因为要考虑到贴到球体时的扭曲问题，赤道部分向两级的采样需求逐渐降低，所以那贴图一般都是中间“肥”上下两端“瘦”，呈现一定的扭曲，以尽量达到采样均匀，且贴到球体后看上去自然一点。对于两级的过采样问题，可以用一些方法降低采样率，具体不太懂所以就不多说了。针对CylinderMap的这些缺陷，部分人们开始选用CubeMap作为贴图方式。而本文也主要谈这种方式。 关于CubeMapping：[Shader快速复习：Cube Mapping(立方环境贴图)]说到星体渲染，可能有人会知道Celestia这个软件，使用它可以渲染出一个绚烂的太空场景。这类软件可谓与球体贴图最靠近乎的东西之一了，从它对球体贴图方式的采用选择上看起吧：Creating Textures for Celestia上面这篇文章提及了主要使用的是Cylinder Map（至少在1.4版），而Cube Map作为一个“将来也许会支持”的选择项而被介绍。可见，Celestia应该还是比较偏好于前者的，这里面有两个比较重要的原因。1. 矩形的星体纹理，比起六张一体的立方纹理，较容易获得如果你在网上搜索一些星体的纹理，譬如地球啊、月球啊、火星啊，你搜到的基本都是一般的长方形纹理吧，配以分辨率(譬如4k纹理通常指长边至少为4000像素的纹理图)。所以，一般是很少见到原生的cubemap(6张图或dds文件)的。在著名的NASA分网站（http://earthobservatory.nasa.gov/）上，你可以搜到一堆堆的星体纹理，非常丰富，但大多都是基于一般的单一矩形纹理的：通过一些工具，我们可以将这样的图片转换成6张子图，也就是把cylinderMap转换成CubeMap。Sourceforge项目“cubemap”（当前版本1.03）就是这样的工具之一，我就是使用它把上面一张2D纹理转换成6张纹理组成cubemap的，还算是比较方便的，效果也不错：所以说，虽然CubeMap的来源一般比较少，但动动手也是可以自己找素材做出来的。2.cubemap贴图的时候6张纹理在球体表面贴合处会出现缝迹如果说Cylinder贴图的弊端是两级位置的过采样造成的扭曲，那么Cube贴图的相应弊端就是接合处的欠采样造成的缝痕了。在这个论坛地址上可以看到一些截图。恰巧这个帖子也是针对这两种方法的讨论，建议看看。里面提及使用Cylinder贴图的同时使用VT来处理的方式，不过这对于我们来说实在也太specific了。一般来说，相对于cylinder贴图造成的那种“几公里外”也能看到的两级扭曲痛苦状，cubemap这种缝痕基本是不把眼睛贴向表面上都不会察觉的程度。贴到表面——这本身就有纹理本身欠采样造成的巨大锯齿在那里了——任何纹理都会这样，所以说CubeMap的这种问题在很多时候都可以忽略的。但是确实也有采用超高分辨率贴图，同时也允许观看者近距离靠近球体的场合，这时候这道缝就很成问题了。也是有对应的大致解决方案的，而且很简单。既然分别都是采样造成的问题，何不对应地在某些临界点改变一下采样率呢？对于Cylinder方式的贴图，在两级减少采样，这涉及采样规则方式的改变和效果的问题，临界点也很难界定，所以是很难做到的；而Cube方式的贴图，只要在边界处向相邻的纹理边界采样并混合（插值）一下，应该就能很好地拯救（模糊）那些缝痕。事实上，这甚至不用我们手动去搞，OpenGL3.2开始已经向我们提供了这么一个核心扩展了：seamless_cube_map。在以前的GPU上是无法把纹理的filtering应用在cubemap相邻的两张子纹理上的。但既然如今可以做到，那么这个扩展就很自然出现的，只要在两纹理边界处像素线性插值一下，缝痕就基本消失了。当然开启这个扩展是会有点点影响效率的（毕竟采样工作增加了嘛），所以如果你确实没有需要近处去观摩一个cubemap（不限于球体贴图）的边缘，那就不要启用这个扩展了。事实上最好也要避免在运行渲染期间去切换这个OpenGL状态，很费效率。在初始化的时候设定，然后不要再去改变它——opengl的spec上如是说。设定很简单：C++代码 初始化阶段glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);  以下是开启这个状态前后的程序截图，可见前者明显看到一条缝痕，后者基本看不到了：如果真的需要一个总结的话，我会说：是时候使用CubeMap来做一般的球面贴图了。本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明2011-10-4
展开全文
• 球体贴图是老生常谈的东西了，很多时候都会遇到。选择什么方式去进行贴图，有时候也还是要考虑一番的。——ZwqXin.com第一次接触球体贴图这玩意，是课程的第三次作业的时候做的Demo(LostHeaven)。那时候恰逢汶川的...
• 现在画了一个球体，但是不知道怎样把一张世界地图的图片贴到他的表面上，希望有大神能帮帮我，谢谢你们了~！
• OpenGL球体贴图的的整个流程就是计算出球体和纹理材质坐标，然后画出球体，按照纹理坐标将bitmap贴上去。 具体方法和上一篇文章画一个球体类似 OpenGL绘制球体 ，只是需要创建材质，并且需要构建一个用来渲染的...
• 上一节我们学会了使用OpenGL着色器，但是在片段着色器中，我们使用简单纯色来绘制物体，这一节，我们要在片段着色器中使用采用器对纹理进行采样输出，作为物体表面的颜色，进而绘制带有纹理贴图的物体。纹理纹理简单...
• #include #include "gl/glut.h" #include #include #include // 参数指定正方形的位置和大小 float xsite = 100.0; //圆心坐标 float ysite = 200.0;...GLsizei rsize = 20;...float ystep = 0.0
• opengl球体 环境映射很正常 但纹理映射贴不上去 用的是直接画球函数glutsolidphere（1,100,100）； 茶壶的环境映射，纹理映射都可以正常画出；长方体给了纹理坐标也正常。 球体的是不是也要给纹理坐标啊？ ...
• OpenGL绘制球体
• 易语言OpenGL控制球体源码,OpenGL控制球体,建立OPenGL组件,撤消OPenGL组件,框架初始化,绘图,画图,按键
• OpenGL控制球体.rar
• 通过OpenGL基本体素，例如三角形、三角形带、四边形、四边形带，它们都可以构成的球体。通过改变半径控制大小，通过改变角度的改变大小就可以改变顶点的数目和密度，通过在调用回调函数设置模式，就可以改变填充状态...
• ## qt opengl 画球体

千次阅读 2018-09-15 13:41:57
和一般写opengl的程序一样，就直接出代码不多说。  在qt中我使用qopenglwidget来操作opengl程序，声明如下 #ifndef WIDGET_H #define WIDGET_H #include &lt;QOpenGLWidget&gt; #include "...
• 1. 利用GLUT库，编写一个OpenGL程序，实现以下功能：  仿照课本的例子，绘制若干OpenGL基本体素（三角形、三角形带、四边形、四边 形带）构成的球体，  可以控制改变球的数量和球的体积，来改变基本体素的数量...
• opengl画球~~_(:зゝ∠)_
• ## OpenGL 旋转球体

千次阅读 2011-05-24 15:43:00
#include GLfloat X = 10.0f; GLfloat Y = 1.0f; GLfloat Z = 5.0f; void myDisplay(void) { GLfloat diffuse[] = {0.7,0.7,0.0,1.0}; glClear (GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,1.0...
• 用VS2012编写
• 真实感球体绘制 opengl
• 基于MFC的opengl绘图 利用顶点数组绘成圆球；简单的openGL应用，适合初学者学习；Application of openGL C++,MFC tec
• 今天用opengl建模了一个球体，接下来简单的介绍一下自己的实现方法。 先用一张比较容易理解的图来说明。 如图所示，假设要建模一个单位球体，球上任意一点的坐标都可由图中所示公式表示。 接下来的代码将生成15...

...