OpenGL -- 纹理

一维的纹理

截图

这里写图片描述

代码

#include <gl\glut.h>    
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

GLubyte texLine[16]; // 6-element texture array

void myinit(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 表示要清除颜色缓冲以及深度缓冲

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    int k;
    // define two green elements for the texture pattern
    for (k = 0; k <= 2; k += 2)
    {
        texLine[4 * k] = 0;
        texLine[4 * k + 1] = 255;
        texLine[4 * k + 2] = 0;
        texLine[4 * k + 3] = 255;
    }
    // define two red elements for the texture pattern
    for (k = 1; k <= 3; k += 2)
    {
        texLine[4 * k] = 255;
        texLine[4 * k + 1] = 0;
        texLine[4 * k + 2] = 0;
        texLine[4 * k + 3] = 255;
    }
    // texLine,0 255 0 255 绿色, 255 0 0 255 红色
    // textLine 分4段 绿,红,绿,红

    /* 定义纹理 */
    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texLine);
    /* 控制滤波 */
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glEnable(GL_TEXTURE_1D);
}

void Draw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glColor3f(1.0,1.0, 1.0); // 设置颜色为白色
    float point1[] = { -0.5f, -0.5f };
    float point2[] = { 0.5f, 0.5f };
    glBegin(GL_LINES); 
        // 使用纹理,全部使用,这样直线会显示成绿红绿红
        glTexCoord1f(0.0);
        glVertex2fv(point1);
        glTexCoord1f(1.0);
        glVertex2fv(point2);
    glEnd();

    glPushMatrix();
    glTranslatef(-0.2f, 0, 0); //平移
    glBegin(GL_LINES);
        // 使用纹理,1/4到1,这样直线会显示成红绿红
        glTexCoord1f(0.25);
        glVertex2fv(point1);
        glTexCoord1f(1.0);
        glVertex2fv(point2);
    glEnd();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.2f, 0, 0); //平移
    glBegin(GL_LINES);
        // 使用纹理,0到3/4,这样直线会显示成绿红绿
        glTexCoord1f(0.0);
        glVertex2fv(point1);
        glTexCoord1f(0.75);
        glVertex2fv(point2);
    glEnd();
    glPopMatrix();

    // 刷新OpenGL命令队列
    glFlush();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    //设置窗口左上角的位置  
    //glutInitWindowPosition(100, 100);
    //设置窗口的宽高  
    glutInitWindowSize(400, 500);
    glutCreateWindow("OpenGL一维纹理");

    //myinit();
    glutDisplayFunc(&Draw);

    glutMainLoop(); // glut事件处理循环
    return 0;
}

参考

《计算机图形学》(第四版)
Computer Graphics with OpenGL Fourth Edition

二维纹理

截图

这里写图片描述

完整代码

#include <gl\glut.h>    
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define PI 3.1415926     
int WinWidth, WinHeight;

// 旋转角度,初始可以随便设置
float rotateX = 20.0f;
float rotateY = 30.0f;

/* 创建纹理 */
#define ImageWidth 64
#define ImageHeight 64
GLubyte Image[ImageWidth][ImageHeight][4];

void makeImage(void)
{
    int i, j;
    for (i = 0; i < ImageWidth; i++)
    {
        for (j = 0; j < ImageHeight; j++)
        {
            // 定义成黑白相间的 8*8 类型 1.0,1.0, 1.0 白色, 黑色 0 0 0
            int c = ((((i & 0x8) == 0) ^ ((j & 0x8)) == 0)) * 255;
            Image[i][j][0] = (GLubyte)c;
            Image[i][j][1] = (GLubyte)c;
            Image[i][j][2] = (GLubyte)c;
            Image[i][j][3] = (GLubyte)255;
        }
    }
}

void myinit(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    //glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    makeImage();
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    /* 定义纹理 */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ImageWidth, ImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &Image[0][0][0]);
    /* 控制滤波 */
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    /* 说明映射方式*/
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    /* 启动纹理映射 */
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_FLAT);
}

