1. 来源:《Computer Graphics Programming in OpenGL Using C++ 》by V Scott
    Gordon John L Clevenger
  2. 内容:程序6.1 Sphere,书P135页,PDF153/403

生成

以下将图片贴图到生成的球体形成效果


完整代码

一共有 8 个文件,名字如下:

  • 220301 6.1 Sphere.cpp
  • 6.1 Shpere.cpp
  • 6.1 Shpere.h
  • 5.2 Utils.cpp
  • 5.2 Utils.h
  • 5.2 vertShader.glsl
  • 5.2 fragShader.glsl
  • brick1.jpg
  • 6.1 earth.jpg

220301 6.1 Sphere.cpp

#include <string>
#include <iostream>
#include <fstream>
#include <cmath>#include "glm\glm.hpp"
#include "glm\gtc\type_ptr.hpp"
#include "glm\gtc\matrix_transform.hpp"
#include "Utils\6.1 Sphere.h"
#include "Utils\5.2 Utils.h"
using namespace std;
#define numVAOs 1
#define numVBOs 3
float cameraX, cameraY, cameraZ;
float pyrLocX, pyrLocY, pyrLocZ;
GLuint renderingProgram;
GLuint vao[numVAOs];
GLuint vbo[numVBOs];
GLuint brickTexture; // 纹理图片ID// allocate variables used in display() function,
// so that they won’t need to be allocated during rendering
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat;Sphere mySphere(48); // 声明一个球的classvoid setupVertices(void) {std::vector<int> ind = mySphere.getIndices(); // 球体点的标注std::vector<glm::vec3> vert = mySphere.getVertices(); // 球上的顶点std::vector<glm::vec2> tex = mySphere.getTexCoords(); // 纹理坐标std::vector<glm::vec3> norm = mySphere.getNormals(); // 球上法向量std::vector<float> pvalues; // vertex positions 顶点位置std::vector<float> tvalues; // texture coordinates 纹理坐标std::vector<float> nvalues; // normal vectors 法向量int numIndices = mySphere.getNumIndices();for (int i = 0; i < numIndices; i++) {     // 把每一个点上的坐标(x,y,z),纹理坐标(s,t),法向量(a,b,c)存储进对应数组pvalues.push_back((vert[ind[i]]).x);pvalues.push_back((vert[ind[i]]).y);pvalues.push_back((vert[ind[i]]).z);tvalues.push_back((tex[ind[i]]).s);tvalues.push_back((tex[ind[i]]).t);nvalues.push_back((norm[ind[i]]).x);nvalues.push_back((norm[ind[i]]).y);nvalues.push_back((norm[ind[i]]).z);}glGenVertexArrays(1, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);// put the vertices into buffer #0  第一个是顶点放入缓存器中glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, pvalues.size() * 4, &pvalues[0], GL_STATIC_DRAW);// put the texture coordinates into buffer #1  第二个是将纹理坐标放入缓存器中glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, tvalues.size() * 4, &tvalues[0], GL_STATIC_DRAW);// put the normals into buffer #2   第三个是将法向量放入缓存器中glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nvalues.size() * 4, &nvalues[0], GL_STATIC_DRAW);
}
void init(GLFWwindow* window) {renderingProgram = createShaderProgram("add/5.2 vertShader.glsl", "add/5.2 fragShader.glsl");cameraX = 0.0f; cameraY = 0.0f; cameraZ = 8.0f;pyrLocX = 1.0f; pyrLocY = -1.0f; pyrLocZ = 0.0f; // shift down Y to reveal perspectivesetupVertices();brickTexture = loadTexture("add/6.1 earth.jpg"); // 加载纹理的图片
}void display(GLFWwindow* window, double currentTime) {glClear(GL_DEPTH_BUFFER_BIT);glUseProgram(renderingProgram);// get the uniform variables for the MV and projection matricesmvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");// build perspective matrixglfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f); // 1.0472 radians = 60 degrees// build view matrix, model matrix, and model-view matrixvMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));// vbo[0]mMat = glm::translate(glm::mat4(1.0f), glm::vec3(pyrLocX, pyrLocY, pyrLocZ));mvMat = vMat * mMat;// copy perspective and MV matrices to corresponding uniform variablesglUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));// associate VBO with the corresponding vertex attribute in the vertex shaderglBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);// 纹理glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, brickTexture);// adjust OpenGL settings and draw modelglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glFrontFace(GL_CCW);// 锥体的三角形是逆时针的面认为是正方向glDrawArrays(GL_TRIANGLES, 0, mySphere.getNumIndices());}int main(void) { // main() is unchanged from beforeif (!glfwInit()) { exit(EXIT_FAILURE); }glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);GLFWwindow* window = glfwCreateWindow(600, 600, "Chapter 6 - program 1", NULL, NULL);glfwMakeContextCurrent(window);if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }glfwSwapInterval(1);init(window);while (!glfwWindowShouldClose(window)) {display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);
}

