第一个3D程序!

news2025/3/10 10:55:29

 运行效果

CPP

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <soil2/SOIL2.h>

#define PI 3.14159f

#define numVAOs 1
#define numVBOs 128

#define SPEED 0.1f
#define ANGLE 0.01f

using namespace std;

GLuint rendering_program;
GLuint vao[numVAOs];
GLuint vbo[numVBOs];
GLuint vbo_count = 0;
GLuint mvloc, ploc, nloc;
GLuint clr_loc;
GLuint global_amb_loc, dirlight_amb_loc, dirlight_dif_loc, dirlight_dir_loc;

int HEIGHT = 724, WIDTH = 1024;
float aspect = (float)WIDTH / (float)HEIGHT;

glm::vec4 GlobalAmbient = { 0.5f, 0.5f, 0.5f, 1.0f };		//全局环境光
glm::vec4 DirLightAmbient = { 0.2f, 0.2f, 0.2f, 1.0f };		//定向光:环境特征
glm::vec4 DirLightDiffuse = { 0.35f, 0.35f, 0.35f, 1.0f };	//定向光:漫反射
glm::vec3 DirLightDirection = { -0.5f, -0.866f, 0.0f };

glm::mat4 tmat;												//平移
glm::mat4 rmat;												//旋转
glm::mat4 vmat;												//t_mat * r_mat
glm::mat4 pmat;												//透视
glm::mat4 mvmat;
glm::mat4 invmat;											//mv矩阵的逆
glm::vec4 texture_color;

struct Camera {
	float x, y, z;
	float theta, fine;
}camera;