void Draw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    // 立方体的8个顶点坐标
    GLfloat vertex_list[][3] = {
        -0.5f, -0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        -0.5f, 0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        -0.5f, -0.5f, 0.5f,
        0.5f, -0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
    };

    GLint index_list[][4] = {
        0, 2, 3, 1,
        0, 4, 6, 2,
        0, 1, 5, 4,
        4, 5, 7, 6,
        1, 3, 7, 5,
        2, 6, 7, 3,
    };

    // 只有正面,并且只显示边线,不进行填充
    /* glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/

    // 设置旋转
    glRotatef(rotateX, 1.0f, 0.0f, 0.0f);
    glRotatef(rotateY, 0.0f, 1.0f, 0.0f);

    // 定义不同的颜色
    GLfloat colors[][3] = { { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 },
    { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 }, { 0.0, 1.0, 1.0 },
    { 1.0, 0.5, 0.5 }, { 0.0, 0.5, 0.5 } };

    int i, j;

    float tex[][2] = { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f } };

    glColor3f(1, 1, 1);
    glBegin(GL_QUADS); // 绘制四边形
    for (i = 0; i < 6; ++i)         // 有六个面,循环六次
    {
        glColor3f(colors[i][0], colors[i][1], colors[i][2]);
        for (j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次
        {
            glTexCoord2f(tex[j][0], tex[j][1]);
            glVertex3fv(vertex_list[index_list[i][j]]);
        }
    }
    glEnd();

    glutSwapBuffers();
}

void Reshape(int w, int h)
{
    WinWidth = w;
    WinHeight = h;
    // //改变显示区域,起始位置为客户端窗口左下角(非坐标原点)
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //宽高比改为当前值,视线区域与屏幕大小一致;
    gluPerspective(45, 1.0*WinWidth / WinHeight, 1, 1000);
    // 开启更新深度缓冲区的功能
    glEnable(GL_DEPTH_TEST);
    // 摄像机视图观看,从 (0,5,20) 往(0,0,0)处看,(0,1,0)为正方向
    gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0);
}

void SpecialKeys(int key, int x, int y)
{
    if (key == GLUT_KEY_UP)   rotateX -= 2.0f;
    if (key == GLUT_KEY_DOWN)  rotateX += 2.0f;
    if (key == GLUT_KEY_LEFT)  rotateY -= 2.0f;
    if (key == GLUT_KEY_RIGHT)  rotateY += 2.0f;

    if (rotateX > 356.0f)  rotateX = 0.0f;
    if (rotateX < -1.0f)  rotateX = 355.0f;
    if (rotateY > 356.0f)  rotateY = 0.0f;
    if (rotateY < -1.0f)  rotateY = 355.0f;

    //刷新窗口
    glutPostRedisplay();
}

int main(int argc, char *argv[])
{
    WinWidth = 800;
    WinHeight = 800;
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE);
    //glutInitWindowPosition(100, 100);
    glutInitWindowSize(WinWidth, WinHeight);
    glutCreateWindow("OpenGL二维纹理");

    myinit();
    glutReshapeFunc(&Reshape);
    glutDisplayFunc(&Draw);

    glutSpecialFunc(SpecialKeys);

    glutMainLoop();
    return 0;
}

参考

多颜色的立方体旋转
http://blog.csdn.net/qq_26437925/article/details/53055535

OpenGL一个简单的纹理贴图
http://www.cnblogs.com/xiacl/archive/2012/05/06/2486120.html

改进

在画立方体时,只对部分面进行纹理贴图

截图

这里写图片描述

修改的部分代码

// 定义不同的颜色
    GLfloat colors[][3] = { { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 },
    { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 }, { 0.0, 1.0, 1.0 },
    { 1.0, 0.5, 0.5 }, { 0.0, 0.5, 0.5 } };

    int i, j;

    float tex[][2] = { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f } };

    for (i = 0; i < 6; ++i)         // 有六个面,循环六次
    {
        // 只绘制两个面的纹理贴图,纹理的启动和禁止用到 glEnable/glDisable
        if (i < 2)
            glEnable(GL_TEXTURE_2D); 
        else
            glDisable(GL_TEXTURE_2D);

        glBegin(GL_QUADS); // 绘制四边形
        glColor3f(colors[i][0], colors[i][1], colors[i][2]);
        for (j = 0; j < 4; ++j)     // 每个面有四个顶点,循环四次
        {
            glTexCoord2f(tex[j][0], tex[j][1]);
            glVertex3fv(vertex_list[index_list[i][j]]);
        }
        glEnd();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值