Vulkan开发实战详解 学习笔记 - 绘制方式,点绘制、线段绘制和三角形绘制

绘制方式,点绘制、线段绘制和三角形绘制

准备绘制的数据ObjectData.h ObjectData.cpp

#ifndef VULKANEXBASE_OBJECTDATA_H
#define VULKANEXBASE_OBJECTDATA_H

class ObjectData
{
public:
	static float* vdata;
	static int dataByteCount;
	static int vCount;
	static void  genVertexData();
};

#endif

ObjectData.cpp

#include <../main_task/ObjectData.h>
#include <vector>
#include <math.h>
#include <string.h>

float* ObjectData::vdata;
int ObjectData::dataByteCount;
int ObjectData::vCount;

void  ObjectData::genVertexData()
{
	vCount = 5;
	dataByteCount = vCount * 6 * sizeof(float);
	vdata = new float[vCount * 6]
	{
		0,0,0, /*坐标*/     1,1,0, /*颜色*/
		60,60,0,    1,1,1,
		-60,60,0,   0,1,0,
		-60,-60,0,  1,1,1,
		50,-60,0,   1,1,0
	};
}

MyVulkanManager.h下面添加绘制方式的变量

	//绘制用对象
	static DrawableObjectCommon* objectForDraw;
	static int topologyWay;//绘制方式

MyVulkanManager.cpp下初始化

int  MyVulkanManager::topologyWay = 0;

void MyVulkanManager::create_vulkan_devices()下添加

VkPhysicalDeviceFeatures pdf; //存储设备所支持特性的结构体实例 
vkGetPhysicalDeviceFeatures(gpus[0], &pdf);			//获取指定设备支持的特性
if (pdf.wideLines == VK_TRUE)						//判断是否支持wideLines特性
{
    printf("支持wideLines特性!\n");
}						//打印调试信息
else { printf("不支持wideLines特性!\n"); }

//获取后给deviceInfo.pEnabledFeatures传入获取的参数
deviceInfo.pEnabledFeatures = &pdf;//启用的设备特性

重新初始化摄像头参数和setProjectFrustum

void MyVulkanManager::initMatrix()
{
	MatrixState3D::setCamera(0, 0, 200, 0, 0, 0, 0, 1, 0);
	MatrixState3D::setInitStack();
	float ratio = (float)screenWidth / (float)screenHeight;
	MatrixState3D::setProjectFrustum(-ratio, ratio, -1, 1, 1.5f, 1000);
}

修改

ShaderQueueSuit_Common.h

添加公有成员

/*绘制方式总数*/
	static const int topologyCount = 3;

修改pipeline为一个数组

	//管线
	VkPipeline pipeline[topologyCount];

修改

ShaderQueueSuit_Common.cpp

	VkPipelineInputAssemblyStateCreateInfo ia;//管线图元组装状态创建信息
	ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
	ia.pNext = NULL;//自定义数据的指针
	ia.flags = 0;//供将来使用的标志
	ia.primitiveRestartEnable = VK_FALSE;//关闭图元重启
	ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;	//采用三角形图元列表模式
	//声明了一个长度为topologyCount的管线图元组装状态创建信息结构体实例数组,topologyCount的值为3,对应本案例中的3种绘制方式。
	VkPipelineInputAssemblyStateCreateInfo ia[topologyCount];	//管线图元组装状态创建信息数组
	//遍历了前面声明的数组中的每个元素,对各个元素的属性进行设置。最主要的是根据元素索引的不同,设置了不同的绘制方式(即图元组装方式)
	for (int i = 0; i < topologyCount; ++i) 
    {						//遍历数组中每个元素进行初始化
		ia[i].sType = 										//指定结构体类型
			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
		ia[i].pNext = NULL;									//自定义数据的指针
		ia[i].flags = 0;										//供将来使用的标志位
		ia[i].primitiveRestartEnable = VK_FALSE;					//关闭图元重启
		switch (i) {								//数组中的每个元素设置不同的图元组装方式
		case 0:ia[i].topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; break;	//点列表方式
		case 1:ia[i].topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; break;	//线段列表方式
		case 2:ia[i].topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; break;	//折线方式
		}
	}

删掉

	pipelineInfo.pInputAssemblyState = &ia;//管线的图元组装状态信息