6.1 Shpere.cpp

#include <cmath>
#include <vector>
#include <iostream>
#include <glm\glm.hpp>
#include "6.1 Sphere.h"
using namespace std;
Sphere::Sphere() {init(48);
}
Sphere::Sphere(int prec) { // prec is precision, or number of slicesinit(prec);
}
float Sphere::toRadians(float degrees) { return (degrees * 2.0f * 3.14159f) / 360.0f; }
void Sphere::init(int prec) {numVertices = (prec + 1) * (prec + 1);numIndices = prec * prec * 6;for (int i = 0; i < numVertices; i++) { vertices.push_back(glm::vec3()); } // std::vector::push_back()for (int i = 0; i < numVertices; i++) { texCoords.push_back(glm::vec2()); } // inserts new element atfor (int i = 0; i < numVertices; i++) { normals.push_back(glm::vec3()); } // the end of a vector andfor (int i = 0; i < numIndices; i++) { indices.push_back(0); } // increases the vector size by 1// calculate triangle verticesfor (int i = 0; i <= prec; i++) {for (int j = 0; j <= prec; j++) {float y = (float)cos(toRadians(180.0f - i * 180.0f / prec));float x = -(float)cos(toRadians(j*360.0f / prec)) * (float)abs(cos(asin(y)));float z = (float)sin(toRadians(j*360.0f / prec)) * (float)abs(cos(asin(y)));vertices[i*(prec + 1) + j] = glm::vec3(x, y, z);texCoords[i*(prec + 1) + j] = glm::vec2(((float)j / prec), ((float)i / prec));normals[i*(prec + 1) + j] = glm::vec3(x, y, z);}}// calculate triangle indicesfor (int i = 0; i < prec; i++) {for (int j = 0; j < prec; j++) {indices[6 * (i*prec + j) + 0] = i * (prec + 1) + j;indices[6 * (i*prec + j) + 1] = i * (prec + 1) + j + 1;indices[6 * (i*prec + j) + 2] = (i + 1)*(prec + 1) + j;indices[6 * (i*prec + j) + 3] = i * (prec + 1) + j + 1;indices[6 * (i*prec + j) + 4] = (i + 1)*(prec + 1) + j + 1;indices[6 * (i*prec + j) + 5] = (i + 1)*(prec + 1) + j;}}
}
// accessors
int Sphere::getNumVertices() { return numVertices; }
int Sphere::getNumIndices() { return numIndices; }
std::vector<int> Sphere::getIndices() { return indices; }
std::vector<glm::vec3> Sphere::getVertices() { return vertices; }
std::vector<glm::vec2> Sphere::getTexCoords() { return texCoords; }
std::vector<glm::vec3> Sphere::getNormals() { return normals; }

6.1 Shpere.h

#pragma once
#include <cmath>
#include <vector>
#include <glm\glm.hpp>
class Sphere
{private:int numVertices;int numIndices;std::vector<int> indices;std::vector<glm::vec3> vertices;std::vector<glm::vec2> texCoords;std::vector<glm::vec3> normals;void init(int);float toRadians(float degrees);
public:Sphere();Sphere(int prec);int getNumVertices();int getNumIndices();std::vector<int> getIndices();std::vector<glm::vec3> getVertices();std::vector<glm::vec2> getTexCoords();std::vector<glm::vec3> getNormals();
};

