OpenGL超级宝典 完整渲染管线画圆

圆的画法

在这里插入图片描述
直接上代码吧。
Shader类是上一篇文章的

shader

vertex shader

#version 450 core
layout(location = 0) in vec3 aPos;

void main()
{
	gl_Position = vec4(aPos, 1.0);
}

tec shader

#version 450 core
layout(vertices = 3) out;


void main()
{
	if(gl_InvocationID == 0)
	{
		//将细分因子写入这两个变量中,后面会详细讲什么意思
		gl_TessLevelInner[0] = 128.0;
		gl_TessLevelInner[1] = 128.0;
		gl_TessLevelOuter[0] = 128.0;
		gl_TessLevelOuter[1] = 128.0;
		gl_TessLevelOuter[2] = 128.0;
	}
	//将输入的数据作为输出数据
	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

}

tee shader

#version 450 core
layout(isolines, equal_spacing, ccw) in;

vec4 circlePoint(vec4 origin, float radius, float t);

void main()
{
	vec4 origin = gl_in[0].gl_Position;
	float radius = gl_in[1].gl_Position.x;
	float t = gl_TessCoord.x;
	gl_Position = circlePoint(origin, radius, t);

}

vec4 circlePoint(vec4 origin, float radius, float t)
{
	float s = t * 2;

	float deltX = abs(radius * cos(s * 3.1415926));
	float deltY = abs(radius * sin(s * 3.1415926));
	
	//第二象限
	if(s > 0.5 && s < 1.0)
	{
		deltX = -deltX;
	}
	//第三象限
	if(s >= 1.0 && s < 1.5)
	{
		deltX = -deltX;
		deltY = -deltY;
	}
	//第四象限
	if(s >= 1.5 && s < 2.0)
	{
		deltY = -deltY;
	}

	vec4 p = vec4(origin.x + deltX, origin.y + deltY, origin.z, 1.0);

	return p;
}

fragment shader

#version 450 core
out vec4 color;

void main()
{
	color = vec4(1.0, 1.0, 0.0, 1.0);
}

代码

#include "sb7.h"
#include "Shader.h"
#include <iostream>

class my_application : public sb7::application
{
public:
	void startup() {
		shader = new Shader("vs.vert", "tec.tesc", "tee.tese", "fs.frag");
		//创建vao
		glCreateVertexArrays(1, &vertex_arrays_object);
		//绑定vao到上下文
		glBindVertexArray(vertex_arrays_object);

		//创建缓存对象
		glCreateBuffers(2, buffer);

		//分配缓存空间,并且设置模式
		//第一个参数是分配缓冲的名称,第二个参数是分配的内存大小
		//第三个是分配的数据,没有可以写NULL,第四个参数是分配内存的目的
		glNamedBufferStorage(buffer[0], sizeof(vertices), NULL, GL_DYNAMIC_STORAGE_BIT);
		//绑定缓存对象到OpenGL
		/*glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
		glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);*/
		
		//第一步,绑定一个缓存到vao
		//第一个参数是需要绑定缓存的vao,第二个参数是绑定的绑定点,
		//第三个参数是绑定的缓存,第4个参数是绑定的数据在缓存中的位置,第5个参数是每个顶点之间的距离
		glVertexArrayVertexBuffer(vertex_arrays_object, 0, buffer[0], 0, sizeof(float) * 3);

		//告诉OpenGL数据的布局和格式
		//第一个参数是哪个vao,第二个参数是顶点属性,第三个参数是顶点的分量数量
		//第4个参数是数据的数据类型,第5个参数是是否标准化,第6个参数是与起点处顶点的偏移量
		glVertexArrayAttribFormat(vertex_arrays_object, 0, 3, GL_FLOAT, GL_FALSE, 0);

		//指示vao的顶点属性(第二个参数)要从绑定点(第三个参数)拿数据
		glVertexArrayAttribBinding(vertex_arrays_object, 0, 0);

		//启动属性自动填充
		//第一个参数是启动的vao,第二个参数是顶点属性
		glEnableVertexArrayAttrib(vertex_arrays_object, 0);

		glNamedBufferStorage(buffer[1], sizeof(bindcolor), NULL, GL_DYNAMIC_STORAGE_BIT);
		glVertexArrayVertexBuffer(vertex_arrays_object, 1, buffer[1], 0, sizeof(float) * 4);
		glVertexArrayAttribFormat(vertex_arrays_object, 1, 4, GL_FLOAT, GL_FALSE, 0);
		glVertexArrayAttribBinding(vertex_arrays_object, 1, 1);
		glEnableVertexArrayAttrib(vertex_arrays_object, 1);
	}

	void render(double currentTime) {
		GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 };
		glClearBufferfv(GL_COLOR, 0, color);

		glEnable(GL_MULTISAMPLE);

		shader->use();
		
		glNamedBufferSubData(buffer[0], 0, sizeof(vertices), vertices);
		glNamedBufferSubData(buffer[1], 0, 4 * 4 * 1, bindcolor);

		glDrawArrays(GL_PATCHES, 0, 3);
	}

	void shutdown(){

	}

private:
	Shader* shader;
	Shader* testShader;
	GLuint vertex_arrays_object;
	GLuint buffer[2];
	//第一个向量是圆心,第二个向量的x分量是半径
	GLfloat vertices[6] = 
	{
		0.0, 0.5, 0.0,
		0.5, 0.0, 0.0
	};
};

DECLARE_MAIN(my_application);

遇到的问题

画的圆是扁的

一开始我画的圆是扁的,最后发现是窗口是矩形的,不是方形,所以标准坐标会变所以才会呈现椭圆形的圆
在这里插入图片描述
解决方案,去sb7.h中改数据
在这里插入图片描述
把上面的width和height改成一样的就行了

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ht巷子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值