计算机图形学(2):OpenGL画球体

参考文章

配置OpenGL环境看上一篇文章

效果图:
在这里插入图片描述

main.cpp:

#include "Dependencies/glew/glew.h"
#include "Dependencies/GLFW/glfw3.h"#include "Dependencies/glm/glm.hpp"
#include "Dependencies/glm/gtc/matrix_transform.hpp"#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>GLint programID;unsigned int VBO, VAO, EBO;const unsigned int SCR_WIDTH = 1200;
const unsigned int SCR_HEIGHT = 1200;const GLfloat  PI = 3.14159265358979323846f;//将球横纵划分成50X50的网格
const int Y_SEGMENTS = 50;
const int X_SEGMENTS = 50;void get_OpenGL_info() {// OpenGL informationconst GLubyte* name = glGetString(GL_VENDOR);const GLubyte* renderer = glGetString(GL_RENDERER);const GLubyte* glversion = glGetString(GL_VERSION);std::cout << "OpenGL company: " << name << std::endl;std::cout << "Renderer name: " << renderer << std::endl;std::cout << "OpenGL version: " << glversion << std::endl;
}bool checkStatus(GLuint objectID,PFNGLGETSHADERIVPROC objectPropertyGetterFunc,PFNGLGETSHADERINFOLOGPROC getInfoLogFunc,GLenum statusType)
{GLint status;objectPropertyGetterFunc(objectID, statusType, &status);if (status != GL_TRUE){GLint infoLogLength;objectPropertyGetterFunc(objectID, GL_INFO_LOG_LENGTH, &infoLogLength);GLchar* buffer = new GLchar[infoLogLength];GLsizei bufferSize;getInfoLogFunc(objectID, infoLogLength, &bufferSize, buffer);std::cout << buffer << std::endl;delete[] buffer;return false;}return true;
}bool checkShaderStatus(GLuint shaderID) {return checkStatus(shaderID, glGetShaderiv, glGetShaderInfoLog, GL_COMPILE_STATUS);
}bool checkProgramStatus(GLuint programID) {return checkStatus(programID, glGetProgramiv, glGetProgramInfoLog, GL_LINK_STATUS);
}std::string readShaderCode(const char* fileName) {std::ifstream meInput(fileName);if (!meInput.good()) {std::cout << "File failed to load ... " << fileName << std::endl;exit(1);}return std::string(std::istreambuf_iterator<char>(meInput),std::istreambuf_iterator<char>());
}void installShaders() {GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);const GLchar* adapter[1];//adapter[0] = vertexShaderCode;std::string temp = readShaderCode("VertexShaderCode.glsl");adapter[0] = temp.c_str();glShaderSource(vertexShaderID, 1, adapter, 0);//adapter[0] = fragmentShaderCode;temp = readShaderCode("FragmentShaderCode.glsl");adapter[0] = temp.c_str();glShaderSource(fragmentShaderID, 1, adapter, 0);glCompileShader(vertexShaderID);glCompileShader(fragmentShaderID);if (!checkShaderStatus(vertexShaderID) || !checkShaderStatus(fragmentShaderID))return;programID = glCreateProgram();glAttachShader(programID, vertexShaderID);glAttachShader(programID, fragmentShaderID);glLinkProgram(programID);if (!checkProgramStatus(programID))return;glDeleteShader(vertexShaderID);glDeleteShader(fragmentShaderID);glUseProgram(programID);}void sendDataToOpenGL() {// TODO:// create 2D objects and 3D objects and/or lines (points) here and bind to VAOs & VBOsstd::vector<float> sphereVertices;std::vector<int> sphereIndices;// 生成球的顶点for (int y = 0; y <= Y_SEGMENTS; y++){for (int x = 0; x <= X_SEGMENTS; x++){float xSegment = (float)x / (float)X_SEGMENTS;float ySegment = (float)y / (float)Y_SEGMENTS;float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);float yPos = std::cos(ySegment * PI);float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);sphereVertices.push_back(xPos);sphereVertices.push_back(yPos);sphereVertices.push_back(zPos);}}// 生成球的Indicesfor (int i = 0; i < Y_SEGMENTS; i++){for (int j = 0; j < X_SEGMENTS; j++){sphereIndices.push_back(i * (X_SEGMENTS + 1) + j);sphereIndices.push_back((i + 1) * (X_SEGMENTS + 1) + j);sphereIndices.push_back((i + 1) * (X_SEGMENTS + 1) + j + 1);sphereIndices.push_back(i * (X_SEGMENTS + 1) + j);sphereIndices.push_back((i + 1) * (X_SEGMENTS + 1) + j + 1);sphereIndices.push_back(i * (X_SEGMENTS + 1) + j + 1);}}glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);	glBindBuffer(GL_ARRAY_BUFFER, VBO);	glBufferData(GL_ARRAY_BUFFER, sphereVertices.size() * sizeof(float), &sphereVertices[0], GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // because the vertex data is tightly packed we can also specify 0 as the vertex attribute's stride to let OpenGL figure it outglEnableVertexAttribArray(0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sphereIndices.size() * sizeof(int), &sphereIndices[0], GL_STATIC_DRAW);}void paintGL(void) {// always run// TODO:// render your objects and control the transformation hereglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glm::mat4 projection = glm::mat4(1.0f);glm::mat4 model = glm::mat4(1.0f);glm::mat4 view = glm::mat4(1.0f);glUniformMatrix4fv(glGetUniformLocation(programID, "projection"), 1, GL_FALSE, &projection[0][0]);glUniformMatrix4fv(glGetUniformLocation(programID, "view"), 1, GL_FALSE, &view[0][0]);glUniformMatrix4fv(glGetUniformLocation(programID, "model"), 1, GL_FALSE, &model[0][0]);glEnable(GL_CULL_FACE);glCullFace(GL_BACK);glBindVertexArray(VAO);//使用线框模式绘制glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glDrawElements(GL_TRIANGLES, X_SEGMENTS * Y_SEGMENTS * 6, GL_UNSIGNED_INT, 0);}void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);
}void initializedGL(void) {// run only once// TODO:sendDataToOpenGL();installShaders();glEnable(GL_DEPTH_TEST);
}int main(int argc, char* argv[]) {GLFWwindow* window;/* Initialize the glfw */if (!glfwInit()) {std::cout << "Failed to initialize GLFW" << std::endl;return -1;}/* glfw: configure; necessary for MAC */glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif/* do not allow resizing */glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);/* Create a windowed mode window and its OpenGL context */window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Assignment 1", NULL, NULL);if (!window) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}/* Make the window's context current */glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);/* Initialize the glew */if (GLEW_OK != glewInit()) {std::cout << "Failed to initialize GLEW" << std::endl;return -1;}get_OpenGL_info();initializedGL();/* Loop until the user closes the window */while (!glfwWindowShouldClose(window)) {/* Render here */paintGL();/* Swap front and back buffers */glfwSwapBuffers(window);/* Poll for and process events */glfwPollEvents();}glfwTerminate();return 0;
}

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;void main()
{gl_Position = vec4(aPos, 1.0);
}

