圆的画法
直接上代码吧。
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改成一样的就行了