渲染世界的OPENGL<12> 一些有趣的纹理着色器

从着色器访问纹理贴图是非常简单的。纹理坐标将会作为属性传递到我们的顶点着色器,在片段着色器当中,这些属性通常是在顶点之间进行平滑插值的。片段着色器使用这些差值纹理坐标来对纹理进行采样。

(1)只处理纹理单元

// The TexturedIdentity Shader
// Vertex Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
//最为简单的纹理渲染器
#version 130
//传递到顶点着色器当中一个顶点坐标
in vec4 vVertex;
//传递到顶点着色器当中一个纹理坐标,注意核心部分就是这个s和t纹理坐标的输入
//顶点属性vTexCoords以及输出变量vVaringTexCoords。用纹理坐标在三角形表面进行差值
//所需要的,就是这些
in vec2 vTexCoords;

smooth out vec2 vVaryingTexCoords;

void main(void) 
    { 
    vVaryingTexCoords = vTexCoords;
    gl_Position = vVertex;
    }

以上就是仅仅处理纹理单元的顶点着色器,在顶点着色器当中,仅仅对顶点坐标以及顶点的纹理坐标s、t进行相应的传递以及处理。因为其为2D纹理图像,所以纹理坐标仅仅包含s、t。

// The TexturedIdentity Shader
// Fragment Shader
// Richard S. Wright Jr.
// OpenGL SuperBible
#version 130

//注意这个新的数据变量类型sample2D
//一个采样器(sample)实际上就是一个这么好设计(使用glUniform1i来设置值)它代表我们将要
//采样的纹理所绑定的纹理单元。sample2D中的2D表示这是一个2D纹理,我们也可以使用1D
//2D或者3D等类型的采样器。 这个值总是设置为0,代表指示纹理单元0。
uniform sampler2D colorMap;

out vec4 vFragColor;
smooth in vec2 vVaryingTexCoords;


void main(void)
   { 
   //将当前传递进片段着色器当中的st纹理坐标和colormap采样进行texture函数
   //从而得到最终要进行光栅化的片段颜色。
   vFragColor = texture(colorMap, vVaryingTexCoords.st);
   }

如上就是纹理坐标的片段着色器,其中仅仅使用了一个texture函数作为fragColor的值。


#pragma comment(lib,"GLTools.lib")

#include <GLTools.h>            // OpenGL toolkit
#include <GLShaderManager.h>    // Shader Manager Class
#include <GL/glut.h>            // Windows FreeGlut equivalent


GLBatch triangleBatch;
GLShaderManager shaderManager;

GLint   myTexturedIdentityShader;
GLuint  textureID;

///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
    glViewport(0, 0, w, h);
}


// 加载一个tga图像作为一个2D纹理,并且进行必要的初始化
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
    GLbyte *pBits;
    int nWidth, nHeight, nComponents;
    GLenum eFormat;

    // 读取对应文件当下的图像
    pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
    if (pBits == NULL)
        return false;
    //设置对应图象的功能以及设置环绕模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
        eFormat, GL_UNSIGNED_BYTE, pBits);
    //在设置完成参数之后,可以释放对应的字符指针
    free(pBits);

    if (minFilter == GL_LINEAR_MIPMAP_LINEAR ||
        minFilter == GL_LINEAR_MIPMAP_NEAREST ||
        minFilter == GL_NEAREST_MIPMAP_LINEAR ||
        minFilter == GL_NEAREST_MIPMAP_NEAREST)
        //生成对应的2维图像
        glGenerateMipmap(GL_TEXTURE_2D);

    return true;
}


///////////////////////////////////////////////////////////////////////////////
// 设置渲染环境
void SetupRC()
{
    // 背景
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    //渲染器初始化
    shaderManager.InitializeStockShaders();

    // Load up a triangle
    GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f,
        0.5f, 0.0f, 0.0f,
        0.0f, 0.5f, 0.0f };

    GLfloat vTexCoords[] = { 0.0f, 0.0f,
        1.0f, 0.0f,
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值