跟我一起学OpenGL- load texture

2024-02-17 10:20
文章标签 load opengl 一起 texture

本文主要是介绍跟我一起学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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717471

相关文章

类的load方法和initialize方法对比

1. load方法在main()之前被调用,而initialize方法在main()之后调用 load方法实际是在load_images过程中被调用的。load_images会将当前应用依赖的所有镜像(动态库)加载到内存,在在加载中首先是对镜像进行扫描,将所有包含 load 方法的类加入列表 loadable_classes ,然后从这个列表中逐一调用其所包含的 load 方法。 +[XXCl

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.

OPENGL顶点数组, glDrawArrays,glDrawElements

顶点数组, glDrawArrays,glDrawElements  前两天接触OpenGL ES的时候发现里面没有了熟悉的glBegin(), glEnd(),glVertex3f()函数,取而代之的是glDrawArrays()。有问题问google,终于找到答案:因为OpenGL ES是针对嵌入式设备这些对性能要求比较高的平台,因此把很多影响性能的函数都去掉了,上述的几个函数都被移除了。接

OpenGL ES学习总结:基础知识简介

什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库。 为桌面版本OpenGL 的一个子集。 OpenGL ES管道(Pipeline) OpenGL ES 1.x 的工序是固定的,称为Fix-Function Pipeline,可以想象一个带有很多控制开关的机器,尽管加工

OpenGL雾(fog)

使用fog步骤: 1. enable. glEnable(GL_FOG); // 使用雾气 2. 设置雾气颜色。glFogfv(GL_FOG_COLOR, fogColor); 3. 设置雾气的模式. glFogi(GL_FOG_MODE, GL_EXP); // 还可以选择GL_EXP2或GL_LINEAR 4. 设置雾的密度. glFogf(GL_FOG_DENSITY, 0

opengl纹理操作

我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是只显示几个多边形那样单调了。——但是这还不够。虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求。例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的。OpenGL纹理映射功能支持将

OpenGL ES 2.0渲染管线

http://codingnow.cn/opengles/1504.html Opengl es 2.0实现了可编程的图形管线,比起1.x的固定管线要复杂和灵活很多,由两部分规范组成:Opengl es 2.0 API规范和Opengl es着色语言规范。下图是Opengl es 2.0渲染管线,阴影部分是opengl es 2.0的可编程阶段。   1. 顶点着色器(Vert

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

How can I load the openai api configuration through js in html?

题意:怎样在HTML中通过JavaScript加载OpenAI API配置 问题背景: I am trying to send a request through js in my html so that openai analyzes it and sends a response, but if in the js I put the following: 我正在尝试通过HTM

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.