如何为这个球体添加纹理?
Posted
技术标签:
【中文标题】如何为这个球体添加纹理?【英文标题】:How to add texture to this sphere? 【发布时间】:2020-04-16 13:27:56 【问题描述】:我创建了一个旋转的有线球体。我已经为立方体做了纹理,但球体似乎是个问题。 我想将世界地图作为纹理添加到这个球体。有什么建议吗?
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <thread>
#include <chrono>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
using namespace std;
GLuint texture;
int start = 1;
GLfloat xRotated, yRotated, zRotated;
GLdouble radius = 1;
void init()
glOrtho(-1000 / 2, 1000 / 2, -1000 / 2, 1000 / 2, -500, 500);
GLuint glInitTexture(char* filename)
GLuint t = 0;
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
unsigned char* data = stbi_load(filename, &width, &height, &nrChannels, 0);
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//unsigned char data[] = 255, 0, 0, 255 ;
if (data)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
else
std::cout << "fail";
return t;
void drawImage(GLuint file, float x, float y, float w, float h)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glPushMatrix();
//glTranslatef(x, y, 0.0);
//glRotatef(angle, 0.0, 0.0, 1.0);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, file);
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 0.01;
//glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
//Plots points of both graphs together
//Displays map on screen
void drawMap()
std::cout << "\nDraw map\n";
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(90.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -15);
for (int i = 0; i < 10000; i++)
glClear(GL_DEPTH_BUFFER_BIT);
drawImage(texture, 0, 0, 100, 200);
//std::this_thread::sleep_for(std::chrono::milliseconds(500));
glutSwapBuffers();
glEnd();
glFlush();
void render()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//glFlush();
glPointSize(5);
glColor3f(1, 1, 1);
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-450, -250, 10);
glEnd();
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-250, -450, 10);
glEnd();
drawMap();
//plotPoints();
glFlush();
void Kbevent(unsigned char key, int x, int y)
if (key == 's')
start = start % 2;
glutPostRedisplay();
int main(int argc, char* argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1560, 810);
glutCreateWindow("Applying Textures");
init();
xRotated = yRotated = zRotated = 30.0;
xRotated = 33;
yRotated = 40;
char fn[] = "map.jpg";
texture = glInitTexture(fn);
glutDisplayFunc(render);
//glutReshapeFunc(reshapeFunc);
//glutIdleFunc(idleFunc);
glutKeyboardFunc(Kbevent);
glutMainLoop();
return 0;
应用 2D 纹理的问题在于,当您将 2D 纹理包裹到球体上时,球体的顶部和底部区域会显得纹理被挤压。
【问题讨论】:
使用gluSphere
而不是glutSolidSphere
见Applying map of the earth texture a Sphere,甚至可能是Bump-map a sphere with a texture map
【参考方案1】:
我建议使用gluSphere
和gluQuadricTexture
而不是glutSolidSphere
。例如:
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
对于连续旋转,您需要增加旋转角度并不断更新窗口 (glutPostRedisplay
)。例如:
void redisplayFunc(void)
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 1;
glutPostRedisplay();
【讨论】:
谢谢!!我现在要做的就是轮换 @ShreyasB 我已经扩展了答案。以上是关于如何为这个球体添加纹理?的主要内容,如果未能解决你的问题,请参考以下文章