片段着色器:

#version 330 core
out vec4 FragColor;void main()
{FragColor = vec4(1.0,0.635,0.345,1.0);
}

想画的更圆可以通过增大全局变量Y_SEGMENTS和X_SEGMENTS

下面是100时的效果
在这里插入图片描述
要给球体上颜色的话,每次生成顶点时要压入三个颜色的比例值,同时在顶点着色器中加入颜色输入值,下面是修改部分:

for (int y = 0; y <= Y_SEGMENTS; y++){for (int x = 0; x <= X_SEGMENTS; x++){float xSegment = (float)x / (float)X_SEGMENTS;float ySegment = (float)y / (float)Y_SEGMENTS;float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);float yPos = std::cos(ySegment * PI);float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);//压入顶点坐标sphereVertices.push_back(xPos);sphereVertices.push_back(yPos);sphereVertices.push_back(zPos);//压入颜色sphereVertices.push_back(sin(xPos) / 2 + 0.5);sphereVertices.push_back(sin(yPos) / 2 + 0.5);sphereVertices.push_back(sin(zPos) / 2 + 0.5);}}

同时将颜色传入顶点着色器中,注意偏移值要改成6

glBindVertexArray(VAO);	glBindBuffer(GL_ARRAY_BUFFER, VBO);	glBufferData(GL_ARRAY_BUFFER, sphereVertices.size() * sizeof(float), &sphereVertices[0], GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0);//新增两行glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (char*)(3 * sizeof(float))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sphereIndices.size() * sizeof(int), &sphereIndices[0], GL_STATIC_DRAW);