5.2 Utils.cpp

#include "Utils/5.2 Utils.h"
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "SOIL2/SOIL2.h"#include <iostream>
#include <string>
#include <fstream>
using namespace std;GLuint createShaderProgram(const char* a_Path, const char* b_Path) {GLint vertCompiled;GLint fragCompiled;GLint linked;string vertShaderStr = readShaderSource(a_Path); // 文件在add文件夹中string fragShaderStr = readShaderSource(b_Path);const char *vertShaderSrc = vertShaderStr.c_str();const char *fragShaderSrc = fragShaderStr.c_str();GLuint vShader = glCreateShader(GL_VERTEX_SHADER);GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(vShader, 1, &vertShaderSrc, NULL);glShaderSource(fShader, 1, &fragShaderSrc, NULL);// 在编译着色器时,捕捉错误glCompileShader(vShader);checkOpenGLError();glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);if (vertCompiled != 1) {cout << "vertex compilation failed" << endl;printShaderLog(vShader);}glCompileShader(fShader);checkOpenGLError();glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragCompiled);if (fragCompiled != 1) {cout << "fragment compilation failed" << endl;printShaderLog(fShader);}GLuint vfProgram = glCreateProgram();glAttachShader(vfProgram, vShader);glAttachShader(vfProgram, fShader);glLinkProgram(vfProgram);checkOpenGLError();glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);if (linked != 1) {cout << "linking failed" << endl;printProgramLog(vfProgram);}return vfProgram;
}string readShaderSource(const char *filePath) {string content;ifstream fileStream(filePath, ios::in);string line = "";while (!fileStream.eof()) {getline(fileStream, line);content.append(line + "\n");}fileStream.close();return content;
}
bool checkOpenGLError() {bool foundError = false;int glErr = glGetError();while (glErr != GL_NO_ERROR) {cout << "glError: " << glErr << endl;foundError = true;glErr = glGetError();}return foundError;
}void printProgramLog(int prog) {int len = 0;int chWrittn = 0;char *log;glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);if (len > 0) {log = (char *)malloc(len);glGetProgramInfoLog(prog, len, &chWrittn, log);cout << "Program Info Log: " << log << endl;free(log);}
}
void printShaderLog(GLuint shader) {int len = 0;int chWrittn = 0;char *log;glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);if (len > 0) {log = (char *)malloc(len);glGetShaderInfoLog(shader, len, &chWrittn, log);cout << "Shader Info Log: " << log << endl;free(log);}
}GLuint loadTexture(const char *texImagePath) {GLuint textureID;textureID = SOIL_load_OGL_texture(texImagePath,SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);if (textureID == 0) cout << "could not find texture file" << texImagePath << endl;// mipmapsglBindTexture(GL_TEXTURE_2D, textureID); 不倒置也不镜像——多选一//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 倒置+镜像——多选一//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); 仅有一个,其余颜色为红色——多选一//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);//float redColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f };//glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, redColor);// 仅有一个,其余为图片最边缘一行一列的颜色拓展——多选一glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glGenerateMipmap(GL_TEXTURE_2D);// if also anisotropic filtering if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) {GLfloat anisoSetting = 0.0f;glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisoSetting);//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoSetting);}return textureID;
}

5.2 Utils.h

#pragma once
#ifndef UTILS_H
#define UTILS_H
#include <string>
#include "GL\glew.h"
#include "GLFW\glfw3.h"
using namespace std;GLuint createShaderProgram(const char* a_Path, const char* b_Path);
string readShaderSource(const char *filePath);
bool checkOpenGLError();
void printProgramLog(int prog);
void printShaderLog(GLuint shader);
GLuint loadTexture(const char *texImagePath);#endif // !UTILS_H