struct Plane {
	GLuint vbo_index[2] = { 0 };
	glm::vec3 position = { 0.0f, 0.0f, 0.0f };
	float vertex_positions[18] = {
		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
		1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
	};
	float vertex_normal[18] = {
		0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
	};
	void init(float x, float y, float z) {
		vbo_index[0] = vbo_count++;
		vbo_index[1] = vbo_count++;
		position = { x, y, z };
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[0]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[1]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_normal), vertex_normal, GL_STATIC_DRAW);
	}
	void draw() {
		glUniformMatrix4fv(mvloc, 1, GL_FALSE, glm::value_ptr(mvmat));
		glUniformMatrix4fv(ploc, 1, GL_FALSE, glm::value_ptr(pmat));
		glUniformMatrix4fv(nloc, 1, GL_FALSE, glm::value_ptr(invmat));
		glUniform4fv(clr_loc, 1, glm::value_ptr(texture_color));
		glBindBuffer(GL_ARRAY_BUFFER, vbo[plane.vbo_index[0]]);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[plane.vbo_index[1]]);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(1);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);
		glDrawArrays(GL_TRIANGLES, 0, 6);
	}
}plane;
struct Tetrahedron {
	GLuint vbo_index[2] = { 0 };
	glm::vec3 position = { 0.0f, 0.0f, 0.0f };
	float vertex_positions[36] = {
		0.0f, -0.408f, 1.155f, -1.0f, -0.408f, -0.577f, 1.0f, -0.408f, -0.577f,
		0.0f, -0.408f, 1.155f, 0.0f, 1.225f, 0.0f, -1.0f, -0.408f, -0.577f,
		0.0f, -0.408f, 1.155f, 1.0f, -0.408f, -0.577f, 0.0f, 1.225f, 0.0f,
		-1.0f, -0.408f, -0.577f, 0.0f, 1.225f, 0.0f, 1.0f, -0.408f, -0.577f
	};
	float vertex_normal[36] = {
		0.0f, -1.225f, -0.0f, 0.0f, -1.225f, 0.0f, 0.0f, -1.225f, 0.0f,
		-1.0f, 0.408f,-0.577f, -1.0f, 0.408f, 0.577f, -1.0f, 0.408f, 0.577f,
		1.0f, 0.408f, 0.577f, 1.0f, 0.408f, 0.577f, 1.0f, 0.408f, 0.577f,
		0.0f, 0.408f, -1.155f, 0.0f, 0.408f, -1.155f, 0.0f, 0.408f, -1.155f
	};
	void init(float x, float y, float z) {
		vbo_index[0] = vbo_count++;
		vbo_index[1] = vbo_count++;
		position = { x, y, z };
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[0]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[1]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_normal), vertex_normal, GL_STATIC_DRAW);
	}
	void draw() {
		glUniformMatrix4fv(mvloc, 1, GL_FALSE, glm::value_ptr(mvmat));
		glUniformMatrix4fv(ploc, 1, GL_FALSE, glm::value_ptr(pmat));
		glUniformMatrix4fv(nloc, 1, GL_FALSE, glm::value_ptr(invmat));
		glUniform4fv(clr_loc, 1, glm::value_ptr(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
		glBindBuffer(GL_ARRAY_BUFFER, vbo[tetrahedron.vbo_index[0]]);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[tetrahedron.vbo_index[1]]);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(1);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);
		glDrawArrays(GL_TRIANGLES, 0, 12);
	}
}tetrahedron;
struct Icosahedron {
	GLuint vbo_index[2] = { 0 };
	glm::vec3 position = { 0.0f, 0.0f, 0.0f };
	float vertex_positions[180] = {
		-0.618f, 1.0f, 0.0f, 0.618f, 1.0f, 0.0f, 0.0f, 0.618f, -1.0f,
		0.618f, -1.0f, 0.0f, -0.618f, -1.0f, 0.0f, 0.0f, -0.618f, -1.0f,
		0.0f, 0.618f, -1.0f, -1.0f, 0.0f, -0.618f, -0.618f, 1.0f, 0.0f,
		-1.0f, 0.0f, -0.618f, 0.0f, -0.618f, -1.0f, -0.618f, -1.0f, 0.0f,
		0.618f, 1.0f, 0.0f, 1.0f, 0.0f, -0.618f, 0.0f, 0.618f, -1.0f,
		1.0f, 0.0f, -0.618f, 0.618f, -1.0f, 0.0f, 0.0f, -0.618f, -1.0f,
		-1.0f, 0.0f, -0.618f, 0.0f, 0.618f, -1.0f, 0.0f, -0.618f, -1.0f,
		0.0f, -0.618f, -1.0f, 0.0f, 0.618f, -1.0f, 1.0f, 0.0f, -0.618f,

		0.618f, 1.0f, 0.0f, -0.618f, 1.0f, 0.0f, 0.0f, 0.618f, 1.0f,
		-0.618f, -1.0f, 0.0f, 0.618f, -1.0f, 0.0f, 0.0f, -0.618f, 1.0f,
		-1.0f, 0.0f, 0.618f, 0.0f, 0.618f, 1.0f, -0.618f, 1.0f, 0.0f,
		-1.0f, 0.0f, 0.618f, -0.618f, -1.0f, 0.0f, 0.0f, -0.618f, 1.0f,
		0.618f, 1.0f, 0.0f, 0.0f, 0.618f, 1.0f, 1.0f, 0.0f, 0.618f,
		0.0f, -0.618f, 1.0f, 0.618f, -1.0f, 0.0f, 1.0f, 0.0f, 0.618f,
		0.0f, -0.618f, 1.0f, 0.0f, 0.618f, 1.0f, -1.0f, 0.0f, 0.618f,
		0.0f, 0.618f, 1.0f, 0.0f, -0.618f, 1.0f, 1.0f, 0.0f, 0.618f,

		-1.0f, 0.0f, 0.618f, -0.618f, 1.0f, 0.0f, -1.0f, 0.0f, -0.618f,
		-1.0f, 0.0f, 0.618f, -1.0f, 0.0f, -0.618f, -0.618f, -1.0f, 0.0f,
		1.0f, 0.0f, 0.618f, 1.0f, 0.0f, -0.618f, 0.618f, 1.0f, 0.0f,
		1.0f, 0.0f, -0.618f, 1.0f, 0.0f, 0.618f, 0.618f, -1.0f, 0.0f
	};
	float vertex_normal[180] = {
		0.0f, 2.618f, -1.0f, 0.0f, 2.618f, -1.0f, 0.0f, 2.618f, -1.0f,
		0.0f, -2.618f, -1.0f, 0.0f, -2.618f, -1.0f, 0.0f, -2.618f, -1.0f,
		-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
		-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
		1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
		1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
		-1.0f, 0.0f, -2.618f, -1.0f, 0.0f, -2.618f, -1.0f, 0.0f, -2.618f,
		1.0f, 0.0f, -2.618f, 1.0f, 0.0f, -2.618f, 1.0f, 0.0f, -2.618f,

		0.0f, 2.618f, 1.0f, 0.0f, 2.618f, 1.0f, 0.0f, 2.618f, 1.0f,
		0.0f, -2.618f, 1.0f, 0.0f, -2.618f, 1.0f, 0.0f, -2.618f, 1.0f,
		-1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
		-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
		-1.0f, 0.0f, 2.618f, -1.0f, 0.0f, 2.618f, -1.0f, 0.0f, 2.618f,
		1.0f, 0.0f, 2.618f, 1.0f, 0.0f, 2.618f, 1.0f, 0.0f, 2.618f,

		-2.618f, 1.0f, 0.0f, -2.618f, 1.0f, 0.0f, -2.618f, 1.0f, 0.0f,
		-2.618f, -1.0f, 0.0f, -2.618f, -1.0f, 0.0f, -2.618f, -1.0f, 0.0f,
		2.618f, 1.0f, 0.0f, 2.618f, 1.0f, 0.0f, 2.618f, 1.0f, 0.0f,
		2.618f, -1.0f, 0.0f, 2.618f, -1.0f, 0.0f, 2.618f, -1.0f, 0.0f
	};
	void init(float x, float y, float z) {
		vbo_index[0] = vbo_count++;
		vbo_index[1] = vbo_count++;
		position = { x, y, z };
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[0]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[vbo_index[1]]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_normal), vertex_normal, GL_STATIC_DRAW);
	}
	void draw() {
		glUniformMatrix4fv(mvloc, 1, GL_FALSE, glm::value_ptr(mvmat));
		glUniformMatrix4fv(ploc, 1, GL_FALSE, glm::value_ptr(pmat));
		glUniformMatrix4fv(nloc, 1, GL_FALSE, glm::value_ptr(invmat));
		glUniform4fv(clr_loc, 1, glm::value_ptr(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)));
		glBindBuffer(GL_ARRAY_BUFFER, vbo[icosahedron.vbo_index[0]]);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, vbo[icosahedron.vbo_index[1]]);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(1);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);
		glDrawArrays(GL_TRIANGLES, 0, 60);
	}
}icosahedron;

