视频加载失败

课程

1244 字
约 4 分钟

10.2 球体纹理映射

计算机图形学labs/lab10-texture-mapping·更新于 2026-09-15

10.2 球体纹理映射

1. 任务描述

本关任务

为了完成本关任务,你需要掌握:了解计算机图形学的纹理映射原理,了解 OpenGL 程序的贴图纹理映射方法。 为了在场景中添加纹理映射,需要执行以下步骤:

  1. 纹理控制:定义纹理如何包裹物体的表面。
  2. 定义纹理:利用矩形图像进行贴图是二维纹理贴图中常用的方法。
  3. 纹理映射方式:用函数可以设置纹理映射的方式。
  4. 纹理坐标:定义纹理与几何坐标对应关系的纹理坐标。

预期输出

预期输出

具体要求

提示:每一步相关知识可以点击展开查看 给球体添加纹理映射。

1. 设置控制纹理映射

设置纹理映射控制的函数,参数分别如下:

    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   

2. 定义一纹理贴图

定义一维纹理贴图函数,参数分别如下:

    glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
相关知识点击查看

一维纹理:
创建一个简单的一维纹理可使用 glTexImage1D() 函数。

void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *texels);

该函数用来定义一个一维纹理。除了参数 texels 现在为一维数组之外,所有参数和 glTexImage2D() 函数中相应的参数有相同的含义。

3. 设置纹理映射方式

设置纹理映射方式,函数参数如下:

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  

4. 设置纹理坐标自动生成函数

设置纹理坐标自动生成函数参数如下:

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);       
    glTexGenfv(GL_S, currentPlane, currentCoeff);
相关知识点击查看

自动纹理坐标生成函数:
下面原型函数可提供自动纹理坐标生成功能:

void glTexGen{ifd}(GLenum coord, GLenum pname, TYPE param);

参数说明如下: (1)coord 指定要产生的纹理坐标类型,可取 GL_S、GL_T、GL_R 或者 GL_Q; (2)pname 指定一个纹理坐标生成函数的符号名,必须是 GL_TEXTURE_GEN_MODE、GL_OBJECT_PLANE、GL_EYE_PLANE 之一; (3)param 指定一个指向纹理生成参数数组的指针。使用 glEnable/glDisable 函数通过使用 GL_TEXTURE_GEN_S、GL_TEXTURE_GEN_T、GL_TEXTURE_GEN_R、或 GL_TEXTURE_GEN_Q 来启用或关闭自动纹理生成功能。

相关知识

相关知识可以在具体步骤中点击展开查看


开始你的任务吧,祝你成功!

2. 我的回答

文件 step1/test1.cpp:

// 提示:在合适的地方修改或添加代码
#include <GL/freeglut.h>
#include<stdlib.h>
#include<stdio.h>
// 评测代码所用头文件-开始
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
// 评测代码所用头文件-结束

#define stripeImageWidth 32
GLubyte stripeImage[4 * stripeImageWidth];


void makeStripeImage(void) 		//生成纹理
{
    
    int j;
    for (j = 0; j < stripeImageWidth; j++)
    {
        stripeImage[4 * j + 0] = (GLubyte)((j <= 4) ? 255 : 0);
        stripeImage[4 * j + 1] = (GLubyte)((j > 4) ? 255 : 0);
        stripeImage[4 * j + 2] = (GLubyte)0;
        stripeImage[4 * j + 3] = (GLubyte)255;
    }
}
// 平面纹理坐标生成
static GLfloat xequalzero[] = { 1.0, 1.0, 1.0, 1.0 };
static GLfloat slanted[] = { 1.0, 1.0, 1.0, 0.0 };
static GLfloat* currentCoeff;
static GLenum currentPlane;
static GLint currentGenMode;
static float roangles;
void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    makeStripeImage();
    
    //********1.请输入代码设置纹理映射控制函数********//
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   
    //**************************************************//
    
    //********2.请输入代码设置纹理的定义函数********//
    glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
    //**************************************************//
    
    //********3.请输入代码进行纹理映射方式设置*********//
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
    //********************************************//
    
    currentCoeff = xequalzero;
    currentGenMode = GL_OBJECT_LINEAR;
    currentPlane = GL_OBJECT_PLANE;
    
    //****************4.自动纹理坐标生成功能功能函数******************//
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);       
    glTexGenfv(GL_S, GL_OBJECT_PLANE, currentCoeff);
    //*******************************************************//
    
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_1D);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);
    glMaterialf(GL_FRONT, GL_SHININESS, 64.0);
    roangles = 45.0f;
}
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glRotatef(roangles, 0.0, 0.0, 1.0);
    glutSolidSphere(2.0, 32, 32);
    glPopMatrix();
    glFlush();
}
void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-3.5, 3.5, -3.5 * (GLfloat)h / (GLfloat)w,
            3.5 * (GLfloat)h / (GLfloat)w, -3.5, 3.5);
    else
        glOrtho(-3.5 * (GLfloat)w / (GLfloat)h,
            3.5 * (GLfloat)w / (GLfloat)h, -3.5, 3.5, -3.5, 3.5);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}



int main(int argc, char *argv[])
{

	glutInit(&argc, argv);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("几何变换示例");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoopEvent();     
     
    /*************以下为评测代码,与本次实验内容无关,请勿修改**************/
	GLubyte* pPixelData = (GLubyte*)malloc(400 * 400 * 3);//分配内存
    GLint viewport[4] = {0};
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGetIntegerv(GL_VIEWPORT, viewport);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
    cv::Mat img;
    std::vector<cv::Mat> imgPlanes;
    img.create(400, 400, CV_8UC3);
    cv::split(img, imgPlanes);

    for (int i = 0; i < 400; i++) {
        unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
        unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
        unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);
        for (int j = 0; j < 400; j++) {
            int k = 3 * (i * 400 + j);
            plane2Ptr[j] = pPixelData[k];
            plane1Ptr[j] = pPixelData[k + 1];
            plane0Ptr[j] = pPixelData[k + 2];
        }
    }
    cv::merge(imgPlanes, img);
    cv::flip(img, img, 0);
    cv::namedWindow("openglGrab");
    cv::imshow("openglGrab", img);
    //cv::waitKey();
    cv::imwrite("../img_step1/test.jpg", img);
    return 0;
}

Profile Image of the Author
Sonder
好想要技术
这是公告标题
这只是一个公告
分类
标签
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录