OpenGL入门第六次实验 纹理映射
鏈接: https://pan.baidu.com/s/1cBTTbbzRCVBCX_H4jf6qMA 提取碼: kj8w
一、實驗原理及要求
參考textureDemo程序,實現太陽、地球和月亮程序中的紋理映射,其中太陽、地球和月亮貼上各自的紋理,同時實現紋理和原來光照效果的混合,即既有光照效果,又有紋理映射效果。
GLFW是一個用于OpenGL應用程序開發的可移植庫。它處理與OpenGL上下文創建、窗口管理、分辨率切換、鍵盤、鼠標、操縱桿和時間輸入以及基本線程設施相關的系統特定任務。
GLEW能自動識別當前平臺所支持的全部OpenGL高級擴展涵數。只要包含glew.h頭文件,就能使用gl,glu,glext,wgl,glx的全部函數。GLEW支持目前流行的各種操作系統
實驗過程中,利用VAO、VBO來存儲直線或者圖案的點集vertices,然后用OpenGL的繪制功能glDrawElements將直線或者圖案繪制出來。
利用Sphere類繪制出三個球體,利用camera類實現視角任意轉移。
二、代碼設計和說明
1、設置紋理映射的各類參數(環繞方式等)
定義了三個紋理變量,texture、texture2、texture3,分別獲取本地的太陽、地球、月亮的紋理。
// 太陽的紋理 unsigned int texture;glGenTextures(1, &texture);glBindTexture(GL_TEXTURE_2D, texture); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object// set the texture wrapping parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// set texture filtering parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.unsigned char *data = stbi_load("sun.jpg", &width, &height, &nrChannels, 0);if (data){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);}else{std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);// 地球的紋理unsigned int texture2;glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object// set the texture wrapping parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// set texture filtering parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// load image, create texture and generate mipmaps//int width, height, nrChannels;// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.unsigned char *data2 = stbi_load("earth.jpg", &width, &height, &nrChannels, 0);if (data2){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data2);glGenerateMipmap(GL_TEXTURE_2D);}else{std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data2);// 月球的紋理unsigned int texture3;glGenTextures(1, &texture3);glBindTexture(GL_TEXTURE_2D, texture3); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object// set the texture wrapping parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// set texture filtering parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// load image, create texture and generate mipmaps//int width, height, nrChannels;// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.unsigned char *data3 = stbi_load("moon.jpg", &width, &height, &nrChannels, 0);if (data){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data3);glGenerateMipmap(GL_TEXTURE_2D);}else{std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data3);2、紋理的綁定
在每個球的glDrawElements操作結束之后,綁定紋理進行繪制,得到三個球體對應的紋理圖像。
3、vertex shader加入紋理坐標屬性
//這是vertex shader#version 330 corelayout (location = 0) in vec3 aPos;layout (location = 1) in vec3 aNormal;layout (location = 2) in vec2 aTexCoord;out vec3 FragPos;out vec3 Normal;out vec2 TexCoord;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){FragPos = vec3(model * vec4(aPos, 1.0));Normal = mat3(transpose(inverse(model))) * aNormal;gl_Position = projection * view * vec4(FragPos, 1.0);TexCoord = vec2(aTexCoord.x, aTexCoord.y);}4、fragment shader修改
//這是fragment shader#version 330 coreout vec4 FragColor;in vec3 Normal;in vec3 FragPos;in vec2 TexCoord;uniform vec3 lightPos;uniform vec3 lightColor;uniform vec3 viewPos;uniform vec3 objectColor;uniform sampler2D texture1;void main() {// ambientfloat ambientStrength = 0.2;vec3 ambient = ambientStrength * lightColor;// diffuse vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);//入射方向float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = diff * lightColor;// specularfloat specularStrength = 0.5;vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), 128);vec3 specular = specularStrength * lightColor * spec;vec3 result = (ambient + diffuse + specular) * objectColor;FragColor = texture(texture1, TexCoord)*vec4(result, 1.0); }三、實驗運行結果(包含用戶輸入和輸出)
光源在相對于中心的右后方
詳細效果可參照錄屏視頻。
總結
以上是生活随笔為你收集整理的OpenGL入门第六次实验 纹理映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新《微专业Android安卓开发工程师
- 下一篇: 修复谷歌拼音输入法已停止运行