string ReadShaderSource(const char* file_path) {
	string content;
	string line = "";
	ifstream file_stream(file_path, ios::in);
	while (!file_stream.eof()) {
		getline(file_stream, line);
		content.append(line + "\n");
	}
	file_stream.close();
	return content;
}
void PrintShaderLog(GLuint shader) {
	int len = 0;
	int ch_writtn = 0;
	char* log;
	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
	if (len > 0) {
		log = (char*)malloc(len);
		glGetShaderInfoLog(shader, len, &ch_writtn, log);
		cout << "Shader Info Log:" << log << endl;
		free(log);
	}
}
void PrintProgramLog(GLuint program) {
	int len = 0;
	int ch_writtn = 0;
	char* log;
	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
	if (len > 0) {
		log = (char*)malloc(len);
		glGetProgramInfoLog(program, len, &ch_writtn, log);
		cout << "Program Info Log:" << log << endl;
		free(log);
	}
}
bool CheckOpenGLError() {
	bool found_error = false;
	int glerr = glGetError();
	while (glerr != GL_NO_ERROR) {
		cout << "GL ERROR:" << glerr << endl;
		found_error = true;
		glerr = glGetError();
	}
	return found_error;
}
GLuint CreateShaderProgram() {
	GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
	GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);
	GLint vert_compiled;
	GLint frag_compiled;
	GLint linked;
	string vert_shader_string = ReadShaderSource("vert_shader.glsl");
	string frag_shader_string = ReadShaderSource("frag_shader.glsl");
	const char* vert_shader_source = vert_shader_string.c_str();
	const char* frag_shader_source = frag_shader_string.c_str();
	glShaderSource(vshader, 1, &vert_shader_source, NULL);
	glShaderSource(fshader, 1, &frag_shader_source, NULL);
	glCompileShader(vshader);
	CheckOpenGLError();
	glGetShaderiv(vshader, GL_COMPILE_STATUS, &vert_compiled);
	if (vert_compiled != 1) {
		cout << "vertex compilation failed" << endl;
		PrintShaderLog(vshader);
	}
	glCompileShader(fshader);
	CheckOpenGLError();
	glGetShaderiv(fshader, GL_COMPILE_STATUS, &frag_compiled);
	if (frag_compiled != 1) {
		cout << "fragment compilation failed" << endl;
		PrintShaderLog(fshader);
	}
	GLuint program = glCreateProgram();
	glAttachShader(program, vshader);
	glAttachShader(program, fshader);
	glLinkProgram(program);
	CheckOpenGLError();
	glGetProgramiv(program, GL_LINK_STATUS, &linked);
	if (linked != 1) {
		cout << "linking failed" << endl;
		PrintProgramLog(program);
	}
	return program;
}
GLuint LoadTexture(const char* ImagePath) {
	GLuint textureID;
	textureID = SOIL_load_OGL_texture(ImagePath, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
	if (textureID == 0) cout << "could not find texture file:" << ImagePath << endl;
	return textureID;
}
void init(GLFWwindow* window) {
	vmat = glm::mat4(1.0f);
	rmat = glm::mat4(1.0f);
	pmat = glm::perspective(1.3f, aspect, 0.1f, 1000.0f);
	rendering_program = CreateShaderProgram();
	glGenVertexArrays(numVAOs, vao);
	glBindVertexArray(vao[0]);
	glGenBuffers(numVBOs, vbo);
	tetrahedron.init(4.0f, 4.0f, 0.0f);
	icosahedron.init(0.0f, 4.0f, 4.0f);
	plane.init(0.0f, 0.0f, 0.0f);
}
void MoveCamera(GLFWwindow* window) {
	bool translate = false;
	bool rotato = false;
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
		camera.x -= (float)sin(camera.theta) * SPEED;
		camera.z -= (float)cos(camera.theta) * SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
		camera.x += (float)sin(camera.theta) * SPEED;
		camera.z += (float)cos(camera.theta) * SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
		camera.x -= (float)cos(camera.theta) * SPEED;
		camera.z += (float)sin(camera.theta) * SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
		camera.x += (float)cos(camera.theta) * SPEED;
		camera.z -= (float)sin(camera.theta) * SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
		camera.y += SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
		camera.y -= SPEED;
		translate = true;
	}
	if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
		if (camera.fine < PI / 2.0) {
			camera.fine += ANGLE;
			rotato = true;
		}
	}
	if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
		if (camera.fine > -PI / 2.0) {
			camera.fine -= ANGLE;
			rotato = true;
		}
	}
	if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
		camera.theta += ANGLE;
		rotato = true;
	}
	if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
		camera.theta -= ANGLE;
		rotato = true;
	}
	if (translate) tmat = glm::translate(glm::mat4(1.0f), glm::vec3(-camera.x, -camera.y, -camera.z));
	if (rotato) rmat = {
		{ cos(camera.theta)  , sin(camera.fine) * sin(camera.theta), cos(camera.fine) * sin(camera.theta), 0.0f },
		{ 0.0f				 , cos(camera.fine)					 , -sin(camera.fine)				   , 0.0f },
		{ -sin(camera.theta) , sin(camera.fine) * cos(camera.theta), cos(camera.fine) * cos(camera.theta), 0.0f },
		{ 0.0f				 , 0.0f								 , 0.0f								   , 1.0f }
	};
	if (translate || rotato) vmat = rmat * tmat;
}
void WindowReshapeCallback(GLFWwindow* window, int new_width, int new_height) {
	WIDTH = new_width;
	HEIGHT = new_height;
	aspect = (float)WIDTH / (float)HEIGHT;
	pmat = glm::perspective(1.3f, aspect, 0.1f, 1000.0f);
	glViewport(0, 0, WIDTH, HEIGHT);
}
void InstallLight() {
	global_amb_loc = glGetUniformLocation(rendering_program, "GlobalAmbient");
	dirlight_amb_loc = glGetUniformLocation(rendering_program, "DirLightAmbient");
	dirlight_dif_loc = glGetUniformLocation(rendering_program, "DirLightDiffuse");
	dirlight_dir_loc = glGetUniformLocation(rendering_program, "DirLightDirection");
	glProgramUniform4fv(rendering_program, global_amb_loc, 1, glm::value_ptr(GlobalAmbient));
	glProgramUniform4fv(rendering_program, dirlight_amb_loc, 1, glm::value_ptr(DirLightAmbient));
	glProgramUniform4fv(rendering_program, dirlight_dif_loc, 1, glm::value_ptr(DirLightDiffuse));
	glProgramUniform3fv(rendering_program, dirlight_dir_loc, 1, glm::value_ptr(DirLightDirection));
}
void display(GLFWwindow* window, double curretTime) {
	glClear(GL_DEPTH_BUFFER_BIT);
	glClear(GL_COLOR_BUFFER_BIT);
	glUseProgram(rendering_program);

	InstallLight();

	mvloc = glGetUniformLocation(rendering_program, "mvmat");
	ploc = glGetUniformLocation(rendering_program, "pmat");
	nloc = glGetUniformLocation(rendering_program, "nmat");
	clr_loc = glGetUniformLocation(rendering_program, "texture_color");

	glDisable(GL_CULL_FACE);

	for (int x = -32; x < 32; x++)
		for (int z = -32; z < 32; z++) {
			glm::mat4 mmat_p = glm::translate(glm::mat4(1.0f), glm::vec3((float)x, 0.0f, (float)z));
			if ((x + z) & 1)
				texture_color = { 0.0f, 1.0f, 0.0f, 1.0f };
			else
				texture_color = { 0.0f, 0.0f, 1.0f, 1.0f };
			mvmat = vmat * mmat_p;
			invmat = glm::transpose(glm::inverse(mvmat));
			plane.draw();
		}
	glEnable(GL_CULL_FACE);

	glm::mat4 mmat_t = glm::translate(glm::mat4(1.0f), tetrahedron.position);
	mvmat = vmat * mmat_t;
	invmat = glm::transpose(glm::inverse(mvmat));
	texture_color = { 1.0f, 0.0f, 0.0f, 1.0f };
	tetrahedron.draw();

	glm::mat4 mmat_i = glm::translate(glm::mat4(1.0f), icosahedron.position);
	mvmat = vmat * mmat_i;
	invmat = glm::transpose(glm::inverse(mvmat));
	texture_color = { 1.0f, 0.0f, 0.0f, 1.0f };
	icosahedron.draw();
}
int main() {
	if (!glfwInit()) { exit(EXIT_FAILURE); }
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "HelloWorld", NULL, NULL);
	glfwMakeContextCurrent(window);
	if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
	glfwSwapInterval(1);
	glfwSetWindowSizeCallback(window, WindowReshapeCallback);

	init(window);

	while (!glfwWindowShouldClose(window)) {
		MoveCamera(window);
		display(window, glfwGetTime());
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwDestroyWindow(window);
	glfwTerminate();
	exit(EXIT_SUCCESS);
}

