#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);
}
OpenGL 二维纹理映射-3
最新推荐文章于 2022-05-16 20:32:36 发布