[OpenGL]纹理贴图实现总结

  • 格式:pdf
  • 大小:94.55 KB
  • 文档页数:4

[OpenGL]纹理贴图实现总结

实现步骤

第⼀步:设置所需要的OpenGL环境

设置上下⽂环境

删除已经存在的渲染的缓存

设置颜⾊缓存

设置帧缓存

清除缓存

设置窗⼝⼤⼩

开启功能

编译shander

使⽤program

获取shader中的属性和uniform索引

第⼆步:绘制图⽚

获取图⽚数据并且的到对应的纹理id

指定纹理,绑定纹理

开始对图形进⾏渲染

(

启⽤顶点属性数组纹理坐标,将纹理坐标传递到shader中

启⽤顶点属性数组顶点坐标,将顶点坐标传递到shader中

启⽤索引数组

开始绘制

)

解绑纹理

实现

这次实现的过程有些艰难啊,⾛了很多的弯路,不过也因此学到蛮多的,⾃⼰写的怎么都运⾏不了,但是在别⼈的基础上运⾏就不⾏,其中

错误的地⽅有:1.纹理的数据错误,使⽤png的库失败;2.绘制函数的参数错误;3.使⽤新版本的glsl语⾔版本,但是xcode并不⽀持,并不熟

悉期间的语⾔版本迭代;

实现代码:

主程序

#include "SOIL.h"

static void error_callback(int error, const char* description)

{

fprintf(stderr, "Error: %s\n", description);

}

int main(void)

{

GLFWwindow* window;

glfwSetErrorCallback(error_callback);

if (!glfwInit())

exit(EXIT_FAILURE);

window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);

if (!window)

{

std::cout << "Failed to create GLFW window" << std::endl;

glfwTerminate();

exit(EXIT_FAILURE);

}

glfwMakeContextCurrent(window);

glewExperimental = GL_TRUE;

glewInit();

glfwSwapInterval(1);

glViewport(0, 0, 640, 480);

bool ret = getImageData("/Users/staff/Desktop/Moni/Moni/wall.png");

if (!ret) {

cout << "get iamge data is failed." << endl; }

else {

cout << "get iamge data is success." << endl;

//测试图⽚数据

// FILE * file;

// file = fopen("/Users/staff/Desktop/abc.png","wb");

// if (file)

// {

// fwrite(_sp_image_data.getBytes(),1,_sp_image_data.getSize(), file);

// }

// fclose(file);

}

// 第⼀⾏和第三⾏不是严格必须的,默认使⽤GL_TEXTURE0作为当前激活的纹理单元

/**

* GL_TEXTURE_2D表⽰操作2D纹理

* 创建纹理对象,

* 绑定纹理对象,

*/

glPixelStorei(GL_UNPACK_ALIGNMENT, 8);

glGenTextures(1, &_sp_textureID);

glBindTexture(GL_TEXTURE_2D, _sp_textureID);

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );

// glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

/**

* 将图像数据传递给到GL_TEXTURE_2D中, 因其于textureID纹理对象已经绑定,所以即传递给了textureID纹理对象中。

* glTexImage2d会将图像数据从CPU内存通过PCIE上传到GPU内存。

* 不使⽤PBO时它是⼀个阻塞CPU的函数,数据量⼤会卡

*/

// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _sp_image_size.getX(), _sp_image_size.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, _sp_image_data.getBytes());

// glGenerateMipmap(GL_TEXTURE_2D);

int width, height;

unsigned char* image = SOIL_load_image("/Users/staff/Desktop/fgh/fgh/wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

glGenerateMipmap(GL_TEXTURE_2D);

SOIL_free_image_data(image);

glBindTexture(GL_TEXTURE_2D, 0);

_vertexShader = glCreateShader(GL_VERTEX_SHADER);

glShaderSource(_vertexShader, 1, &CCPositionTextureColorVert, NULL);

glCompileShader(_vertexShader);

GLint status;

glGetShaderiv(_vertexShader, GL_COMPILE_STATUS, &status);

if (!status) {

GLint infoLen = 0;

glGetShaderiv(_vertexShader, GL_INFO_LOG_LENGTH, &infoLen);

if (infoLen) {

char* infoLog = static_cast(malloc(sizeof(char) * infoLen));

glGetShaderInfoLog(_vertexShader, infoLen, NULL, infoLog);

cout << "compile vert shader wrong..." << infoLog << endl;

}

}

else {

cout << "compile vert shader success..." << endl;

}

_fragShader = glCreateShader(GL_FRAGMENT_SHADER);

glShaderSource(_fragShader, 1, &CCPositionTextureColorFrag, NULL);

glCompileShader(_fragShader);

glGetShaderiv(_fragShader, GL_COMPILE_STATUS, &status);

if (!status) {

GLint infoLen = 0;

glGetShaderiv(_fragShader, GL_INFO_LOG_LENGTH, &infoLen);

if (infoLen) {

char* infoLog = static_cast(malloc(sizeof(char) * infoLen));

glGetShaderInfoLog(_fragShader, infoLen, NULL, infoLog);

cout << "compile frag shader wrong..." << infoLog << endl;

}

}

else {

cout << "compile vert frag success..." << endl;

}

_program = glCreateProgram(); glAttachShader(_program, _vertexShader);

glAttachShader(_program, _fragShader);

glLinkProgram(_program);

glGetProgramiv(_program, GL_LINK_STATUS, &status);

if (status == GL_FALSE) {

GLint infoLen = 0;

glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLen);

if (infoLen) {

char* infoLog = static_cast(malloc(sizeof(char) * infoLen));

glGetProgramInfoLog(_program, infoLen, NULL, infoLog);

cout << "link program wrong..." << infoLog << endl;

}

}

else {

cout << "the program link success." << endl;

}

//设置顶点数据(和缓冲)和属性指针

GLfloat vertices[] = {

// Positions // Colors // Texture Coords

0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 0.1f,

0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.8f,

-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.8f,

-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.1f

};

GLuint indices[] = {

0, 1, 3,

1, 2, 3

};

GLuint VBO, VAO, EBO;

glGenVertexArrays(1, &VAO);

glGenBuffers(1, &VBO);

glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);