绘线模式去除

glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, X_SEGMENTS * Y_SEGMENTS * 6, GL_UNSIGNED_INT, 0);

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;out vec3 ourColor;void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor ;
}

片段着色器:

#version 330 coreout vec4 FragColor;in vec3 ourColor;void main()
{FragColor = vec4(ourColor,1.0);
}

效果图:
在这里插入图片描述

工程文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/47131.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB | 一起来感受数学之美叭

前两天去观摩了MATHWORKS官方举办的Mathematics is beautiful数学之美投票比赛&#xff0c;见到了很多非常惊艳的作品&#xff0c;在这里分享给大家让大家一同感受大神们的创造力&#xff0c;接下来由我来做全程解说。 虽然看起来代码都写好了&#xff0c;&#xff0c;&#x…

由绘制python蟒蛇实例来整体掌握turtle绘图方法

经典案例&#xff1a;python蟒蛇的绘制 话不多说&#xff0c;直接上代码&#xff0c;先整体感知turtle图形绘制。 print("python蟒蛇的绘制") import turtle as t#引入turtle库函数来实现绘图功能 #并使用import...as...使turtle起个小名为t&#xff0c;使代码简洁 t…

七夕节快到了,教你用MATLAB绘制blingbling的大钻石

1效果 2程序说明 其实非常简单&#xff0c;只需要计算出各个顶点位置&#xff0c;并用fill3绘制一个个面出来即可&#xff0c;为了钻石的色彩更加丰富&#xff0c;我们用light函数设置了光照并为fill3创建出的PATCH对象设置了以下属性。 FaceAlpha 面透明度EdgeAlpha 边透明度…

520还在画玫瑰?教你用MATLAB画个玫瑰花球

效果如下&#xff1a; 原理 玫瑰绘制 要画花球我们要先会绘制一朵花&#xff1a; 如何画一朵花可以看看这篇&#xff1a;MATLAB 3D玫瑰花绘制 三维坐标变化 主要用下面的坐标变化方法&#xff1a; 正十二面体球 想像这里有一个正十二面体球&#xff0c;我们把每一面放上…

Android应用开发-学生信息管理系统

设计目的 1、网上很少有关于SQLite简单综合项目的测试APP。 2、把自己所学的部分UI综合一下&#xff0c;希望能给新手一些帮助。 涉及知识点 1、包括SQLite的增删查找等功能。查找中加入了“模糊搜索”的功能。 2、RecyclerView展示 3、SharedPreference保存密码&#xff0c…

基于Android的班级管理APP的设计与实现

选题背景 在当代大学生的日常学习和生活中&#xff0c;手机已经成为必不可少的工具&#xff0c;这导致大学学习生活中的各种日常生活及学习事务需要通过手机作为媒介进行通知及处理。而目前市场上存在的各种社交软件&#xff08;如QQ、微信等&#xff09;并不是为大学生量身定…

团队博客————学生成绩管理系统

项目简介&#xff1a; 支持实现教师端的登录注册&#xff0c;增添、修改与删除学生信息&#xff0c;增添学生时学号自动生成&#xff1b;将学生成绩导入并按照总分排序&#xff0c;查询成绩并支持模糊匹配&#xff1b;可导出学生成绩到excel表格&#xff1b;可生成以分数段划分…

基于android的学生选课信息app

学生选课系统是一个学校不可缺少的部分&#xff0c;该系统可以快速方便的使学生完成课程的选修及选修课程的管理&#xff0c;让管理员方便的管理选修课和设置选修时间&#xff0c;教师也可以查看自己代的选修课和给学生录入成绩。 本软件是一个Android 客户端JSP Servlet服务端…

安卓学生管理系统

安卓学生管理系统是大三时的期末作业&#xff0c;这里附上github链接&#xff0c;给需要交作业的小朋友~ app截图如下&#xff1a;

Android 学生管理系统

Android学生管理系统 由android mysql实现 1.需求分析 功能需求和页面需求两天没有细想&#xff0c;想到啥功能写啥功能想到啥界面写啥界面 2.系统设计 总体界面结构参照了微信的设计结构&#xff0c;主要功能包括管理员的注册和登录&#xff0c;所有学生信息的查询、单个…

奏响风电数字化“协奏曲”,联想助力世优电气打造智能管理闭环

