题目一要求
添加更多顶点到数据中,使用glDrawArrays,
尝试绘制两个彼此相连的三角形:参考解答(需要FQ)
主要代码:
完整代码:
// OpenGLDemo.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
char* readTheFile(string strSource);
const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
const char* fragmentShaderSource = readTheFile("fragmentShaderSource.frag");
class MyTriangle {
public:
float vertices[18] = {
//第一个三角形
.5f,.5f,.0f,//右上
-.5f,.5f,.0f,//左上
.5f,-.5f,.0f,//右下
//第二个三角形
-.5f,-.5f,.0f,//左下
.5f,-.5f,.0f,//右下
-.5f,.5f,.0f//左上
};
//生成顶点缓冲对象 ID:VBO
unsigned int VBO;
//生成顶点数组对象 ID:VAO
unsigned int VAO;
//储存 顶点着色器
unsigned int vertexShader;
//储存 片段着色器
unsigned int fragmentShader;
//存储 着色器程序
unsigned int shaderProgram;
void drawMyGraph(){
vertexShaderInit();
FragmentShaderInit();
shaderProgramLinker();
vertexInput();
}
private:
void vertexInput() {
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
// 1. 绑定VAO , VBO
glBindVertexArray(VAO);
// 2. 复制顶点数组到缓冲中供OpenGL使用
//将缓冲对象 绑定到GL_ARRAY_BUFFER目标
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//定义顶点数据复制到缓冲内存
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
void vertexShaderInit() {
//创建一个顶点着色器对象
vertexShader = glCreateShader(GL_VERTEX_SHADER);
//着色器源码附着到着色器对象上
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
//编译着色器对象
glCompileShader(vertexShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void FragmentShaderInit() {
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void shaderProgramLinker() {
//创建着色器程序对象
shaderProgram = glCreateProgram();
//附加着色器到着色器程序
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
int success;
char infoLog[22];
glGetProgramiv(shaderProgram, GL_LINK_STATUS,&success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
};
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create the windows" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
MyTriangle myTriangle;
myTriangle.drawMyGraph();
//启用线段模式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while (!glfwWindowShouldClose(window)) {
//输入处理
processInput(window);
//渲染指令
glClearColor(0.2f,0.3f,0.3f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 4. 当我们渲染一个物体时要使用着色器程序
glUseProgram(myTriangle.shaderProgram);
glBindVertexArray(myTriangle.VAO);
// 3. 绘制物体
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &myTriangle.VAO);
glDeleteBuffers(1, &myTriangle.VBO);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
//.frag .vert文件读取
char* readTheFile(string strSource) {
std::ifstream myfile(strSource);
std::string str((std::istreambuf_iterator<char>(myfile)),
std::istreambuf_iterator<char>());
//str数组长度一定要 +1,
/*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
int len = str.length();
char* result = new char[len];
strcpy_s(result, len + 1, str.c_str());
return result;
}
题目二要求
创建相同的两个三角形,
但对它们的数据使用不同的VAO和VBO:参考解答
(需要FQ)
主要代码:
// OpenGLDemo.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
char* readTheFile(string strSource);
const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
const char* fragmentShaderSource = readTheFile("fragmentShaderSource.frag");
class MyTriangle {
public:
float verticesFirst[9] = {
//第一个三角形
.5f,.5f,.0f,//右上
-.5f,.5f,.0f,//左上
.5f,-.5f,.0f,//右下
};
float verticesSecond[9] = {
//第二个三角形
-.5f,-.5f,.0f,//左下
-.5f,.5f,.0f,//左上
.5f,-.5f,.0f,//右下
};
//生成顶点缓冲对象 ID:VBO
unsigned int VBOs[2];
//生成顶点数组对象 ID:VAO
unsigned int VAOs[2];
//储存 顶点着色器
unsigned int vertexShader;
//储存 片段着色器
unsigned int fragmentShader;
//存储 着色器程序
unsigned int shaderProgram;
void drawMyGraph(){
vertexShaderInit();
FragmentShaderInit();
shaderProgramLinker();
vertexInput();
}
private:
void vertexInput() {
glGenBuffers(2, VBOs);
glGenVertexArrays(2, VAOs);
// 1. 绑定VAO , VBO
glBindVertexArray(VAOs[0]);
// 2. 复制顶点数组到缓冲中供OpenGL使用
//将缓冲对象 绑定到GL_ARRAY_BUFFER目标
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
//定义顶点数据复制到缓冲内存
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFirst), verticesFirst, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesSecond),
verticesSecond, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
void vertexShaderInit() {
//创建一个顶点着色器对象
vertexShader = glCreateShader(GL_VERTEX_SHADER);
//着色器源码附着到着色器对象上
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
//编译着色器对象
glCompileShader(vertexShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void FragmentShaderInit() {
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void shaderProgramLinker() {
//创建着色器程序对象
shaderProgram = glCreateProgram();
//附加着色器到着色器程序
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
int success;
char infoLog[22];
glGetProgramiv(shaderProgram, GL_LINK_STATUS,&success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
};
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create the windows" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
MyTriangle myTriangle;
myTriangle.drawMyGraph();
//启用线段模式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while (!glfwWindowShouldClose(window)) {
//输入处理
processInput(window);
//渲染指令
glClearColor(0.2f,0.3f,0.3f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 4. 当我们渲染一个物体时要使用着色器程序
glUseProgram(myTriangle.shaderProgram);
glBindVertexArray(myTriangle.VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(myTriangle.VAOs[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(2, myTriangle.VAOs);
glDeleteBuffers(2, myTriangle.VBOs);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
//.frag .vert文件读取
char* readTheFile(string strSource) {
std::ifstream myfile(strSource);
std::string str((std::istreambuf_iterator<char>(myfile)),
std::istreambuf_iterator<char>());
//str数组长度一定要 +1,
/*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
int len = str.length();
char* result = new char[len];
strcpy_s(result, len + 1, str.c_str());
return result;
}
题目三:
创建两个着色器程序,第二个程序使用一个不同的片段着色器,输出黄色;
再次绘制这两个三角形,让其中一个输出为黄色:参考解答
// OpenGLDemo.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
char* readTheFile(string strSource);
const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
const char* fragmentShaderSource[2] = {
readTheFile("fragmentShaderSource.frag"),
readTheFile("fragmentShaderSource2.frag")
};
class MyTriangle {
public:
float verticesFirst[9] = {
//第一个三角形
.5f,.5f,.0f,//右上
-.5f,.5f,.0f,//左上
.5f,-.5f,.0f,//右下
};
float verticesSecond[9] = {
//第二个三角形
-.5f,-.5f,.0f,//左下
-.5f,.5f,.0f,//左上
.5f,-.5f,.0f,//右下
};
//生成顶点缓冲对象 ID:VBO
unsigned int VBOs[2];
//生成顶点数组对象 ID:VAO
unsigned int VAOs[2];
//储存 顶点着色器
unsigned int vertexShader;
//储存 片段着色器
unsigned int fragmentShader[2];
//存储 着色器程序
unsigned int shaderProgram[2];
void drawMyGraph(){
vertexShaderInit();
FragmentShaderInit();
shaderProgramLinker();
vertexInput();
}
private:
void vertexInput() {
glGenBuffers(2, VBOs);
glGenVertexArrays(2, VAOs);
// 1. 绑定VAO , VBO
glBindVertexArray(VAOs[0]);
// 2. 复制顶点数组到缓冲中供OpenGL使用
//将缓冲对象 绑定到GL_ARRAY_BUFFER目标
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
//定义顶点数据复制到缓冲内存
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFirst), verticesFirst, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesSecond),
verticesSecond, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
void vertexShaderInit() {
//创建一个顶点着色器对象
vertexShader = glCreateShader(GL_VERTEX_SHADER);
//着色器源码附着到着色器对象上
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
//编译着色器对象
glCompileShader(vertexShader);
//检测着色编译是否成功
int success;
char infoLog[22];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void FragmentShaderInit() {
int success;
char infoLog[22];
int len = sizeof(fragmentShader) / sizeof(unsigned int);
for (int i = 0; i < len;i++) {
fragmentShader[i] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[i], 1, &fragmentShaderSource[i], NULL);
glCompileShader(fragmentShader[i]);
glGetShaderiv(fragmentShader[i], GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader[i], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
}
void shaderProgramLinker() {
int len = sizeof(shaderProgram) / sizeof(unsigned int);
for (int i = 0;i < len;i++) {
//创建着色器程序对象
shaderProgram[i] = glCreateProgram();
//附加着色器到着色器程序
glAttachShader(shaderProgram[i], vertexShader);
glAttachShader(shaderProgram[i], fragmentShader[i]);
glLinkProgram(shaderProgram[i]);
int success;
char infoLog[22];
glGetProgramiv(shaderProgram[i], GL_LINK_STATUS,&success);
if (!success) {
glGetProgramInfoLog(shaderProgram[i], 512, NULL, infoLog);
std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader[i]);
}
}
};
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create the windows" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
MyTriangle myTriangle;
myTriangle.drawMyGraph();
while (!glfwWindowShouldClose(window)) {
//输入处理
processInput(window);
//渲染指令
glClearColor(0.2f,0.3f,0.3f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 4. 当我们渲染一个物体时要使用着色器程序
glUseProgram(myTriangle.shaderProgram[0]);
glBindVertexArray(myTriangle.VAOs[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(myTriangle.shaderProgram[1]);
glBindVertexArray(myTriangle.VAOs[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(2, myTriangle.VAOs);
glDeleteBuffers(2, myTriangle.VBOs);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
//.frag .vert文件读取
char* readTheFile(string strSource) {
std::ifstream myfile(strSource);
std::string str((std::istreambuf_iterator<char>(myfile)),
std::istreambuf_iterator<char>());
//str数组长度一定要 +1,
/*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
int len = str.length();
char* result = new char[len];
strcpy_s(result, len + 1, str.c_str());
return result;
}