openGL系列文章目录

前言

某些类型的对象(例如球体、圆锥体等)具有数学定义,这些定义有助于算法生成。例
如,对于半径为R 的圆,围绕其圆周的点的坐标可以被很好地定义

图1

我们可以系统地使用圆的几何知识来通过算法建立球体模型。我们的策略如下。
(1)在整个球体上,选择表示一系列圆形“水平切片”的精度。见图2 的左侧。
(2)将每个圆形切片的圆周细分为若干个点。见图6.2 的右侧。更多的点和水平切片可
以生成更精确、更平滑的球体模型。在我们的模型中,每个切片将具有相同数量的点。
(3)将顶点分组为三角形。一种方法是逐步遍历顶点,在每一步构建两个三角形。例如,
当我们沿着图6.3 中球体上5 个彩色顶点这一行移动时,对于这5 个顶点中的每一个,我们构建了以相应颜色显示的两个三角形

一、代码

#include "glew/glew.h"
#include "glfw/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Sphere.h"
#include "Utils.h"
#include <iostream>
#include <fstream>
#include <string>using namespace std;static const int screen_width = 1920;
static const int screen_height = 1080;int width = 0, height = 0;
float aspect = 0.f;
float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float sphereLocX = 0.f, spherelocY = 0.f, sphereLocZ = 0.f;GLuint renderingProgram = 0;
static const int numberVAOs = 1;
static const int numberVBOs = 3;
GLuint vao[numberVAOs] = { 0 };
GLuint vbo[numberVBOs] = { 0 };glm::mat4 mMat(1.f), vMat(1.f), mvMat(1.f), pMat(1.f);
int mvLoc = 0;
int projLoc = 0;
float rotAmt = 0.f;GLuint earthTextureId = 0;Sphere earth = Sphere(48);void setupVertices()
{vector<int> ind = earth.getIndices();vector<glm::vec3> vert = earth.getVertices();vector<glm::vec2> tex = earth.getTexCoords();vector<glm::vec3> norm = earth.getNormals();vector<glm::vec3> tang = earth.getTangents();vector<float> pValues;vector<float> tValues;vector<float> nValues;int numIndices = earth.getNumIndices();for (int i=0; i<numIndices; i++){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(numberVAOs, vao);glBindVertexArray(vao[0]);glGenBuffers(numberVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, pValues.size() * 4, &pValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * 4, &tValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nValues.size() * 4, &nValues[0], GL_STATIC_DRAW);
}void init(GLFWwindow* window)
{renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");cameraX = 0.f, cameraY = 0.f, cameraZ = 6.f;sphereLocX = 0.f, spherelocY = 0.f, sphereLocZ = 0.f;glfwGetFramebufferSize(window, &width, &height);//屏幕坐标和窗口的帧缓冲/*GLFW在这里和这里解释文档中的两个坐标系。简而言之,窗口坐标是相对于监视器和 / 或窗口的,并且以不一定对应于真实屏幕像素的人造单元给出。 当DPI缩放被激活时(例如,在带有视网膜显示器的Mac上),情况尤其如此。与窗口坐标相比,帧缓冲区的大小与像素相关,以便与glViewport OpenGLs要求相匹配。请注意,在某些系统上,窗口坐标和像素坐标可以相同,但这不一定是正确的。*/aspect = (float)width / (float)height;pMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);setupVertices();earthTextureId = Utils::loadTexture("resource/earth.jpg");
}void display(GLFWwindow* window, float currentTime)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.1f, 0.2f, 1.f, 1.f);//必不可少!!!否则窗口是黑的,不会渲染任何东西glUseProgram(renderingProgram);mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");//移动相机矩阵:这里必须是-cameraZ,否则相机看不到球体vMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, -cameraZ));mMat = glm::translate(glm::mat4(1.f), glm::vec3(sphereLocX, spherelocY, sphereLocZ));mMat = glm::rotate(glm::mat4(1.f), currentTime * 0.5f, glm::vec3(0.f, 1.f, 0.f));//右乘规则//mvMat = mMat * vMat;   //金字塔会离开视口mvMat = vMat * mMat;//更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回// 将透视矩阵和MV 矩阵复制给相应的统一变量/*通过一致变量(uniform修饰的变量)引用将一致变量值传入渲染管线。location : uniform的位置。count : 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。transpose : 指明矩阵是列优先(column major)矩阵(GL_FALSE)还是行优先(row major)矩阵(GL_TRUE)。value : 指向由count个元素的数组的指针。*/glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));//绑定到球体顶点缓冲区glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);//指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置/*Parametersindex指定要修改的顶点属性的索引值size指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(梦维:如position是由3个(x, y, z)组成,而颜色是4个(r, g, b, a))type指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。normalized指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。stride指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。pointer指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0。*/glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);//启用或禁用通用顶点属性数组,参数0索引和着色器中的layout(location = 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, earthTextureId);//背面剔除,默认情况下,背面剔除是关闭的glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);glDrawArrays(GL_TRIANGLES, 0, earth.getNumIndices());//glDrawArrays(GL_TRIANGLES, 0, earth.getNumVertices());
}void window_size_callback(GLFWwindow* window, int newWidth, int newHeight)
{glViewport(0, 0, newWidth, newHeight);aspect = (float)newWidth / (float)newHeight;pMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);
}int main(int argc, char** argv)
{int glfwState = glfwInit();if (GLFW_FALSE == glfwState){cout << "GLFW initialize failed,invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);GLFWwindow* window = glfwCreateWindow(screen_width, screen_height, "Sphere Draw", nullptr, nullptr);if (!window){cout << "GLFW create window failed,invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwMakeContextCurrent(window);glfwSetWindowSizeCallback(window, window_size_callback);glfwSwapInterval(1);int glewState = glewInit();if (GLEW_OK != glewState){cout << "GLEW initialize failed,invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}init(window);while (!glfwWindowShouldClose(window)){display(window, (float)glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);return 0;
}

顶点着色器

#version 460 corelayout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoords;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;//uniform sampler2D samp;
layout (binding = 0) uniform sampler2D samp;//out vec4 color;
out vec2 tc;void main()
{gl_Position = proj_matrix * mv_matrix * vec4(position, 1.f);tc = texCoords;
}

片元着色器

#version 460 corein vec2 tc;
out vec4 color;uniform mat4 mv_matrix;
uniform mat4 proj_matrix;layout(binding = 0) uniform sampler2D samp;void main()
{color = texture(samp, tc);
}

二、运行效果

源码下载

源码工程下载

openGL绘制地球相关推荐

  1. openGL绘制带纹理地球,并实现鼠标键盘控制

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.绘制球体 二.关键代码 球体类(Sphere) 主函数 顶点着色器 片元着色器 显示效果 源码下载 参考 前言 openGL绘制 ...

  2. openGL绘制带纹理太阳、地球、月亮,并且地球自转并且围绕太阳旋转。月亮自转也会围绕地球旋转

    openGL系列文章目录 前言 使用openGL绘制太阳.地球.月亮,太阳自转,地球自转并且围绕太阳旋转.月亮自转也会围绕地球旋转,其实月亮也会围绕太阳旋转的. 一.效果 还是有不满意的地方: 1.没 ...

  3. OpenGL绘制地球仪(包含环境配置)

    OpenGL绘制地球仪 文章目录 OpenGL绘制地球仪 环境配置 glut配置 glaux环境配置 源码 Main.cpp MyTexMgr.h MyTexMgr.cpp 资料下载 环境配置 使用软 ...

  4. OpenGL绘制地月天体,基于Qt框架。

    使用Qt5.8,OpenGL4.3,glm0.9.6.3,绘制地球(带纹理).月球(带纹理).云层(使用混合方式绘制在地球外层)等物体,并且有光照.白天与黑夜过渡效果(利用多重和过程纹理).天体的自转 ...

  5. 如何用 OpenGL 绘制雪花?

    作者 | 许向武 责编 | 张红月 出品 | CSDN博客 看冬奥才知道,阿勒泰不但是中国的"雪都",还是"人类滑雪起源地".这个说法是否成立,姑且不论,阿勒泰 ...

  6. 使用OpenGL绘制圆环体(Torus)

    本篇介绍一下使用OpenGL绘制圆环体的方法.程序是在C#和OpenTK环境下编译的. 代码: /// <summary> /// 绘制圆环体 /// </summary> / ...

  7. 【OpenGL】十三、OpenGL 绘制三角形 ( 绘制单个三角形 | 三角形绘制顺序 | 绘制多个三角形 )

    文章目录 一.绘制三角形 二.三角形绘制顺序 1.绘制正面 2.三个点逆时针方向排列 3.三个点顺时针方向排列 4.设置点的正面方向 三.绘制多个三角形 四.相关资源 一.绘制三角形 三角形绘制即绘制 ...

  8. 【OpenGL】十一、OpenGL 绘制多个点 ( 绘制单个点 | 绘制多个点 )

    文章目录 一.绘制单个点 二.绘制多个点 三.相关资源 在上一篇博客 [OpenGL]十.OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | ...

  9. 【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )

    文章目录 一.初始化 OpenGL 矩阵 1.设置投影矩阵 2.设置模型视图矩阵 二.绘制点 1.清除缓冲区 2.设置当前颜色值 3.设置绘制点的大小 4.绘制点 5.将缓冲区绘制到前台 三.部分代码 ...

  10. 【OpenGL】九、OpenGL 绘制基础 ( OpenGL 状态机概念 | OpenGL 矩阵概念 )

    文章目录 一.OpenGL 状态机概念 二.OpenGL 矩阵概念 上一篇博客 [OpenGL]八.初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗 ...

最新文章

  1. 苹果 2020 iPhone 展望:相机大升级,5G 首次接入
  2. 保存图像_设计干货知识:SVG vs PNG vs JPG|图像格式的优缺点
  3. 计时器Chronometer和时钟(AnalogClock和DigitalClock)
  4. Go语言初探gRPC服务
  5. 5个常见的Hibernate异常及其解决方法
  6. fresco使用中圆角出现了黑边
  7. android signalr 自动重连,.net-何时在signalR中重新连接?
  8. Opencv环境配置
  9. EVO自动处理SLAM数据脚本
  10. 计算机视觉——SIFT图像匹配算法
  11. stata陈强:计量经济学及stata应用_陈强 第四章 一元线性回归
  12. FLV方式实现网页FFmpeg推流无插件播放
  13. python 读excel字符型 数值_浅谈python 读excel数值为浮点型的问题
  14. c语言游戏菜单栏界面设计,俄罗斯方块——菜单和游戏界面.cpp
  15. 【2022年9月】237条微信内置浏览器UA
  16. algorithm的使用
  17. Textarea输入框失去焦点时隐藏手机键盘
  18. Windows10 蓝屏 DRIVER_IRQL_NOT_LESS_OR_EQUAL (vfilter.sys)的可能解决方法
  19. 药业借CRM 提升企业营销管理能力
  20. 仙剑人物MMD制作详细教程,包含模型提取和3DMAX简单操作

热门文章

  1. 如何使用MEGA软件构建系统发育树_速成实用经验
  2. python | prophet的案例实践:趋势检验、突变点检验等
  3. 广州大学锐捷认证协议安全性研究
  4. Keras:我的第一个神经网络二分类模型
  5. SQLMAP命令详解
  6. 威纶通定时循环操作宏_「精品详解」威纶通触摸屏宏指令应用(三)
  7. 机床数据采集之凯恩帝(KND)机床 IP地址设置
  8. odoo stock库存模块
  9. 【2020年高被引学者】 车万翔 哈尔滨工业大学
  10. matlab log算子求取,数字图像处理---LOG算子和CANNY算子边缘提取(matlab)