顶点着色器

#version 430

layout (location=0) in vec3 position;
layout (location=1) in vec3 normal;

out vec3 varying_normal;
out vec3 varying_direction;

uniform mat4 mvmat;
uniform mat4 pmat;
uniform mat4 nmat;
uniform vec4 texture_color;
h
uniform vec4 GlobalAmbient;
uniform vec4 DirLightAmbient;
uniform vec4 DirLightDiffuse;
uniform vec3 DirLightDirection;

void main(void) {
	varying_normal = (nmat * vec4(normal, 1.0)).xyz;
	varying_direction = (nmat * vec4(DirLightDirection, 1.0)).xyz;
	gl_Position = pmat * mvmat * vec4(position, 1.0);
}

片段着色器

#version 430

in vec3 varying_normal;
in vec3 varying_direction;

out vec4 color;

uniform mat4 mvmat;
uniform mat4 pmat;
uniform mat4 nmat;
uniform vec4 texture_color;

uniform vec4 GlobalAmbient;
uniform vec4 DirLightAmbient;
uniform vec4 DirLightDiffuse;
uniform vec3 DirLightDirection;

void main(void) {
	vec3 L = normalize(varying_direction);
	vec3 N = normalize(varying_normal);
	float cos_theta = dot(L, N);
	vec3 ambient = GlobalAmbient.xyz * texture_color.xyz + DirLightAmbient.xyz * texture_color.xyz;
	vec3 diffuse = texture_color.xyz * DirLightDiffuse.xyz * max(cos_theta, 0.0);
	color = vec4(ambient + diffuse, 1.0);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NeuralCF 模型:神经网络协同过滤模型

实验和完整代码 完整代码实现和jupyter运行&#xff1a;https://github.com/Myolive-Lin/RecSys--deep-learning-recommendation-system/tree/main 引言 NeuralCF 模型由新加坡国立大学研究人员于 2017 年提出&#xff0c;其核心思想在于将传统协同过滤方法与深度学习技术相结…

第二十三章 MySQL锁之表锁

目录 一、概述 二、语法 三、特点 一、概述 表级锁&#xff0c;每次操作锁住整张表。锁定粒度大&#xff0c;发生锁冲突的概率最高&#xff0c;并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。 对于表级锁&#xff0c;主要分为以下三类&#xff1a; 1. 表锁 2. 元数…

【Uniapp-Vue3】获取用户状态栏高度和胶囊按钮高度

在项目目录下创建一个utils文件&#xff0c;并在里面创建一个system.js文件。 在system.js中配置如下代码&#xff1a; const SYSTEM_INFO uni.getSystemInfoAsync();// 返回状态栏高度 export const getStatusBarHeight ()> SYSTEM_INFO.statusBarHeight || 15;// 返回胶…

通向AGI之路:人工通用智能的技术演进与人类未来

文章目录 引言:当机器开始思考一、AGI的本质定义与技术演进1.1 从专用到通用:智能形态的范式转移1.2 AGI发展路线图二、突破AGI的五大技术路径2.1 神经符号整合(Neuro-Symbolic AI)2.2 世界模型架构(World Models)2.3 具身认知理论(Embodied Cognition)三、AGI安全:价…

将ollama迁移到其他盘(eg:F盘)

文章目录 1.迁移ollama的安装目录2.修改环境变量3.验证 背景&#xff1a;在windows操作系统中进行操作 相关阅读 &#xff1a;本地部署deepseek模型步骤 1.迁移ollama的安装目录 因为ollama默认安装在C盘&#xff0c;所以只能安装好之后再进行手动迁移位置。 # 1.迁移Ollama可…

Java自定义IO密集型和CPU密集型线程池

文章目录 前言线程池各类场景描述常见场景案例设计思路公共类自定义工厂类-MyThreadFactory自定义拒绝策略-RejectedExecutionHandlerFactory自定义阻塞队列-TaskQueue&#xff08;实现 核心线程->最大线程数->队列&#xff09; 场景1&#xff1a;CPU密集型场景思路&…

使用开源项目:pdf2docx,让PDF转换为Word

目录 1.安装python 2.安装 pdf2docx 3.使用 pdf2docx 转换 PDF 到 Word pdf2docx&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 环境&#xff1a;windows电脑 1.安装python Download Python | Python.org 最好下载3.8以上的版本 安装时记得选择上&#…

蓝桥杯思维训练营(四)

文章目录 小红打怪494.目标和 小红打怪 小红打怪 思路分析&#xff1a;可以看到ai的范围较大&#xff0c;如果我们直接一个个进行暴力遍历的话&#xff0c;会超时。当我们的攻击的次数越大的时候&#xff0c;怪物的血量就会越少&#xff0c;这里就有一个单调的规律在里面&…

尝试把clang-tidy集成到AWTK项目

前言 项目经过一段时间的耕耘终于进入了团队开发阶段&#xff0c;期间出现了很多问题&#xff0c;其中一个就是开会讨论团队的代码风格规范&#xff0c;目前项目代码风格比较混乱&#xff0c;有的模块是驼峰&#xff0c;有的模块是匈牙利&#xff0c;后面经过讨论&#xff0c;…

【学习笔记】深度学习网络-正则化方法

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 在之前的文章中介绍了深度学习中用…

介绍一下Mybatis的底层原理(包括一二级缓存)

表面上我们的就是Sql语句和我们的java对象进行映射&#xff0c;然后Mapper代理然后调用方法来操作数据库 底层的话我们就涉及到Sqlsession和Configuration 首先说一下SqlSession&#xff0c; 它可以被视为与数据库交互的一个会话&#xff0c;用于执行 SQL 语句&#xff08;Ex…

WordPress使用(1)

1. 概述 WordPress是一个开源博客框架&#xff0c;配合不同主题&#xff0c;可以有多种展现方式&#xff0c;博客、企业官网、CMS系统等&#xff0c;都可以很好的实现。 官网&#xff1a;博客工具、发布平台和内容管理系统 – WordPress.org China 简体中文&#xff0c;这里可…

BUUCTF_[安洵杯 2019]easy_web(preg_match绕过/MD5强碰撞绕过/代码审计)

打开靶场&#xff0c;出现下面的静态html页面&#xff0c;也没有找到什么有价值的信息。 查看页面源代码 在url里发现了img传参还有cmd 求img参数 这里先从img传参入手&#xff0c;这里我发现img传参好像是base64的样子 进行解码&#xff0c;解码之后还像是base64的样子再次进…

C基础寒假练习(4)

输入带空格的字符串&#xff0c;求单词个数、 #include <stdio.h> // 计算字符串长度的函数 size_t my_strlen(const char *str) {size_t len 0;while (str[len] ! \0) {len;}return len; }int main() {char str[100];printf("请输入一个字符串: ");fgets(…

MySQL 事务实现原理( 详解 )

MySQL 主要是通过: 锁、Redo Log、Undo Log、MVCC来实现事务 事务的隔离性利用锁机制实现 原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。 Redo Log(重做日志)&#xff1a;记录事务对数据库的所有修改&#xff0c;在崩溃时恢复未提交的更改&#xff0c;保证事务…

git基础使用--1--版本控制的基本概念

文章目录 git基础使用--1--版本控制的基本概念1.版本控制的需求背景&#xff0c;即为啥需要版本控制2. 集中式版本控制SVN3. 分布式版本控制 Git4. SVN和Git的比较 git基础使用–1–版本控制的基本概念 1.版本控制的需求背景&#xff0c;即为啥需要版本控制 先说啥叫版本&…

Unity飞行代码 超仿真 保姆级教程

本文使用Rigidbody控制飞机&#xff0c;基本不会穿模。 效果 飞行效果 这是一条优雅的广告 如果你也在开发飞机大战等类型的飞行游戏&#xff0c;欢迎在主页搜索博文并参考。 搜索词&#xff1a;Unity游戏(Assault空对地打击)开发。 脚本编写 首先是完整代码。 using System.Co…

力扣73矩阵置零

给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 输入&#xff1a;matrix [[0,1,2,0],[3,4,5,2],[…

登录认证(5):过滤器:Filter

统一拦截 上文我们提到&#xff08;登录认证&#xff08;4&#xff09;&#xff1a;令牌技术&#xff09;&#xff0c;现在大部分项目都使用JWT令牌来进行会话跟踪&#xff0c;来完成登录功能。有了JWT令牌可以标识用户的登录状态&#xff0c;但是完整的登录逻辑如图所示&…

python算法和数据结构刷题[1]:数组、矩阵、字符串

一画图二伪代码三写代码 LeetCode必刷100题&#xff1a;一份来自面试官的算法地图&#xff08;题解持续更新中&#xff09;-CSDN博客 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 面试经典 150 题 - 学习计…