[Piglit] [PATCH 1/4] Add new classes to draw points and lines in to multisample FBO

Anuj Phogat anuj.phogat at gmail.com
Fri May 18 16:54:58 PDT 2012


This patch adds following new classes to common.cpp file:
 - Points: Draws a sequence of points with varied sizes in
           color buffer.

 - Spiral: Draws points with varied sizes in spiral pattern.

 - StencilSpiral: Draws spiral pattern in stencil buffer.

 - DepthSpiral: Draws spiral pattern in depth buffer.

 - Lines: Draws a sequence of lines with varied width in
          color buffer

 - Star: Draws lines in a star like pattern.

 - StencilStar: Draws star pattern in stencil buffer.

 - DepthStar: Draws star pattern in depth buffer.

All above mentioned classes are used to verify drawing multisample
points and lines in color, depth and sencil buffers.

Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
 tests/spec/ext_framebuffer_multisample/common.cpp |  446 +++++++++++++++++++++
 tests/spec/ext_framebuffer_multisample/common.h   |  152 +++++++
 2 files changed, 598 insertions(+), 0 deletions(-)

diff --git a/tests/spec/ext_framebuffer_multisample/common.cpp b/tests/spec/ext_framebuffer_multisample/common.cpp
index d1e6bcd..33b2859 100644
--- a/tests/spec/ext_framebuffer_multisample/common.cpp
+++ b/tests/spec/ext_framebuffer_multisample/common.cpp
@@ -639,6 +639,452 @@ void Triangles::draw(float (*proj)[4])
 	}
 }
 