5.2 vertShader.glsl

#version 430
layout (location=0) in vec3 pos;
layout (location=1) in vec2 texCoord;
out vec2 tc; // texture coordinate output to rasterizer for interpolation
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout (binding=0) uniform sampler2D samp; // not used in vertex shader
void main(void)
{    gl_Position = proj_matrix * mv_matrix * vec4(pos,1.0);tc = texCoord;
}

5.2 fragShader.glsl

#version 430
in vec2 tc; // interpolated incoming texture coordinate
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout (binding=0) uniform sampler2D samp;
void main(void)
{ color = texture(samp, tc);
}

brick1.jpg

6.1 earth.jpg

C++/OpenGL 入门(16):生成球体并贴纹理图相关推荐

  1. C++/OpenGL 入门(18):读取obj文件并贴图

    来源:<Computer Graphics Programming in OpenGL Using C++ >by V Scott Gordon John L Clevenger 内容:程 ...

  2. OpenGL 入门 17:立方体贴图

    立方体贴图(Cube Map) 立方体贴图是由"上下左右前后"6个2D纹理合并成的一张纹理.与2D纹理使用(u,v)坐标采样不同的是,立方体纹理使用一个方向向量进行采样. 1. 方 ...

  3. 最全面的openGL 入门学习

    自己在找openGL学习资料的时候,找到此篇openGL入门学习(虽然不是移动开发,但给我提供了非常好的思路),所以转一下让更多人知道,本文来自http://www.cppblog.com/doing ...

  4. OpenGL入门学习 (转)

    OpenGL入门学习 (转) 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜 ...

  5. OpenGL入门学习[三]

    OpenGL入门学习[三] http://xiaxveliang.blog.163.com/blog/static/2970803420126246501930/ OpenGL入门学习[十一] 我们在 ...

  6. 【待完善】OpenGL入门学习

    严正声明:本文转载自网络,但具体出处未知.如果有读者了解,请联系我更正. 为了阅读方便,我对文字格式进行了修改,并填补了缺少的图片. 我尊重每位作者的权益,如果本文存在侵权行为,请联系我删除并道歉. ...

  7. 【转载】OpenGL入门学习

    说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...

  8. OpenGL入门教程(转)

    OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...

  9. opengl 入门学习

    转自 http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 说起编程作图,大概还有很多人想起TC的#include <gr ...

最新文章

  1. C/C++中__builtin_popcount()的使用及原理
  2. oralce mysql_Oralce和Mysql的3个区别
  3. Webpack按需加载秒开应用
  4. Java枚举(深刻而不深沉平淡而不平庸)
  5. 引号吃掉了我的数据~~~
  6. 算法心得1:由$nlogn$复杂度的LIS算法引起的思考
  7. python执行Linux系统命令
  8. artcam 9.0英文版本下载_Win10安装paddlepaddle-gpu的python版本
  9. 51单片机 wifi模块代码编写的历程 esp8266
  10. google测试框架
  11. nginx+uWSGI+django+virtualenv+supervisor发布web服务器流程
  12. itsm软件_itsm软件的主要功能
  13. chrome安装crx文件
  14. 采用Pyinstaller将python程序打包成exe可执行程序
  15. 基于 NCNN 的 Chinese-Lite 模型测试
  16. itext Pdf页眉/页脚/水印
  17. 自行车(山地车)拆脚踏
  18. 管理工具导入CSV文件,中文数据乱码的解决办法。
  19. PMC:从小芯片看大世界
  20. 非应届生,无经验怎么找工作?我有点伤心了

热门文章

  1. 商品SKU选择DEMO
  2. VSCode编译C程序
  3. 技术流:纯代码模拟登录耐克官网思路分享
  4. 如何改变黑窗口的颜色?
  5. PBR物理光照计算公式推导详解
  6. Labelme分割标注软件使用
  7. python 去除字符串中的特殊字符
  8. 人月神话读书笔记(一)
  9. 外排序与MapReduce的Sort
  10. 审慎、谨行,B站的自我修养