本文主要是介绍跟我一起学OpenGL- load texture,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
上一篇文章已经说明了如何使用texture, 但是颜色还不够真实,我们日常看到的颜色中有很多图片,能不能把这些图片真实的展示出来呢?答案是肯定的,比如一面墙,我们不需要专门去画这堵墙,可以把墙的图片贴上来就可以了。步骤是:
1 读取图片,区分RGBA
2 将图片当成texture去采样
3 draw并显示出来
图片有很多种格式 ,jpg, png, ppm, bmp等,可惜OpenGL并没有提供读取图片的API,这就需要我们自己去做了。常见的开源项目里面有很多可以完成这个操作的,比如SOIL,这里我们就看个简单的读取bmp格式的,以美女图片为例。
读取图片的函数为:
96 void read_bmp()97 {98 GLint pixel_length;99
100 FILE* pfile = fopen("girl.bmp","rw+");
101 if(pfile == 0)
102 printf("File open failed\n");
103
104 fseek(pfile,0x0012,SEEK_SET);
105 fread(&image_width, sizeof(image_width), 1, pfile);
106 fread(&image_height, sizeof(image_height), 1, pfile);
107 printf("---image_width=%d\n", image_width);
108 printf("---image_height=%d\n", image_height);
109
110 pixel_length = image_width * 3;
111 printf("---pixellength=%d\n", pixel_length);
112 while(pixel_length % 4 != 0) pixel_length++;
113
114 pixel_length *= image_height;
115 printf("---pixellength=%d\n", pixel_length);
116
117 pixel_data = (GLubyte*)malloc(pixel_length);
118 if(pixel_data == 0) exit(0);
119
120 fseek(pfile, 54, SEEK_SET);
121 fread(pixel_data, pixel_length, 1, pfile);
122 for (int i = 0 ; i < 1000; i++)
123 {
124 if(pixel_data[i] != 0)
125 printf("---pixel_data=%d\n", pixel_data[i]);
126 }
127 fclose(pfile);
128 }
剩下的部分和上一篇文章差不多,不再赘述。整个程序如下:
1 #include <GL/glew.h>2 #include <GL/freeglut.h>3 #include<stdio.h>4 #include<stdlib.h>5 #include <iostream>6 using namespace std;7 #define BUFFER_OFFSET(x) ((const void*) (x))89 enum VAO_IDs {Triangles, NumVAOs};10 enum Buffer_IDs {ArrayBuffer, NumBuffers};11 enum Attrib_IDs {vPosition = 0};1213 GLuint VAOs[NumVAOs];14 GLuint Buffers[NumBuffers];15 GLuint program;1617 GLushort indices[] = {18 0, 1, 3, /* first triangle */19 1, 2, 3 /* second triangle */20 };2122 GLuint tex;2324 const GLchar* vertex_shader = "#version 300 es \n"25 "layout(location=0) in vec3 vPosition;\n"26 "layout(location=1) in vec2 texCo;\n"27 "out vec2 TexC;\n"28 "void main()\n"29 "{\n"30 "gl_Position = vec4(vPosition, 1.0);\n"31 "TexC = vec2(texCo.x, texCo.y);\n"32 "}\n";3334 const GLchar* fragment_shader = "#version 300 es \n"35 "precision highp float; \n"36 "uniform sampler2D color;\n"37 "layout(location=0)out vec4 fColor;\n"38 "in vec2 TexC;\n"39 "void main()\n"40 "{\n"41 "fColor = texture2D(color, TexC);\n"42 "}\n";4344 void init_shader()45 {46 // vertex shader47 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);48 glShaderSource(vertexShader, 1, &vertex_shader, NULL);49 glCompileShader(vertexShader);50 // check vertex shader compiling status51 GLint compiled;52 GLchar log[256];53 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled);54 if (!compiled)
55 {56 glGetShaderInfoLog(vertexShader, 256, NULL, log);57 std::cerr << "vertex shader compile failed" << log << std::endl;58 }59 60 // fragment shader61 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);62 glShaderSource(fragmentShader, 1, &fragment_shader, NULL);63 glCompileShader(fragmentShader);64 // check fragment shader compiling status65 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled);66 if (!compiled)67 {68 glGetShaderInfoLog(fragmentShader, 256, NULL, log);69 std::cerr << "fragment shader compile failed" << log << std::endl;70 }71 72 // link shaders73 program = glCreateProgram();74 glAttachShader(program, vertexShader);75 glAttachShader(program, fragmentShader);76 glLinkProgram(program);77 78 cout << "prog=" << program << endl;79 //check link status80 GLint linked;81 glGetProgramiv(program, GL_LINK_STATUS, &linked);82 if (!linked)83 {84 glGetProgramInfoLog(program, 256, NULL, log);85 std::cerr << "shader linking failed" << log << std::endl;86 }87 // delete shader88 glDeleteShader(vertexShader);89 glDeleteShader(fragmentShader);90 }91 92 GLint image_width;93 GLint image_height;94 GLubyte* pixel_data;95 96 void read_bmp()97 {98 GLint pixel_length;99
100 FILE* pfile = fopen("girl.bmp","rw+");
101 if(pfile == 0)
102 cout << "File open failed" << endl;
103
104 fseek(pfile,0x0012,SEEK_SET);
105 fread(&image_width, sizeof(image_width), 1, pfile);
106 fread(&image_height, sizeof(image_height), 1, pfile);
107 cout << "---image_width=" << image_width << endl;
108 cout << "---image_height=" << image_height << endl;
109
110 pixel_length = image_width * 3;
111 cout << "---pixel_length=" << pixel_length << endl;
112 while(pixel_length % 4 != 0) pixel_length++;
113
114 pixel_length *= image_height;
115 cout << "---pixel_length=" << pixel_length << endl;
116
117 pixel_data = (GLubyte*)malloc(pixel_length);
118 if(pixel_data == 0) exit(0);
119
120 fseek(pfile, 54, SEEK_SET);
121 fread(pixel_data, pixel_length, 1, pfile);
122 for (int i = 0 ; i < 1000; i++)
123 {
124 if(pixel_data[i] != 0)
125 cout << "---pixel_data=" << (int)pixel_data[i] << endl;
126 }
127 fclose(pfile);
128 }
129
130 void init_data()
131 {
132 glClearColor(0, 0, 0, 0);
133 glClear(GL_COLOR_BUFFER_BIT);
134
135 read_bmp();
136
137 glGenVertexArrays(NumVAOs, VAOs);
138 glBindVertexArray(VAOs[Triangles]);
139
140 const GLfloat vertices[] = {
141 // positions
142 -1.0f, -1.0f, 0.0f, // top right
143 1.0f, -1.0f, 0.0f, // bottom right
144 1.0f, 1.0f, 0.0f, // bottom left
145 -1.0f, 1.0f, 0.0f, // top left
146
147 // texture coords
148 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f
149 };
150
151 glGenBuffers(NumBuffers, Buffers);
152 glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
153 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
154
155 GLuint ebo;
156 glGenBuffers(1, &ebo);
157 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
158 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
159
160 glGenTextures(1, &tex);
161 glBindTexture(GL_TEXTURE_2D, tex);
162
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
165
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
168 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image_width, image_height, 0, GL_BGR, GL_UNSIGNED_BYTE, pixel_data);
169
170 glUseProgram(program);
171
172 GLint texloc = glGetAttribLocation(program, "texCo");
173 cout << "texloc=" << texloc << endl;
174 GLint posloc = glGetAttribLocation(program, "vPosition");
175 cout << "posloc=" << posloc << endl;
176
177 glEnableVertexAttribArray(posloc);
178 glVertexAttribPointer(posloc, 3, GL_FLOAT, GL_FALSE, 0, 0);
179
180 glEnableVertexAttribArray(texloc);
181 glVertexAttribPointer(texloc, 2, GL_FLOAT, GL_FALSE, 0, (void*)(12*sizeof(float)));
182 }
183
184 void display()
185 {
186 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
187 glFlush();
188 }
189
190 int main(int argc, char* argv[])
191 {
192 glutInit(&argc, argv);
193 glutInitDisplayMode(GLUT_RGBA);
194 glutInitWindowSize(300 ,300);
195 glutInitWindowPosition(100, 100);
196 glutCreateWindow("Learn opengl: load texture");
197
198 const char* version = (const char*)glGetString(GL_VERSION);
199 cout << "version=" << version << endl;
200 const char* vendor = (const char*)glGetString(GL_VENDOR);
201 cout << "vendor=" << vendor << endl;
202
203 const char* render = (const char*)glGetString(GL_RENDERER);
204 cout << "render=" << render << endl;
205
206 glewExperimental = GL_TRUE;
207 if(glewInit())
208 {
209 std::cout << "Unable to Initialize" << std::endl;
210 exit(1);
211 }
212 init_shader();
213 init_data();
214 glutDisplayFunc(display);
215 glutMainLoop();
216 }
运行完后,就可以显示出来图片了:
这篇关于跟我一起学OpenGL- load texture的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!