OpenGL 二维纹理映射-3

#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GLUT/GLUT.h>
#include <png.h>

using namespace std;

unsigned int img = -1;
GLuint vShader,fShader;//顶点着色器对象
GLuint programHandle = -1;
GLuint VBO, VAO, EBO;

GLuint loadPNGTexture(const char *filename)
{
   //gl_texture_t在“Xcode加入libpng库”这篇文章里定义
    gl_texture_t *png_tex = NULL;
    GLuint tex_id = 0;
    GLint alignment;

    //ReadPNGFromFile函数在“Xcode加入libpng库”这篇文章里定义
    png_tex = ReadPNGFromFile(filename);
    if (png_tex && png_tex->texels)
    {
        /* Generate texture */
        glGenTextures(1, &png_tex->id);
        glBindTexture(GL_TEXTURE_2D, png_tex->id);
        //当使用纹理坐标映射到纹理时,例如(0.5,1.0)对应纹理(128,256)的情况是比较少的,更多的时候是比如(152.34,745.14),这时该怎么选择像素呢。
        //此处使用的是GL_LINEAR,坐标中心点附近的2x2像素进行加权计算从而选择一个像素。
        //另外一个问题是,纹理应用到物体上,最终要绘制在显示设备上,这里存在一个纹理像素到屏幕像素的转换问题,有三个情况
        //1.一个纹素最终对应屏幕上的多个像素 这称之为放大(GL_TEXTURE_MAG_FILTER)
        //2.一个纹素对应屏幕上的一个像素 这种情况不需要滤波方法
        //3.一个纹素对应少于一个像素,或者说多个纹素对应屏幕上的一个像素 这个称之为缩小(GL_TEXTURE_MIN_FILTER)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        //如果纹理坐标超出了[0,0]到[1,1]的范围,这时就使用GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T来处理
        //GL_REPEAT 坐标的整数部分被忽略,重复纹理,这是OpenGL纹理默认的处理方式.
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        //函数glTexEnvf是设置像素界别的,从字面意思上是设置贴图纹理的函数,但是实际上该函数是像素级别的,所以能够影响混合等其他像素级别的操作。
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        
        //GL_UNPACK_ALIGNMENT,获取字节对齐方式
        glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexImage2D(GL_TEXTURE_2D, 0, png_tex->internalFormat, png_tex->width, png_tex->height, 0, png_tex->format, GL_UNSIGNED_BYTE, png_tex->texels);
        //还原字节对齐方式
        glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
        tex_id = png_tex->id;
        /* OpenGL has its own copy of texture data */
        free(png_tex->texels);
        free(png_tex);
    }
    return tex_id;
}

void initVBO()
{
    GLfloat vertices[] = {
        // Positions          // Colors           // Texture Coords
        -0.5f, -0.5f, 0.0f,   1.0f, 1.0f, 1.0f,   0.0f, 0.0f,
        0.5f, -0.5f, 0.0f,    1.0f, 1.0f, 1.0f,   1.0f, 0.0f,
        0.5f,  0.5f, 0.0f,    1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 1.0f,   0.0f, 1.0f
    };
    
    GLuint indices[] = {
        0, 1, 3,
        1, 2, 3
    };
    
    glGenVertexArraysAPPLE(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    
    glBindVertexArrayAPPLE(VAO);
    
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    GLuint _positionSlot = glGetAttribLocation(programHandle, "position");
    GLuint _colorSlot = glGetAttribLocation(programHandle, "color");
    GLuint _textureCoordsSlot = glGetAttribLocation(programHandle, "texCoord");
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(_positionSlot);
    
    glVertexAttribPointer(_colorSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(_colorSlot);
    
    glVertexAttribPointer(_textureCoordsSlot, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
    glEnableVertexAttribArray(_textureCoordsSlot);
    
    glBindVertexArrayAPPLE(0);
}

void init()
{
    GLenum err = glewInit();
    if( GLEW_OK != err )
    {
        cout <<"Error initializing GLEW: " << glewGetErrorString(err) << endl;
    }
   //initShader函数和“VAO和VBO画三角形”这篇文章里的函数一样
    initShader("/Users/jlb/Documents/OpenGLTest/OpenGLTest/triangles.vert",
               "/Users/jlb/Documents/OpenGLTest/OpenGLTest/triangles.frag");

    img = loadPNGTexture("/Users/jlb/Documents/OpenGLTest/OpenGLTest/falling_chip.png");
    
    initVBO();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    
   //开启混合,否则PNG图片的透明效果无法实现
    glEnable (GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, img);
    glUniform1i(glGetUniformLocation(programHandle, "ourTexture1"), 0);
    glBindVertexArrayAPPLE(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArrayAPPLE(0);
    
    glutSwapBuffers();
}

void changeSize(GLsizei w, GLsizei h)
{
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(600,600);
    glutInitWindowPosition(100,100);
    glutCreateWindow("GLSL Test : Draw a triangle");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(changeSize);
    
    glutMainLoop();
    return 0;
}


triangles.vert
attribute vec3 position;
attribute vec3 color;
attribute vec2 texCoord;

varying vec3 ourColor;
varying vec2 TexCoord;

void main() {
    gl_Position = vec4(position, 1.0);
    ourColor = color;
    TexCoord = texCoord;
}

triangles.frag
varying vec3 ourColor;
varying vec2 TexCoord;

//varying vec4 color;

uniform sampler2D ourTexture1;

void main() {
    gl_FragColor = texture2D(ourTexture1, TexCoord) * vec4(ourColor, 1.0);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值