函数结尾修改

	result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineInfo, NULL, &pipeline);
	assert(result == VK_SUCCESS);

	//创建了topologyCount个管线,每个管线对应一种绘制方式。同时将创建的管线依次存储在pipeline数组中,以备后面绘制时使用。
	for (int i = 0; i<topologyCount; i++) 
	{                                //为每种图元组装方式创建管线
		pipelineInfo.pInputAssemblyState = &ia[i];                    //指定管线的图元组装状态信息
		result = vkCreateGraphicsPipelines                    //创建管线
		(device, pipelineCache, 1, &pipelineInfo, NULL, &pipeline[i]);
		assert(result == VK_SUCCESS);                            //检查管线创建是否成功
	}

采用点、线段等绘制方式时,默认情况下点的大小仅有一个像素,线段的粗细也是一个像素。如果需要更大的点或更粗的线段,就需要修改点的大小、线段的粗细设置。首先介绍线段粗细的设置

rs.lineWidth = 15.0f;//线宽度(仅在线绘制模式起作用)

销毁管线

void ShaderQueueSuit_Common::destroy_pipe_line(VkDevice& device){	//销毁管线	for (int i = 0; i<topologyCount; i++)	{		vkDestroyPipeline(device, pipeline[i], NULL);	}	//销毁管线缓冲	vkDestroyPipelineCache(device, pipelineCache, NULL);}

接下来在

void MyVulkanManager::drawObject()中的

		MatrixState3D::pushMatrix();										//保护现场
		MatrixState3D::rotate(xAngle, 1, 0, 0);								//绕X轴旋转xAngle
		MatrixState3D::rotate(yAngle, 0, 1, 0);								//绕Y轴旋转yAngle
		MatrixState3D::pushMatrix();//保护现场
		objForDraw->drawSelf(cmdBuffer, sqsCL->pipelineLayout, sqsCL->pipeline,
			&(sqsCL->descSet[0]));//绘制第一个立方体
		MatrixState3D::popMatrix();//恢复现场
		MatrixState3D::pushMatrix();//保护现场
		MatrixState3D::translate(3.5f, 0, 0);//沿x方向平移3.5
		MatrixState3D::rotate(30, 0, 0, 1);							//绕z轴旋转30°
		MatrixState3D::scale(0.4f, 2.0f, 0.6f);					//x、y、z 3个方向按各自的缩放因子进行缩放

		objForDraw->drawSelf(cmdBuffer, sqsCL->pipelineLayout, sqsCL->pipeline,
			&(sqsCL->descSet[0]));//绘制变换后的立方体
		MatrixState3D::popMatrix();//恢复现场

改为

		vkCmdBeginRenderPass(cmdBuffer, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
		//添加
		objForDraw->drawSelf(cmdBuffer, sqsCL->pipelineLayout, sqsCL->pipeline[topologyWay], &(sqsCL->descSet[0]));
		vkCmdEndRenderPass(cmdBuffer);//结束渲染通道

修改void MyVulkanManager::createDrawableObject()

//创建绘制用物体
    ObjectData::genVertexData();
	//objForDraw = new DrawableObjectCommonLight(CubeData::vdata, CubeData::dataByteCount, CubeData::vCount, device, memoryroperties);
    objForDraw = new DrawableObjectCommonLight(ObjectData::vdata, ObjectData::dataByteCount, ObjectData::vCount, device, memoryroperties);

最后运行发现每有显示,查找代码原来是

void ShaderQueueSuit_Common::create_pipeline_layout(VkDevice& device)

创建管线中下列代码

const unsigned push_constant_range_count = 1;			//推送常量块数量
VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;	//指定结构体类型
push_constant_ranges[0].offset = 0;						//推送常量数据起始偏移量
push_constant_ranges[0].size = sizeof(float) * 16;			//推送常量数据字节总数

没有删掉

推送常量(push constants)不为空

在这里插入图片描述

添加单击屏幕切换

之前

		objForDraw->drawSelf(cmdBuffer, sqsCL->pipelineLayout, sqsCL->pipeline[topologyWay], &(sqsCL->descSet[0]));

中有一个topologyWay 标志

	case XCB_BUTTON_RELEASE:
	{
		xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event;
		print_modifiers(ev->state);
		switch (ev->detail)
		{
			case 3:
			if (isClick)
			{
                //添加3种绘制方式之间进行切换
				MyVulkanManager::topologyWay = (++MyVulkanManager::topologyWay%ShaderQueueSuit_Common::topologyCount);
			}
			isClick = true;
			mouseLeftDown = false;
			printf("mouseLeftDown\n");
			break;

		default:
			break;
		}
		break;
	}

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值