ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

7-纹理坐标包装

2021-04-24 23:04:02  阅读:235  来源: 互联网

标签:userData 1.0 包装 0.0 0.3 TEXTURE 纹理 坐标 GL


目录

概述

纹理包装模式用于指定纹理坐标超出[0.0, 1.1]范围时所发生的行为,用glTexParameter[i|f] [v]设置,这些模式可以为s、t、r坐标单独设置。GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T和GL_TEXTURE_WRAP_R分别定义s和t和r坐标超出[0.0, 1.0]范围时发生的行为。

包装模式选择:

纹理包装模式 描述
GL_REPEAT 重复纹理
GL_CLAMP_TO_EDGE 限定读取纹理的边缘
GL_MIRRORED_REPEAT 重复纹理和镜像

正常纹理坐标是[0, 1]之间,而右边的纹理坐标为[-1, 2],比正常的大了3倍,所以,一行的小方块数目为12个。

左边为正常纹理,右边为纹理坐标包装

纹理坐标包装的坐标设置:
    GLfloat vVertices[] = {
            -0.3f,  0.3f, 0.0f, 1.0f,  // Position 0
            -1.0f,  -1.0f,              // TexCoord 0
            -0.3f, -0.3f, 0.0f, 1.0f, // Position 1
            -1.0f,  2.0f,              // TexCoord 1
            0.3f, -0.3f, 0.0f, 1.0f, // Position 2
            2.0f,  2.0f,              // TexCoord 2
            0.3f,  0.3f, 0.0f, 1.0f,  // Position 3
            2.0f,  -1.0f               // TexCoord 3
    };

正常纹理坐标:
    GLfloat vVertices[] = {
            -0.3f,  0.3f, 0.0f, 1.0f,  // Position 0
            0.0f,  0.0f,              // TexCoord 0
            -0.3f, -0.3f, 0.0f, 1.0f, // Position 1
            0.0f,  1.0f,              // TexCoord 1
            0.3f, -0.3f, 0.0f, 1.0f, // Position 2
            1.0f,  1.0f,              // TexCoord 2
            0.3f,  0.3f, 0.0f, 1.0f,  // Position 3
            1.0f,  0.0f               // TexCoord 3
    };

image

源码解析

#include <stdlib.h>
#include "esUtil.h"

typedef struct
{
    GLuint programObject;
    GLint samplerLoc;
    GLint offsetLoc;
    GLuint textureId;
} myUserData;

GLubyte *GenCheckImage(int width, int height, int checkSize)
{
    int x, y;
    GLubyte *pixels = (GLubyte *)malloc(width * height * 3);
    if (pixels == NULL) {
        return NULL;
    }
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            GLubyte rColor = 0;
            GLubyte bColor = 0;
            if ((x/checkSize)%2 == 0) {
                rColor = 255 * ((y/checkSize) % 2);
                bColor = 255 * (1 - ((y/checkSize) % 2));
            } else {
                bColor = 255 * ((y/checkSize) % 2);
                rColor = 255 * (1 - ((y/checkSize) % 2));
            }

            pixels[(y*width + x)*3] = rColor;
            pixels[(y*width + x)*3 + 1] = 0;
            pixels[(y*width + x)*3 + 2] = bColor;
        }
    }
    return pixels;
}

GLuint CreateTexture2D()
{
    GLuint textureId;
    int width = 256, height = 256;
    GLubyte *pixels;
    pixels = GenCheckImage(width, height, 64);
    if (pixels == NULL) {
        return 0;
    }
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
            0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return textureId;
}

int Init(MYESContext *myesContext)
{
    myUserData *userData = (myUserData *)myesContext->userData;
    char vShaderStr[] =
            "#version 300 es \n"
            "uniform float u_offset; \n"
            "layout(location = 0) in vec4 a_position; \n"
            "layout(location = 1) in vec2 a_texCoord; \n"
            "out vec2 v_texCoord; \n"
            "void main() \n"
            "{ \n"
            "   gl_Position = a_position; \n"
            "   gl_Position.x += u_offset; \n"
            "   v_texCoord = a_texCoord; \n"
            "} \n";

    char fShaderStr[] =
            "#version 300 es \n"
            "precision mediump float; \n"
            "in vec2 v_texCoord; \n"
            "layout(location = 0) out vec4 outColor; \n"
            "uniform sampler2D s_texture; \n"
            "void main() \n"
            "{ \n"
            "   outColor = texture(s_texture, v_texCoord); \n"
            "} \n";
    userData->programObject = myesLoadProgram(vShaderStr, fShaderStr);
    userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
    userData->offsetLoc = glGetUniformLocation(userData->programObject, "u_offset");
    userData->textureId = CreateTexture2D();
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    return GL_TRUE;
}

void Draw(MYESContext *myesContext)
{
    myUserData *userData = (myUserData *)myesContext->userData;
    GLfloat vVertices[] = {
            -0.3f,  0.3f, 0.0f, 1.0f,  // Position 0
            -1.0f,  -1.0f,              // TexCoord 0
            -0.3f, -0.3f, 0.0f, 1.0f, // Position 1
            -1.0f,  2.0f,              // TexCoord 1
            0.3f, -0.3f, 0.0f, 1.0f, // Position 2
            2.0f,  2.0f,              // TexCoord 2
            0.3f,  0.3f, 0.0f, 1.0f,  // Position 3
            2.0f,  -1.0f               // TexCoord 3
    };
    GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
    glViewport(0, 0, myesContext->width, myesContext->height);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(userData->programObject);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), vVertices);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), &vVertices[4]);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, userData->textureId);
    glUniform1i(userData->samplerLoc, 0);
    // 这里是设置重复纹理
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glUniform1f(userData->offsetLoc, -0.7f);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

    // 这里是设置限定读取纹理的边缘
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glUniform1f(userData->offsetLoc, 0.0f);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

    // 这里是设置重复纹理和镜像
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    glUniform1f(userData->offsetLoc, 0.7f);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}

void ShutDown(MYESContext *myesContext)
{
    myUserData *userData = (myUserData *)myesContext->userData;
    glDeleteTextures(1, &userData->textureId);
    glDeleteProgram(userData->programObject);
}

int myesMain(MYESContext *myesContext)
{
    myesContext->userData = malloc(sizeof(myUserData));
    myesCreateWindow(myesContext, "9_3_texturewrap", 320, 240, MY_ES_WINDOW_RGB);

    if (!Init(myesContext))
    {
        return GL_FALSE;
    }

    esRegisterDrawFunc(myesContext, Draw);
    esRegisterShutdownFunc(myesContext, ShutDown);

    return GL_TRUE;
}

参考

1. 纹理
https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/06%20Textures/

标签:userData,1.0,包装,0.0,0.3,TEXTURE,纹理,坐标,GL
来源: https://www.cnblogs.com/pyjetson/p/14698469.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有