三角形光栅化算法

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "shader_s.h"

#include <iostream>
#include <vector>
using namespace std;
unsigned int VBO, VAO;
vector<float> vertices;
double xpos, ypos;
int n = 0;
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 800;


float f(float x, float y, float x0, float y0, float x1, float y1) {  
	//过(x0,y0)和(x1,y1)的隐式直线方程
	return (y0 - y1) * x + (x1 - x0) * y + x0 * y1 - x1 * y0;
}

float floor(float x1, float x2, float x3) {  //最低点
	float x = min(x1, x2);
	x = min(x, x3);
	return x;
}

float ceiling(float x1, float x2, float x3) {  //最高点
	float x = max(x1, x2);
	x = max(x, x3);
	return x;
}

void processInput(GLFWwindow* window);

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	// make sure the viewport matches the new window dimensions; 
	glViewport(0, 0, width, height);
}

// settings

void swap(int& a, int& b) {
	int t = a;
	a = b;
	b = t;
}

void drawTriangle(float x0, float x1, float x2, float y0, float y1, float y2) {  //画三角形
	float ymin, xmin, ymax, xmax;
	ymin = floor(y0, y1, y2);
	xmin = floor(x0, x1, x2);
	ymax = ceiling(y0, y1, y2);
	xmax = ceiling(x0, x1, x2);
	float i, j, k1, k2, k3, fa, fb, fc, f12, f20, f01;
	for (i = xmin; i <= xmax; i++) {
		for (j = ymin; j <= ymax; j++) {
			fa = f(x0, y0, x1, y1, x2, y2);
			fb = f(x1, y1, x2, y2, x0, y0);
			fc = f(x2, y2, x0, y0, x1, y1);
			f12 = f(-1, -1, x1, y1, x2, y2);
			f20 = f(-1, -1, x2, y2, x0, y0);
			f01 = f(-1, -1, x0, y0, x1, y1);
			k1 = f(i, j, x1, y1, x2, y2) / fa;  //a
			k2 = f(i, j, x2, y2, x0, y0) / fb;  //beita
			k3 = 1 - k1 - k2;                   //y
			if (k1 >= 0 && k2 >= 0 && k3 >= 0) {
				if ((k1 > 0 || fa * f12 > 0) && (k2 > 0 || fb * f20 > 0) && (k3 > 0 || fc * f01 > 0)) 
				{  //处理三角形边上的像素
					vertices.push_back(i);
					vertices.push_back(j);
					vertices.push_back(k1);
					vertices.push_back(k2);
					vertices.push_back(k3);
				}
			}
		}
	}
}


int main()
{
	//           x0    x1   x2   y0  y1    y2
	drawTriangle(100, 340, 340, 240, 240, 480);
	drawTriangle(220, 460, 460, 240, 240, 0);
	drawTriangle(460, 460, 700, 120, 360, 360);
	drawTriangle(340, 580, 340, 360, 360, 600);
	

	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif

	// glfw window creation
	// --------------------
	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// glad: load all OpenGL function pointers
	// ---------------------------------------
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// build and compile our shader program
	// ------------------------------------
	Shader ourShader("triangle.vert", "triangle.frag"); // you can name your shader files however you like

	// set up vertex data (and buffer(s)) and configure vertex attributes
	// ------------------------------------------------------------------

	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);
	// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
	// position attribute
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	// color attribute
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
	glEnableVertexAttribArray(1);
	// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
	// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
	// glBindVertexArray(0);


	glm::mat4 proj = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);

	glm::mat4 model = glm::mat4(1.0f);
	glm::mat4 view = glm::mat4(1.0f);
	// render loop
	// -----------
	while (!glfwWindowShouldClose(window))
	{
		// input
		// -----
		processInput(window);

		// render
		// ------
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// render the triangle
		ourShader.use();


		glm::mat4 proj = glm::ortho(0.0f, 800.0f, 0.0f, 800.0f, 0.1f, 100.0f);

		glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0, 0.0, -10.0));
		glm::mat4 view = glm::mat4(1.0f);

		unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
		unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view");
		unsigned int projectLoc = glGetUniformLocation(ourShader.ID, "projection");
		// pass them to the shaders (3 different ways)
		glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
		glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
		glUniformMatrix4fv(projectLoc, 1, GL_FALSE, glm::value_ptr(proj));
		// note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
	//	ourShader.setMat4("projection", projection);




		glBindVertexArray(VAO);
		glDrawArrays(GL_POINTS, 0, vertices.size() / 5);


		// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
		// -------------------------------------------------------------------------------
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// optional: de-allocate all resources once they've outlived their purpose:
	// ------------------------------------------------------------------------
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);

	// glfw: terminate, clearing all previously allocated GLFW resources.
	// ------------------------------------------------------------------
	glfwTerminate();
	return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值