环境的配置
因为要使用到这两个库所以说我们要把这两个库连接到工程中。
1.glew glfw(32bit)下载
2.新建c++桌面开发 空白
3.新增项目
4.配置设置(项目/属性)
(1)先调成所有配置
(2)依次点击 c/c++常规/附加所包含目录 在里边添加 下好的glew glfw 里include文件
(3)依次点击 连接器 常规 附加到库目录
(4)连接器 输入附加到依赖项
5.在代码中输入头文件
#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
渲染出一个简单的四边形
#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include"Shader.h"
///通过ESC退出程序
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
int main()
{
//glfw用来实列化窗口
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, "My Opengl Game", NULL, NULL);
if (window == NULL)
{
printf("Open window failed");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f,
0.5f,-0.5f, 0.0f, 0.0f,1.0f,0.0f,
-0.5f,-0.5f, 0.0f, 0.0f,0.0f,1.0f,
-0.5f, 0.5f, 0.0f, 0.5f,0.5f,0.0f
};
unsigned int indices[] = {
0,1,3,
1,2,3
};
顶点着色器,通过glsl语言来编写
const char* vertexShaderSource =
"#version 330 core \n"
"layout(location = 6) in vec3 aPos; \n"
"layout(location = 7) in vec3 aColor;"
"out vec4 vertexColor; \n"
"void main(){\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); \n"
"vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);\n"
"} \n";
const char* fragmentShaderSource =
"#version 330 core \n"
"in vec4 vertexColor; \n "
"uniform vec4 ourColor; \n"
"out vec4 fragmentcolor; \n"
"void main(){ \n"
"fragmentcolor = vertexColor ;} \n";
//初始化glew用来管理函数的指针
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
printf("Init Glew failed");
glfwTerminate();
return -1;
}
//设置viewport视口
glViewport(0, 0, 800, 600);
//通过
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
unsigned int vertexshader; //编译顶点着色器的源码,通过id来引用
vertexshader = glcreateshader(gl_vertex_shader);
glshadersource(vertexshader, 1, &vertexshadersource, null);
glcompileshader(vertexshader);
unsigned int fragmentshader; //编译片段着色器的源码通过id来引用
fragmentshader = glcreateshader(gl_fragment_shader);
glshadersource(fragmentshader, 1, &fragmentshadersource, null);
glcompileshader(fragmentshader);
unsigned int shaderprogram; //着色器程序,把着色器合并
shaderprogram = glcreateprogram();
glattachshader(shaderprogram, vertexshader);
glattachshader(shaderprogram, fragmentshader);
gllinkprogram(shaderprogram);
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); //链接顶点位置属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); //链接顶点颜色属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(7);
//游戏循环引擎,不希望渲染好直接退出游戏
while (!glfwWindowShouldClose(window))
{
//通过
glfwSetKeyCallback(window, key_callback);
//渲染
//清空颜色缓冲
glClearColor(0.5f, 0.1f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//激活着色器
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//绘制三角形(两种绘制方式)
//glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate(); //释放Glfw分配的内存
return 0;
}
通过读取文件shader来绘制四边形
两个Shader.text文件
fragmentSource.txt
#version 330 core
in vec4 vertexColor;
uniform vec4 ourColor;
out vec4 fragmentcolor;
void main()
{
fragmentcolor = vertexColor;
}
vertexShader.txt
#version 330 core
layout(location = 6) in vec3 aPos;
layout(location = 7) in vec3 aColor;
out vec4 vertexColor;
void main(){
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);
}
shader.cpp
#include "Shader.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define GLEW_STATIC
using namespace std;
Shader::Shader(const char* vertexPath,const char* fragmentPath)
{
ifstream vertexFile;
ifstream fragmentFile;
stringstream vertexSStream;
stringstream fragmentSStream;
//打开文件并且转化为文件流
vertexFile.open(vertexPath);
fragmentFile.open(fragmentPath);
vertexFile.exceptions(ifstream::failbit || ifstream::badbit);
fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);
try
{
if (!vertexFile.is_open() || !vertexFile.is_open())
{
printf("Open file error");
}
//把文件流读取到缓冲区并且转化为字符串流
vertexSStream << vertexFile.rdbuf();
fragmentSStream << fragmentFile.rdbuf();
//把字符串流转化为字符串
vertexString = vertexSStream.str();
fragmentString = fragmentSStream.str();
//把字符出去转换为字符指针
vertexSource = vertexString.c_str();
fragmentSource = fragmentString.c_str();
//通过id来引用这两个shader
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex,1,&vertexSource,NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1,&fragmentSource, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
//创建program来把两个shader连接在一起
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
}
catch (const std::exception& ex)
{
printf(ex.what());
}
}
void Shader::checkCompileErrors(unsigned int ID,string type)
{
int success;
char infoLog[512];
if (type != "PROGRAM")
{
glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(ID, 512,NULL, infoLog);
cout << "shader compile error:" << infoLog << endl;
}
}
else
{
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if(!success)
{
glGetProgramInfoLog(ID, 512, NULL, infoLog);
cout << "program compile error:" << infoLog << endl;
}
}
}
void Shader::use()
{
glUseProgram(ID);
}
shader.h
#pragma once
#include<string>
class Shader
{
public:
Shader(const char* vertexPath, const char* fragmentPath);
std::string vertexString;
std::string fragmentString;
const char* vertexSource;
const char* fragmentSource;
unsigned int ID;
void use();
void checkCompileErrors(unsigned int ID, std::string type);
};
main.cpp
```csharp
#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include"Shader.h"
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
int main()
{
//glfw用来实列化窗口
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, "My Opengl Game", NULL, NULL);
if (window == NULL)
{
printf("Open window failed");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f,
0.5f,-0.5f, 0.0f, 0.0f,1.0f,0.0f,
-0.5f,-0.5f, 0.0f, 0.0f,0.0f,1.0f,
-0.5f, 0.5f, 0.0f, 0.5f,0.5f,0.0f
};
unsigned int indices[] = {
0,1,3,
1,2,3
};
//初始化glew用来管理函数的指针
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
printf("Init Glew failed");
glfwTerminate();
return -1;
}
//设置viewport视口
glViewport(0, 0, 800, 600);
Shader *myShader = new Shader("vertexSource.txt", "fragmentSource.txt");
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); //链接顶点位置属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); //链接顶点颜色属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(7);
//游戏循环引擎,不希望渲染好直接退出游戏
while (!glfwWindowShouldClose(window))
{
glfwSetKeyCallback(window, key_callback);
//渲染
//清空颜色缓冲
glClearColor(0.5f, 0.1f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// glUseProgram(shaderProgram);//激活着色器
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
myShader->use();
//绘制三角形
// glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate(); //释放Glfw分配的内存
return 0;
}
给长方形添加纹理贴图
首先把顶点信息改善
GLfloat vertices[] = {
// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上
};
如何向vao解释这些uv信息
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); //链接顶点位置属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(6);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); //链接顶点颜色属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(7);
glVertexAttribPointer(8, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); //链接顶点uv属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(8);
创建贴图缓冲区
unsigned int TexBuffer;
glGenTextures(1, &TexBuffer);
glBindTexture(GL_TEXTURE_2D, TexBuffer);
int width, height, nrChannel;
unsigned char *data = stbi_load("bird.jpg", &width, &height, &nrChannel, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
printf("load image error");
}
stbi_image_free(data);
加入到顶点着色器中
#version 330 core
layout(location = 6) in vec3 aPos;
layout(location = 7) in vec3 aColor;
layout(location = 8) in vec2 texCoord;
out vec4 vertexColor;
out vec2 TexCoord;
void main(){
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);
TexCoord = texCoord;
}
加入到片段着色器中
#version 330 core
in vec4 vertexColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
out vec4 fragmentcolor;
void main()
{
fragmentcolor = texture(ourTexture,TexCoord);
}
首先这个要有一个库的引入soil 简易图形库
创建多个游戏物体并实现相机的移动
实现一个相机类
camera.h
#pragma once
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
class Camera
{
public:
Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup);
Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup);
glm::vec3 Position;
glm::vec3 Forward;
glm::vec3 Right;
glm::vec3 Up;
glm::vec3 Worldup;
float Pitch;
float Yaw;
float SenseX = 0.001f;
float SenseY = 0.001f;
float speedZ = 0;
glm::mat4 GetViewMatrix();
void ProcessMouseMovement(float deltaX, float deltaY);
void UpdateCameraPos();
private :
void UpadateCameraVectors();
};
Camera.cpp
#include "Camera.h"
Camera::Camera(glm::vec3 position, glm::vec3 target,glm::vec3 worldup)
{
Position = position;
Worldup = worldup;
Forward = glm::normalize(target - position);
Right = glm::normalize(glm::cross(Forward, Worldup));
Up = glm::normalize(glm::cross(Forward, Right));
}
Camera::Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup)
{
Position = position;
Worldup = worldup;
Pitch = pitch;
Yaw = yaw;
Forward.x = glm::cos(pitch)*glm::sin(yaw);
Forward.y = glm::sin(pitch);
Forward.z = glm::cos(pitch)*glm::cos(yaw);
Right = glm::normalize(glm::cross(Forward, Worldup));
Up = glm::normalize(glm::cross(Forward, Right));
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(Position, Position + Forward, Worldup);
}
void Camera::ProcessMouseMovement(float deltaX, float deltaY)
{
Pitch -= deltaY * SenseX;
Yaw -= deltaX * SenseY;
UpadateCameraVectors();
}
void Camera::UpdateCameraPos()
{
Position += Forward * speedZ*0.1f;
}
//private
void Camera::UpadateCameraVectors()
{
Forward.x = glm::cos(Pitch)*glm::sin(Yaw);
Forward.y = glm::sin(Pitch);
Forward.z = glm::cos(Pitch)*glm::cos(Yaw);
Right = glm::normalize(glm::cross(Forward, Worldup));
Up = glm::normalize(glm::cross(Forward, Right));
}
顶点着色器
#version 330 core
layout(location = 6) in vec3 aPos;
//layout(location = 7) in vec3 aColor;
layout(location = 8) in vec2 texCoord;
//out vec4 vertexColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main(){
gl_Position = projMat*viewMat*modelMat*vec4(aPos.x, aPos.y, aPos.z, 1.0);//顶点着色器的输出
//vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);
TexCoord = texCoord;
}
主函数
#include<iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include"Shader.h"
#define STB_IMAGE_IMPLEMENTATION
#include"stb_image.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include"Camera.h"
//Camera camera(glm::vec3(0, 0, 3.0f), glm::vec3(0,0 , 0), glm::vec3(0, 1.0f, 0));
Camera camera(glm::vec3(0, 0, 3.0f), glm::radians(-15.0f), glm::radians(180.0f), glm::vec3(0, 1.0f, 0));
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
camera.speedZ = 1.0f;
}
else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
camera.speedZ = -1.0f;
}
else
{
camera.speedZ = 0;
}
}
float lastX;
float lastY;
bool firstMouse = true;
void mouse_callback(GLFWwindow *window, double xPos, double yPos)
{
if (firstMouse == true)
{
lastX = xPos;
lastY = yPos;
firstMouse = false;
}
float deltaX, deltaY;
deltaX = xPos - lastX;
deltaY = yPos - lastY;
lastX = xPos;
lastY = yPos;
camera.ProcessMouseMovement(deltaX, deltaY);
// printf("%f \n", deltaX);
}
int main()
{
//glfw用来实列化窗口
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, "My Opengl Game", NULL, NULL);
if (window == NULL)
{
printf("Open window failed");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//关闭鼠标显示
glfwSetCursorPosCallback(window, mouse_callback);
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
glm::vec3 cubePositions[] = {
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f, 2.0f, -2.5f),
glm::vec3(1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f)
};
unsigned int indices[] = {
0,1,3,
1,2,3
};
//初始化glew用来管理函数的指针
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
printf("Init Glew failed");
glfwTerminate();
return -1;
}
//设置viewport视口
glViewport(0, 0, 800, 600);
glEnable(GL_DEPTH_TEST);//开启深度测试,这样的话会可以判断那些先渲染那些后渲染
Shader *myShader = new Shader("vertexSource.txt", "fragmentSource.txt");
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); //链接顶点位置属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(6);
glVertexAttribPointer(8, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); //链接顶点uv属性,如何向opengl解释这些顶点数据
glEnableVertexAttribArray(8);
unsigned int TexBufferA;
glGenTextures(1, &TexBufferA);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TexBufferA);
int width, height, nrChannel;
unsigned char *data = stbi_load("bird.jpg", &width, &height, &nrChannel, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
printf("load image error");
}
stbi_image_free(data);
unsigned int TexBufferB;
glGenTextures(1, &TexBufferB);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, TexBufferB);
int width2, height2, nrChannel2;
unsigned char *data2 = stbi_load("ground.png", &width2, &height2, &nrChannel2, 0);//加载图片
if (data2)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width2, height2, 0, GL_RGB, GL_UNSIGNED_BYTE, data2);//生成图片
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
printf("load image error");
}
stbi_image_free(data2);
glm::mat4 trans;
//trans = glm::translate(trans, glm::vec3(-1.0f, 0, 0));
glm::mat4 modelMat;
modelMat = glm::rotate(modelMat, glm::radians(-55.0f), glm::vec3(1.0f, 1.0f, 0));
glm::mat4 viewMat;
//viewMat = camera.GetViewMatrix();
glm::mat4 projMat;
projMat = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f,0.1f, 100.0f);//参数分别是视野,宽高比,近平面和远平面
//游戏循环引擎,不希望渲染好直接退出游戏
while (!glfwWindowShouldClose(window))
{
//trans = glm::translate(trans, glm::vec3(-0.01f, 0, 0));
glfwSetKeyCallback(window, key_callback);
//渲染
//清空颜色缓冲
glClearColor(0.5f, 0.1f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TexBufferA);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, TexBufferB);
// glBindTexture(GL_TEXTURE_2D, TexBuffer);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
viewMat = camera.GetViewMatrix();
for (int i = 0; i < 10; i++)
{
glm::mat4 modelMat2;
modelMat2 = glm::translate(modelMat2, cubePositions[i]);
myShader->use();
glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);
glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture2"), 3);
glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "modelMat"), 1, false, glm::value_ptr(modelMat2));
glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "viewMat"), 1, false, glm::value_ptr(viewMat));
glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "projMat"), 1, false, glm::value_ptr(projMat));
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glfwSwapBuffers(window);
glfwPollEvents();
camera.UpdateCameraPos();
}
glfwTerminate(); //释放Glfw分配的内存
return 0;
}