双碳目标之下&#xff0c;可再生能源行业的快速增长&#xff0c;以及能源电力企业降本增效的需求&#xff0c;使得智能化管理平台成为新能源企业数字化转型的关键选择。 这一点&#xff0c;湖南世优电气股份有限公司&#xff08;以下简称“世优电气”&#xff09;感触颇深。作为…

探访世优科技数字人虚拟直播产品体系 | 世优开放日再次成功举行

2023年5月30日&#xff0c;世优科技全栈技术产品体验活动&#xff08;第二期&#xff09;顺利落下帷幕。此次活动共邀请到30余位各行各业的嘉宾到场&#xff0c;在两个多小时的开放日活动中&#xff0c;世优科技全面展示数字人及虚拟直播领域的技术产品体系。来访嘉宾们全程体验…

斩获5项大奖,世优科技虚拟人驱动技术亮相2022亚洲VRAR博览会

2022第6届以“开放共建创造融合”为主题的亚洲VR&AR博览会于8月12日落下帷幕。在数字经济发展和5G时代的大浪潮下&#xff0c;VR/AR产业链正在迎来加速发展&#xff0c;这从博览会的现场盛况可见一斑&#xff0c;本届展会吸引了众多来自海内外的VR/AR领域专家、学者&#x…

世优科技虚拟数字人直播方案,助力企业品牌破局直播同质化难题

随着互联网的快速发展&#xff0c;短视频带货、直播带货行业呈现出井喷式发展&#xff0c;网络电商直播已经成长为一个巨大的产业。预计2026年&#xff0c;我国网络直播市场规模将超过2万亿元。直播的快速发展越来越深刻地影响人们的消费及生活方式。但火热的同时&#xff0c;也…

元宇宙世界杯来袭,虚拟数字人+虚拟场景开创世界杯观赛全新体验

距离万众期盼的2022卡塔尔世界杯开幕已不足一周&#xff0c;世界杯作为全球最负盛名的体育赛事&#xff0c;不仅是球迷的节日&#xff0c;更是属于全民的狂欢。在开赛之际&#xff0c;中国移动重磅发布世界杯“元宇宙”全新玩法&#xff0c;通过融合“虚拟技术融合创新”全量全…

iDWF互博会即将开幕,世优科技携虚拟人女娲及虚拟直播SaaS平台亮相

助力数字经济发展的新引擎&#xff0c;探索“元宇宙”的新窗口&#xff0c;链接政产学研用金的新平台&#xff0c;全景数字生活的超级体验馆。以“通向数字新世界”为主题&#xff0c;2022互联网技术与应用博览会&#xff08;简称&#xff1a;iDWF互博会&#xff09;即将于2022…

AI数字人产品“世优BOTA”发布会 ,世优科技上海发起人刘凯源演讲回顾

4月20日&#xff0c;世优&#xff08;北京&#xff09;科技有限公司正式发布了新一代AI数字人产品——“世优BOTA”。世优科技上海发起人刘凯源表示&#xff0c;“数字人是元宇宙重要生产力&#xff0c;世优BOTA是人机交互的里程碑式作品”。世优BOTA可以帮助企业快速实现自有数…

2022科大讯飞全球1024开发者节科技共创,AI创新正当时

数字经济已成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。作为数字时代的核心引擎&#xff0c;人工智能正持续推动数万亿数字经济产业转型升级。 引领时代浪潮&#xff0c;科大讯飞全球1024开发者节&#xff0c;以AI开发者为受众群体&#xff0c;汇聚…

虚拟直播降低线上直播成本,虚拟直播如何助力企业抓住新风口?

近年来电商直播的渗透力在不断加强&#xff0c;但是直播形式单一&#xff0c;内容同质化等问题也逐渐显现&#xff0c;很多用户已经对电商直播产生了视觉疲劳。在这样的背景下&#xff0c;无论是平台还是品牌方&#xff0c;都想要寻求新技术、新模式&#xff0c;以实现直播新增…

山西文旅虚拟星推官“青鸟”亮相,世优科技提供虚拟人全栈技术支持

3月21日&#xff0c;由文化和旅游部资源开发司指导&#xff0c;山西省文化和旅游厅与太原市人民政府主办的2023数字文旅品牌创新大会在太原晋阳湖国际会议中心举行。 本次大会以“数字文旅美好生活”为主题&#xff0c;来自全国文旅业界的专家学者齐聚一堂&#xff0c;聚焦数字…