+void Lines::compile()
+{
+	/* Line coords within (-1,-1) to (1,1) rect */
+	static const float pos_line[][2] = {
+		{ -0.8, -0.5 },
+		{  0.8, -0.5 }
+	};
+
+	/* Number of line instances across (and down) */
+	int lines_across = 4;
+
+	/* Total number of lines drawn */
+	num_lines = lines_across * lines_across;
+
+	/* Amount each line should be rotated compared to prev */
+	float rotation_delta = M_PI * 2.0 / num_lines;
+
+	/* Scaling factor uniformly applied to line coords */
+	float line_scale = 0.8 / lines_across;
+
+	/* Final scaling factor */
+	float final_scale = 0.95;
+
+	static const char *vert =
+		"#version 130\n"
+		"in vec2 pos_line;\n"
+		"uniform float line_scale;\n"
+		"uniform float rotation_delta;\n"
+		"uniform int lines_across;\n"
+		"uniform float final_scale;\n"
+		"uniform mat4 proj;\n"
+		"uniform int line_num;\n"
+		"\n"
+		"void main()\n"
+		"{\n"
+		"  vec2 pos = line_scale * pos_line;\n"
+		"  float rotation = rotation_delta * line_num;\n"
+		"  pos = mat2(cos(rotation), sin(rotation),\n"
+		"             -sin(rotation), cos(rotation)) * pos;\n"
+		"  int i = line_num % lines_across;\n"
+		"  int j = lines_across - 1 - line_num / lines_across;\n"
+		"  pos += (vec2(i, j) * 2.0 + 1.0) / lines_across - 1.0;\n"
+		"  pos *= final_scale;\n"
+		"  gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
+		"}\n";
+
+	static const char *frag =
+		"#version 130\n"
+		"void main()\n"
+		"{\n"
+		"  gl_FragColor = vec4(1.0);\n"
+		"}\n";
+
+	/* Compile program */
+	prog = glCreateProgram();
+	GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	glAttachShader(prog, vs);
+	GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	glAttachShader(prog, fs);
+	glBindAttribLocation(prog, 0, "pos_line");
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog)) {
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	/* Set up uniforms */
+	glUseProgram(prog);
+	glUniform1f(glGetUniformLocation(prog, "line_scale"), line_scale);
+	glUniform1f(glGetUniformLocation(prog, "rotation_delta"),
+		    rotation_delta);
+	glUniform1i(glGetUniformLocation(prog, "lines_across"), lines_across);
+	glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
+	proj_loc = glGetUniformLocation(prog, "proj");
+	line_num_loc = glGetUniformLocation(prog, "line_num");
+
+	/* Set up vertex array object */
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+
+	/* Set up vertex input buffer */
+	glGenBuffers(1, &vertex_buf);
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(pos_line), pos_line,
+		     GL_STATIC_DRAW);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, ARRAY_SIZE(pos_line[0]), GL_FLOAT,
+			      GL_FALSE, sizeof(pos_line[0]), (void *) 0);
+}
+
+void Lines::draw(float (*proj)[4])
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glBindVertexArray(vao);
+	for (int line_num = 0; line_num < num_lines; ++line_num) {
+		glLineWidth(1 + line_num / 4);
+		glUniform1i(line_num_loc, line_num);
+		glDrawArrays(GL_LINES, 0, 2);
+	}
+}
+
+void Points::compile()
+{
+	/* Point coords within (-1,-1) to (1,1) rect */
+	static const float pos_point[2] = { -0.5, -0.5 };
+
+	/* Number of point instances across (and down) */
+	int points_across = 4;
+
+	/* Total number of points drawn */
+	num_points = points_across * points_across;
+
+	/* Scaling factor uniformly applied to point coords */
+	float point_scale = 0.8 / points_across;
+
+	/* Final scaling factor */
+	float final_scale = 0.95;
+
+	static const char *vert =
+		"#version 130\n"
+		"in vec2 pos_point;\n"
+		"uniform float point_scale;\n"
+		"uniform int points_across;\n"
+		"uniform float final_scale;\n"
+		"uniform mat4 proj;\n"
+		"uniform int point_num;\n"
+		"uniform float depth;\n"
+		"\n"
+		"void main()\n"
+		"{\n"
+		"  vec2 pos = point_scale * pos_point;\n"
+		"  int i = point_num % points_across;\n"
+		"  int j = points_across - 1 - point_num / points_across;\n"
+		"  pos += (vec2(i, j) * 2.0 + 1.0) / points_across - 1.0;\n"
+		"  pos *= final_scale;\n"
+		"  gl_Position = proj * vec4(pos, depth, 1.0);\n"
+		"}\n";
+
+	static const char *frag =
+		"#version 130\n"
+		"void main()\n"
+		"{\n"
+		"  gl_FragColor = vec4(1.0);\n"
+		"}\n";
+
+	/* Compile program */
+	prog = glCreateProgram();
+	GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	glAttachShader(prog, vs);
+	GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	glAttachShader(prog, fs);
+	glBindAttribLocation(prog, 0, "pos_point");
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog)) {
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	/* Set up uniforms */
+	glUseProgram(prog);
+	glUniform1f(glGetUniformLocation(prog, "point_scale"), point_scale);
+	glUniform1i(glGetUniformLocation(prog, "points_across"), points_across);
+	glUniform1f(glGetUniformLocation(prog, "final_scale"), final_scale);
+	proj_loc = glGetUniformLocation(prog, "proj");
+	point_num_loc = glGetUniformLocation(prog, "point_num");
+	depth_loc = glGetUniformLocation(prog, "depth");
+
+	/* Set up vertex array object */
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+
+	/* Set up vertex input buffer */
+	glGenBuffers(1, &vertex_buf);
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(pos_point), pos_point,
+		     GL_STATIC_DRAW);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, ARRAY_SIZE(pos_point), GL_FLOAT,
+			      GL_FALSE, 0, (void *) 0);
+}
+
+void Points::draw(float (*proj)[4])
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glBindVertexArray(vao);
+	glUniform1f(depth_loc, 0.0);
+	for (int point_num = 0; point_num < num_points; ++point_num) {
+		glPointSize(2 + point_num);
+		glUniform1i(point_num_loc, point_num);
+		glDrawArrays(GL_POINTS, 0, 1);
+	}
+}
+
+void Spiral::compile()
+{
+	/* Point coords within (-1,-1) to (1,1) rect */
+	static const float pos_point[2] = { 0.7, 0.7 };
+
+	num_points = 15;
+	num_circles = 3;
+
+	static const char *vert =
+		"#version 130\n"
+		"in vec2 pos_point;\n"
+		"uniform float rotation;\n"
+		"uniform float length;\n"
+		"uniform float depth;\n"
+		"uniform mat4 proj;\n"
+		"\n"
+		"void main()\n"
+		"{\n"
+		"  vec2 pos = pos_point * length;\n"
+		"  pos = mat2(cos(rotation), sin(rotation),\n"
+		"             -sin(rotation), cos(rotation)) * pos;\n"
+		"  gl_Position = proj * vec4(pos, depth, 1.0);\n"
+		"}\n";
+
+	static const char *frag =
+		"#version 130\n"
+		"void main()\n"
+		"{\n"
+		"  gl_FragColor = vec4(0.0);\n"
+		"}\n";
+
+	/* Compile program */
+	prog = glCreateProgram();
+	GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	glAttachShader(prog, vs);
+	GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	glAttachShader(prog, fs);
+	glBindAttribLocation(prog, 0, "pos_point");
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog)) {
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	/* Set up uniforms */
+	glUseProgram(prog);
+	rotation_loc = glGetUniformLocation(prog, "rotation");
+	length_loc = glGetUniformLocation(prog, "length");
+	depth_loc = glGetUniformLocation(prog, "depth");
+	glUniform1f(depth_loc, 0.0);
+	proj_loc = glGetUniformLocation(prog, "proj");
+
+	/* Set up vertex array object */
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+
+	/* Set up vertex input buffer */
+	glGenBuffers(1, &vertex_buf);
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(pos_point), pos_point,
+		     GL_STATIC_DRAW);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, ARRAY_SIZE(pos_point), GL_FLOAT,
+			      GL_FALSE, 0, (void *) 0);
+}
+
+void
+StencilSpiral::draw(float (*proj)[4])
+{
+	glEnable(GL_STENCIL_TEST);
+	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glUniform1f(depth_loc, 0.0);
+	glBindVertexArray(vao);
+
+	/* Total number of points drawn */
+	int total_points = num_circles * num_points;
+
+	for (int i = 0; i < total_points; ++i) {
+		/* Set the stencil value of point between 0 - 7 */
+		glStencilFunc(GL_ALWAYS, i % 8, 0xff);
+		glPointSize(1 + 2 * ((total_points - i) / num_circles ));
+
+		glUniform1f(length_loc, (1.0 - i * 1.0 / total_points));
+		glUniform1f(rotation_loc, M_PI * 2.0 * i / (num_points));
+
+		glDrawArrays(GL_POINTS, 0, 1);
+	}
+
+	glDisable(GL_STENCIL_TEST);
+}
+
+void
+DepthSpiral::draw(float (*proj)[4])
+{
+	glEnable(GL_DEPTH_TEST);
+	glDepthFunc(GL_LESS);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glBindVertexArray(vao);
+
+	/* Total number of points drawn */
+	int total_points = num_circles * num_points;
+
+	for (int i = 0; i < total_points; ++i) {
+		glPointSize(1 + 2 * ((total_points - i) / num_circles ));
+
+		/* Draw points in a haphazard order so we can verify that
+		 * depth comparisons sort them out properly.
+		 */
+		int point_to_draw = (i * 10) % total_points;
+
+		glUniform1f(length_loc, (1.0 - i * 1.0 / total_points));
+
+		/* Draw points in a depth range of -1 to +1 */
+		float depth = float(total_points - point_to_draw * 2 - 1)
+			      / (total_points + 1);
+		glUniform1f(depth_loc, depth);
+		glUniform1f(rotation_loc, M_PI * 2.0 * i / num_points);
+
+		glDrawArrays(GL_POINTS, 0, 1);
+	}
+
+	glDisable(GL_DEPTH_TEST);
+}
+
+void Star::compile()
+{
+	/* Triangle coords within (-1,-1) to (1,1) rect */
+	static const float pos_line[][2] = {
+		{ -0.3, -0.8 },
+		{  0.3,  0.8 }
+	};
+
+	/* Total number of lines drawn */
+	num_lines = 7;
+
+	static const char *vert =
+		"#version 130\n"
+		"in vec2 pos_line;\n"
+		"uniform float rotation;\n"
+		"uniform float depth;\n"
+		"uniform mat4 proj;\n"
+		"\n"
+		"void main()\n"
+		"{\n"
+		"  vec2 pos = pos_line;\n"
+		"  pos = mat2(cos(rotation), sin(rotation),\n"
+		"             -sin(rotation), cos(rotation)) * pos;\n"
+		"  gl_Position = proj * vec4(pos, depth, 1.0);\n"
+		"}\n";
+
+	static const char *frag =
+		"#version 130\n"
+		"void main()\n"
+		"{\n"
+		"  gl_FragColor = vec4(0.0);\n"
+		"}\n";
+
+	/* Compile program */
+	prog = glCreateProgram();
+	GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	glAttachShader(prog, vs);
+	GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	glAttachShader(prog, fs);
+	glBindAttribLocation(prog, 0, "pos_line");
+	glLinkProgram(prog);
+	if (!piglit_link_check_status(prog)) {
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	/* Set up uniforms */
+	glUseProgram(prog);
+	rotation_loc = glGetUniformLocation(prog, "rotation");
+	depth_loc = glGetUniformLocation(prog, "depth");
+	glUniform1f(depth_loc, 0.0);
+	proj_loc = glGetUniformLocation(prog, "proj");
+
+	/* Set up vertex array object */
+	glGenVertexArrays(1, &vao);
+	glBindVertexArray(vao);
+
+	/* Set up vertex input buffer */
+	glGenBuffers(1, &vertex_buf);
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(pos_line), pos_line,
+		     GL_STATIC_DRAW);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, ARRAY_SIZE(pos_line[0]), GL_FLOAT,
+			      GL_FALSE, sizeof(pos_line[0]), (void *) 0);
+}
+
+void
+StencilStar::draw(float (*proj)[4])
+{
+	glEnable(GL_STENCIL_TEST);
+	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glBindVertexArray(vao);
+	for (int i = 0; i < num_lines; ++i) {
+		glStencilFunc(GL_ALWAYS, i+1, 0xff);
+		glUniform1f(rotation_loc, M_PI * 2.0 * i / num_lines);
+		glDrawArrays(GL_LINES, 0, 2);
+	}
+
+	glDisable(GL_STENCIL_TEST);
+}
+
+void
+DepthStar::draw(float (*proj)[4])
+{
+	glEnable(GL_DEPTH_TEST);
+	glDepthFunc(GL_LESS);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	glUseProgram(prog);
+	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, &proj[0][0]);
+	glBindVertexArray(vao);
+	for (int i = 0; i < num_lines; ++i) {
+		/* Draw lines in a haphazard order so we can verify
+		 * that depth comparisons sort them out properly.
+		 */
+		int line_to_draw = (i * 3) % num_lines;
+
+		/* Note: with num_lines == 7, this causes us to draw
+		 * lines at depths of 3/4, 1/2, -1/4, 0, 1/4, 1/2,
+		 * and 3/4.
+		 */
+		glUniform1f(depth_loc,
+			    float(num_lines - line_to_draw * 2 - 1)
+			    / (num_lines + 1));
+
+		glUniform1f(rotation_loc,
+			    M_PI * 2.0 * line_to_draw / num_lines);
+		glDrawArrays(GL_LINES, 0, 2);
+	}
+
+	glDisable(GL_DEPTH_TEST);
+}
+
 void Sunburst::compile()
 {
 	/* Triangle coords within (-1,-1) to (1,1) rect */
diff --git a/tests/spec/ext_framebuffer_multisample/common.h b/tests/spec/ext_framebuffer_multisample/common.h
index d86cb95..1bb39b4 100644
--- a/tests/spec/ext_framebuffer_multisample/common.h
+++ b/tests/spec/ext_framebuffer_multisample/common.h
@@ -115,6 +115,7 @@ public:
 
 private:
 	GLint prog;
+	GLint count;
 	GLint color_loc;
 	GLuint vertex_buf;
 	GLuint vao;
@@ -187,6 +188,157 @@ private:
 };
 
 /**
+ * Program we use to draw a test pattern into the color buffer.
+ *
+ * This program draws a sequence of points with varied sizes. This ensures
+ * antialiasing works well with all point sizes.
+ */
+class Points : public TestPattern
+{
+public:
+	virtual void compile();
+	virtual void draw(float (*proj)[4]);
+
+private:
+	GLint prog;
+	GLuint vao;
+	GLint proj_loc;
+	GLint depth_loc;
+	GLint point_num_loc;
+	GLuint vertex_buf;
+	int num_points;
+};
+
+/**
+ * Program we use to draw a test pattern into the depth and stencil
+ * buffers.
+ *
+ * This program draws a "spiral" pattern consisting of 45 points,
+ * each with a different size.
+ * This program is further specialized into depth and stencil variants.
+ */
+class Spiral : public TestPattern
+{
+public:
+	virtual void compile();
+
+protected:
+	GLint prog;
+	GLint rotation_loc;
+	GLint depth_loc;
+	GLint length_loc;
+	GLint proj_loc;
+	GLuint vao;
+	int num_points;
+	int num_circles;
+
+private:
+	GLuint vertex_buf;
+};
+
+/**
+ * Program we use to draw a test pattern into the stencil buffer.
+ *
+ * The points in this spiral are drawn back-to-front, using no
+ * depth testing.  Each point is drawn using a stencil
+ * value between 0 to 7.
+ */
+class StencilSpiral : public Spiral
+{
+public:
+	virtual void draw(float (*proj)[4]);
+};
+
+/**
+ * Program we use to draw a test pattern into the depth buffer.
+ *
+ * The points in this spiral are drawn at a series of different
+ * depth values, with depth testing enabled.  They are drawn in an
+ * arbitrary non-consecutive order, to verify that depth testing
+ * properly sorts the surfaces into front-to-back order.
+ */
+class DepthSpiral : public Spiral
+{
+public:
+	virtual void draw(float (*proj)[4]);
+};
+
+/**
+ * Program we use to draw a test pattern into the color buffer.
+ *
+ * This program draws a sequence of lines with varied width. This ensures
+ * antialiasing works well with all line widths.
+ */
+class Lines : public TestPattern
+{
+public:
+	virtual void compile();
+	virtual void draw(float (*proj)[4]);
+
+private:
+	GLint prog;
+	GLuint vao;
+	GLint proj_loc;
+	GLint line_num_loc;
+	GLuint vertex_buf;
+	int num_lines;
+};
+
+/**
+ * Program we use to draw a test pattern into the depth and stencil
+ * buffers.
+ *
+ * This program draws a "star" pattern consisting of 7 overlapping
+ * lines, each at a different angle.  This ensures that we'll thoroughly
+ * exercise antialiasing.
+ *
+ * This program is further specialized into depth and stencil variants.
+ */
+class Star : public TestPattern
+{
+public:
+	virtual void compile();
+
+protected:
+	GLint prog;
+	GLint rotation_loc;
+	GLint depth_loc;
+	GLint proj_loc;
+	GLuint vao;
+	int num_lines;
+
+private:
+	GLuint vertex_buf;
+};
+
+/**
+ * Program we use to draw a test pattern into the stencil buffer.
+ *
+ * The lines in this star are drawn back-to-front, using no
+ * depth testing.  Each line is drawn using a different stencil
+ * value.
+ */
+class StencilStar : public Star
+{
+public:
+	virtual void draw(float (*proj)[4]);
+};
+
+/**
+ * Program we use to draw a test pattern into the depth buffer.
+ *
+ * The lines in this star are drawn at a series of different
+ * depth values, with depth testing enabled.  They are drawn in an
+ * arbitrary non-consecutive order, to verify that depth testing
+ * properly sorts the lines into front-to-back order.
+ */
+class DepthStar : public Star
+{
+public:
+	virtual void draw(float (*proj)[4]);
+};
+
+/**
  * Program we use to draw a test pattern into the depth and stencil
  * buffers.
  *
-- 
1.7.7.6



More information about the Piglit mailing list