check_tex

#coding=UTF-8

import checkingBoxBase as cbb
from maya.cmds import *
import maya.mel as mm

reload(cbb)
“”"
class checkingBoxCmd(cbb.checkingBoxCmd):
pass
“”"
class checkingBoxUI(cbb.checkingBoxUI):
title = 'Checking Box - Tex ’
win_height = 620
def updateList(self, *args):
cbb.checkingBoxUI.updateList(self,*args)
#checking1()
CheckObjectKFrame()
texFileCheck()
clearRedundantShapes()
clearUnusedNodes()
clearLightLinkers()
cheakHypershade()
checkFaceShade()
delHistory()
checkAxis()
checkSameObjs()
nameShapes()
checkUVSets()
checkNormals()
clearUnknownNode()
removeOpenedWindow()

Cmds ========================================

class checking1(cbb.checkingBoxCmd):
label = u’checking1’
def cmd(self):
#self.cont = ‘’
print ‘checking1’
self.cont += u’Finish’
return 1
def showInfo(self):
cbb.checkingBoxCmd.showInfo(self)
text(al=‘left’,l=‘other info’)
class CheckObjectKFrame(cbb.checkingBoxCmd):
label = u’检查所有大纲物体有没有K帧’
def cmd(self):
try:
sel = cmds.ls(type=“transform”)
self.l = []
for i in sel:
key = cmds.keyframe( i, query=True, keyframeCount=True )
if key == 0:
pass
else:
self.l.append(i)
if len(self.l) == 0:
self.cont = u’检查完成,没有K帧。’
return 1
else:
self.showInfo()
return 0
except:
self.cont = u’检查完成,有K帧。’
return 0
def showInfo(self):
cbb.checkingBoxCmd.showInfo(self)
setParent(self.infoUI)
columnLayout(adj=1)
iconTextButton(l=u"有K帧的物体名:",h=18,style=‘iconAndTextHorizontal’,bgc=[0.8,0.8,0.8])
# setParent(’…’)
# setParent(’…’)
for obj in self.l:
columnLayout(adj=1)
#iconTextButton(l=u"有K帧的物体名:",h=18,style=‘iconAndTextHorizontal’,bgc=[0.8,0.8,0.8])
columnLayout(adj=1,co=(‘left’,20))
iconTextButton(l=obj,h=18,style=‘iconAndTextHorizontal’,
c=‘from maya.cmds import *;select("%s")’%obj)
setParent(’…’)
setParent(’…’)
class clearLightLinkers(cbb.checkingBoxCmd):
label = u’清理灯光链接’
def cmd(self):
try:
mm.eval(“jrLightLinksCleanUp”)
self.cont = u’清理完成。’
return 1
except:
self.cont = u’清理失败。’
return 0
class removeOpenedWindow(cbb.checkingBoxCmd):
label = u’关闭多余窗口,并线框显示’
def cmd(self):
try:
from scripts.general import remove_opened_windows
remove_opened_windows.main()
import scripts.general.panel as panel
panel.Panel().set_outliner_persp()
except Exception:
self.cont = u’清理失败。’
return 0
else:
self.cont = u’清理完成。’
return 1
class clearUnknownNode(cbb.checkingBoxCmd):
label = u’清理无法识别的节点’
def cmd(self):
try:
from scripts.general import delete_unknown_node
delete_unknown_node.main()
self.cont = u’清理完成。’
return 1
except:
self.cont = u’清理失败。’
return 0
class checkSameObjs(cbb.checkingBoxCmd):
label = u’检查同名的物体’
def cmd(self):
import checkSameName
reload(checkSameName)
ins = checkSameName.checkSameName()
ins.check()
if ins.list=={}:
return 1
else:
self.cont = u’点击下列物体名称进行选择’
return 0
def showInfo(self):
cbb.checkingBoxCmd.showInfo(self)
import checkSameName
ins = checkSameName.checkSameName()
ins.check()
ins.showUI(self.infoUI)
class checkNormals(cbb.checkingBoxCmd):
label = u’检查法线’
def cmd(self):
mm.eval(‘setNamedPanelLayout “Single Perspective View”’)
modelEditor(‘modelPanel4’,e=1,twoSidedLighting=0,udm=1)
setFocus(‘modelPanel4’)
mm.eval(‘DisplayShaded’)
self.cont = u’单视图显示\n’
self.cont += u’单个默认灯光\n’
self.cont += u’使用默认材质显示\n’
self.cont += u’实体显示\n’
self.cont += u’\n请检查各物体的法线…\n’
return .5
class checkUVSets(cbb.checkingBoxCmd):
label = u’检查UV’
def cmd(self):
cont = u’’
objs = ls(type=‘mesh’)
for obj in objs:
auv = polyUVSet(obj, q=1, auv=1)
if len(auv)>1:
cont += u’%s存在多个UVSet:\n’%obj
for uv in auv:
cont += ‘%s,’%uv
cont += ‘\n’
cuv = polyUVSet(obj,q=1, cuv=1)
if cuv!= ‘map1’:
cont += u’当前UV:%s\n’%cuv
if cont != ‘’:
self.cont = cont
return 0
else:
self.cont = u’所有物体UVSet正常!\n’
self.cont += u’请检查UV是否有重叠和扭曲的情况…\n’
return .5
class clearUnusedNodes(cbb.checkingBoxCmd):
label = u’清理无用的节点,相机,灯光,层,mentalray,海龟节点等’
def cmd(self):
self.cont = ‘’
# Get nodes
cams = mm.eval(‘listTransforms -cameras’)
cmds.select(“defaultLightSet”,hi=True)
lits = ls(sl=True,type=‘transform’)
select(cl=True)
nodes = ls(type=[‘displayLayer’,‘renderLayer’])
try:
nodes.extend(ls(type=‘mentalraySubdivApprox’)) # For mental ray
except:
pass
tbl = [“TurtleRenderOptions”,“TurtleUIOptions”,“TurtleBakeLayerManager”,“TurtleDefaultBakeLayer”]
# Del nodes
self.cont += self.delNodes(cams) # del cameras
self.cont += self.delNodes(lits) # del lights
self.cont += self.delNodes(nodes) # del other nodes
self.delNodes(tbl)
try:
mm.eval(‘MLdeleteUnused’) # del shaders
except:
self.cont += ‘Unused Shader Node\n’
# Result
list = u’清理列表:\n’
list += ‘camera\nlight\ndisplayLayer\nrenderLayer\nmentalraySubdivApprox\nUnused Shader Node\n’
list += ‘\n’
if self.cont==’’:
self.cont = list + u’已完全清理!’
return 1
else:
self.cont = list + u’下列节点清理失败,可能是参考灯光,手动清理:\n’ + self.cont
return 0
def delNodes(self,nodes):
defaultNodes = [‘top’,‘side’,‘front’,‘persp’,‘defaultLayer’,‘defaultRenderLayer’,‘defaultObjectSet’]
act = ‘’
for node in nodes:
if node not in defaultNodes:
try:
delete( node )
except:
act = node + ‘\n’
return act
class cheakHypershade(cbb.checkingBoxCmd):
label = u’清理材质编辑器无用节点’
def cmd(self):
mm.eval(‘hyperShadePanelMenuCommand(“hyperShadePanel1”, “deleteUnusedNodes”);’)
self.cont = u’清理完成。’
return 1
class nameShapes(cbb.checkingBoxCmd):
label = u’shape名称与transform名称一致’
def cmd(self):
self.cont = ‘’
do = ‘’
notdo = ‘’
nodes = ls(type=‘transform’)
for node in nodes:
shapes = listRelatives(node,s=1,f=1,type=(‘mesh’,‘nurbsSurface’))
if shapes!=None:
shape = shapes[0]
name = node.rsplit(’|’,1)[-1] + ‘Shape’
if not shape.endswith(name):
try:
rename(shape,name)
do += ‘%s %s\n’%(shape,name)
except:
notdo += ‘%s\n’%shape
if not do==’’:
self.cont += u’重命名物体:\n’
self.cont += do
if not notdo==’’:
self.cont += u’重命名失败:\n’
self.cont += notdo
if self.cont==’’:
self.cont += u’所有shape名称都与transform名称一致!’
return 1
elif notdo==’’:
return 1
else:
return 0
class clearRedundantShapes(cbb.checkingBoxCmd):
label = u’清除多余的shape节点’
def cmd(self):
count = 0
nodes = ls(type=‘transform’)
for node in nodes:
shapes = listRelatives(node,s=1,f=1,ni=1)
if shapes!=None and len(shapes)>1:
shapes.pop(0)
delete(shapes)
count += 1
self.cont = u’处理多余的shape节点: %s\n\n’%count
self.cont += u’注:\n不处理中介节点’
return 1
class delHistory(cbb.checkingBoxCmd):
label = u’删除历史’
def cmd(self):
self.cont = self.zeroSmooth()
self.cont += self.unlockNormal()
self.cont += self.delHistory()
if self.cont==’’:
self.cont = u’场景中无模型物体!!!’
return 1
def delHistory(self):
cont = ‘’
nodes = ls(type=(‘mesh’,‘nurbsSurface’))
if nodes!=[]:
delete(nodes,ch=1)
cont = u’删除历史:%s\n’%len(nodes)
return cont
def unlockNormal(self):
cont = ‘’
nodes = ls(type=(‘mesh’,‘nurbsSurface’))
if nodes!=[]:
polyNormalPerVertex(nodes, ufn=1)
cont = u’Unlock Normal 节点: %s\n’%len(nodes)
return cont
def zeroSmooth(self):
cont = ‘’
nodes = ls(type=‘polySmoothFace’)
for node in nodes:
setAttr((node+’.divisions’),0)
if nodes!=[]:
cont = u’处理smooth节点: %s\n’%len(nodes)
return cont
class checkAxis(cbb.checkingBoxCmd):
label = u’轴心点回物体中心,位移旋转缩放属性设为默认值’
def cmd(self):
error = ‘’
objs = ls(type=(‘mesh’,‘nurbsSurface’))
for obj in objs:
p = listRelatives(obj,p=1,f=1)[0]
xform(p,cp=1)
try:
makeIdentity(p,a=1,t=1,r=1,s=1,n=0)
except:
error += ‘%s\n’%p
if error!=’’:
self.cont = u’以下物体处理失败:\n’
self.cont += error
self.cont += u’物体属性被锁定或者被连接,\n请手动检查…’
return 0.5
self.cont = u’处理物体: %s\n’%len(objs)
return 1
class texFileCheck(cbb.checkingBoxCmd):
label = u’检查贴图路径’
def cmd(self):
selFile = ls(type=‘file’)
l = []
self.a = []
for sf in selFile:
texFilePath = getAttr("%s.fileTextureName"%sf).split(’/’)[0]
if texFilePath != ‘X:’:
self.a.append(sf)
l.append(texFilePath)
l = set(l)
l = list(l)
if len(l) == 1:
if l[0] == ‘X:’:
self.cont = u"贴图路径全部指认X盘"
return 1
else:
self.showInfo()
return 0
elif len(l) == 0:
self.cont = u"没有指认任何贴图"
return 0.5
else:
self.showInfo()
self.cont += u"检查并修改"
return 0
def showInfo(self):
cbb.checkingBoxCmd.showInfo(self)
setParent(self.infoUI)
columnLayout(adj=1)
iconTextButton(l=u"不是X盘路径的贴图路径来源于:",h=18,style=‘iconAndTextHorizontal’,bgc=[0.8,0.8,0.8])
# setParent(’…’)
# setParent(’…’)
for obj in self.a:
columnLayout(adj=1)
#iconTextButton(l=u"有K帧的物体名:",h=18,style=‘iconAndTextHorizontal’,bgc=[0.8,0.8,0.8])
columnLayout(adj=1,co=(‘left’,20))
iconTextButton(l=obj,h=18,style=‘iconAndTextHorizontal’,
c=‘from maya.cmds import *;select("%s")’%obj)
setParent(’…’)
setParent(’…’)

class checkFaceShade(cbb.checkingBoxCmd):
label = u’检查面材质,或模型有无材质’
def cmd(self):
self.l = []
try:
a = ls(type=(‘mesh’,‘nurbsSurface’))
g = pickWalk(a,d=“up”)
select(cl=True)
l = []
for i in g:
getSGs = listConnections(listRelatives(i, shapes=1, f=1)[0], destination=1, source=0, plugs=0, s=1, type=“shadingEngine”)
print getSGs
if len(getSGs) == 1:
pass
else:
self.l.append(i)
for ig in getSGs:
if ig == ‘initialShadingGroup’:
self.l.append(i)

        if len(self.l) == 0:
            self.cont = u"模型材质材质正确且无面材质。"
            return 1
        else:
            self.showInfo()
            return 0.5
    except:
        self.cont = u"错误。"
        return 0

def showInfo(self):
    cbb.checkingBoxCmd.showInfo(self)
    setParent(self.infoUI)
    columnLayout(adj=1)
    iconTextButton(l=u"有面材质的或lamber1材质物体名:",h=18,style='iconAndTextHorizontal',bgc=[0.8,0.8,0.8])
    # setParent('..')
    # setParent('..')
    for obj in self.l:
        columnLayout(adj=1)
        #iconTextButton(l=u"有K帧的物体名:",h=18,style='iconAndTextHorizontal',bgc=[0.8,0.8,0.8])
        columnLayout(adj=1,co=('left',20))
        iconTextButton(l=obj,h=18,style='iconAndTextHorizontal',
                       c='from maya.cmds import *;select("%s")'%obj)
        setParent('..')
        setParent('..')

Main ------------------

def checkTex():
obj = checkingBoxUI(‘checkModel’)
obj.build()
obj.show()

#include <cstdlib> #include <dlfcn.h> #include "VulkanGraphics.h" #include "imgui_impl_vulkan.h" #include <vulkan/vulkan_android.h> #include <android/native_window.h> #include <unistd.h> #ifndef NDEBUG static void check_vk_result(VkResult err) { if (err == 0) return; fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); if (err < 0) abort(); } #else static void check_vk_result(VkResult err) { } #endif VkPhysicalDevice VulkanGraphics::SetupVulkan_SelectPhysicalDevice() { uint32_t gpu_count; VkResult err = vkEnumeratePhysicalDevices(m_Instance, &gpu_count, nullptr); check_vk_result(err); IM_ASSERT(gpu_count > 0); ImVector<VkPhysicalDevice> gpus; gpus.resize(gpu_count); err = vkEnumeratePhysicalDevices(m_Instance, &gpu_count, gpus.Data); check_vk_result(err); // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple // dedicated GPUs) is out of scope of this sample. for (VkPhysicalDevice &device: gpus) { VkPhysicalDeviceProperties properties; vkGetPhysicalDeviceProperties(device, &properties); if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) return device; } // Use first GPU (Integrated) is a Discrete one is not available. if (gpu_count > 0) return gpus[0]; return VK_NULL_HANDLE; } bool VulkanGraphics::Create(ANativeWindow *Window, int m_Width, int m_Height) { this->m_Window = Window; if (InitVulkan() != 1) { fprintf(stderr, "Vulkan is not supported %s\n", dlerror()); abort(); } wd = std::make_unique<ImGui_ImplVulkanH_Window>(); //为imgui加载vulkan函数 void *libvulkan = dlopen("libvulkan.so", RTLD_NOW); ImGui_ImplVulkan_LoadFunctions([](const char *function_name, void *handle) -> PFN_vkVoidFunction { return reinterpret_cast<PFN_vkVoidFunction>(dlsym(handle, function_name)); }, libvulkan); VkResult err; // Create Vulkan Instance { const char *instance_extensions[] = { "VK_KHR_surface", "VK_KHR_android_surface", }; VkApplicationInfo appInfo = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pNext = nullptr, .pApplicationName = "pApplicationName", .applicationVersion = VK_MAKE_VERSION(1, 0, 0), .pEngineName = "pEngineName", .engineVersion = VK_MAKE_VERSION(1, 0, 0), .apiVersion = VK_MAKE_VERSION(1, 1, 0), }; VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.pApplicationInfo = &appInfo; create_info.enabledExtensionCount = sizeof(instance_extensions) / sizeof(instance_extensions[0]); create_info.ppEnabledExtensionNames = instance_extensions; #ifdef IMGUI_VULKAN_DEBUG_REPORT // Enabling validation layers const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); extensions_ext[extensions_count] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count + 1; create_info.ppEnabledExtensionNames = extensions_ext; // Create Vulkan Instance err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); free(extensions_ext); // Get the function pointer (required for any extensions) auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); // Setup the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = NULL; err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #else // Create Vulkan Instance without any debug feature err = vkCreateInstance(&create_info, m_Allocator, &m_Instance); check_vk_result(err); IM_UNUSED(m_DebugReport); #endif } // Select Physical Device (GPU) m_PhysicalDevice = SetupVulkan_SelectPhysicalDevice(); // Select graphics queue family { uint32_t count; vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &count, nullptr); VkQueueFamilyProperties *queues = (VkQueueFamilyProperties *) malloc(sizeof(VkQueueFamilyProperties) * count); vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &count, queues); for (uint32_t i = 0; i < count; i++) if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { m_QueueFamily = i; break; } free(queues); IM_ASSERT(m_QueueFamily != (uint32_t) -1); } // Create Logical Device (with 1 queue) { ImVector<const char *> device_extensions; device_extensions.push_back("VK_KHR_swapchain"); // Enumerate physical device extension uint32_t properties_count; ImVector<VkExtensionProperties> properties; vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &properties_count, nullptr); properties.resize(properties_count); vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &properties_count, properties.Data); #ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); #endif const float queue_priority[] = {1.0f}; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = m_QueueFamily; queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = queue_priority; VkDeviceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); create_info.pQueueCreateInfos = queue_info; create_info.enabledExtensionCount = (uint32_t) device_extensions.Size; create_info.ppEnabledExtensionNames = device_extensions.Data; err = vkCreateDevice(m_PhysicalDevice, &create_info, m_Allocator, &m_Device); check_vk_result(err); vkGetDeviceQueue(m_Device, m_QueueFamily, 0, &m_Queue); } // Create Descriptor Pool { VkDescriptorPoolSize pool_sizes[] = { {VK_DESCRIPTOR_TYPE_SAMPLER, 1000}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000}, {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000}, {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000}, {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000}, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000}, {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000}, {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000} }; VkDescriptorPoolCreateInfo pool_info = {}; pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); pool_info.poolSizeCount = (uint32_t) IM_ARRAYSIZE(pool_sizes); pool_info.pPoolSizes = pool_sizes; err = vkCreateDescriptorPool(m_Device, &pool_info, m_Allocator, &m_DescriptorPool); check_vk_result(err); } { // Create Window Surface VkSurfaceKHR surface; VkAndroidSurfaceCreateInfoKHR createInfo{ .sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, .pNext = nullptr, .flags = 0, .window = m_Window}; err = vkCreateAndroidSurfaceKHR(m_Instance, &createInfo, m_Allocator, &surface); check_vk_result(err); wd->Surface = surface; // Check for WSI support VkBool32 res; vkGetPhysicalDeviceSurfaceSupportKHR(m_PhysicalDevice, m_QueueFamily, wd->Surface, &res); if (res != VK_TRUE) { fprintf(stderr, "Error no WSI support on physical device 0\n"); exit(-1); } // Select Surface Format const VkFormat requestSurfaceImageFormat[] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM}; const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(m_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t) IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); // 呈现模式 // 代码中已有逻辑,无需修改,只需确保不定义APP_USE_UNLIMITED_FRAME_RATE #ifndef APP_USE_UNLIMITED_FRAME_RATE VkPresentModeKHR present_modes[] = {VK_PRESENT_MODE_FIFO_KHR}; // 垂直同步模式 #endif wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(m_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); // Create SwapChain, RenderPass, Framebuffer, etc. IM_ASSERT(m_MinImageCount >= 2); // 在调用 ImGui_ImplVulkanH_CreateOrResizeWindow 前添加 m_MinImageCount = 2; // 双缓冲,或根据屏幕刷新率设置为3(三缓冲) ImGui_ImplVulkanH_CreateOrResizeWindow(m_Instance, m_PhysicalDevice, m_Device, wd.get(), m_QueueFamily, m_Allocator, (int) m_Width, (int) m_Height, m_MinImageCount); } return true; } void VulkanGraphics::Setup() { ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = m_Instance; init_info.PhysicalDevice = m_PhysicalDevice; init_info.Device = m_Device; init_info.QueueFamily = m_QueueFamily; init_info.Queue = m_Queue; init_info.PipelineCache = m_PipelineCache; init_info.DescriptorPool = m_DescriptorPool; init_info.RenderPass = wd->RenderPass; init_info.Subpass = 0; init_info.MinImageCount = m_MinImageCount; init_info.ImageCount = wd->ImageCount; init_info.MSAASamples = VK_SAMPLE_COUNT_2_BIT; init_info.Allocator = m_Allocator; init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info); } void VulkanGraphics::PrepareFrame(bool resize) { if (m_SwapChainRebuild || resize) { int width = ANativeWindow_getWidth(m_Window); int height = ANativeWindow_getHeight(m_Window); if (m_LastWidth == 0 || m_LastHeight == 0) { m_LastWidth = width; m_LastHeight = height; } if (width > 0 && height > 0) { if (width != m_LastWidth || height != m_LastHeight) { //切屏休息半秒 usleep(500000); m_LastWidth = width; m_LastHeight = height; ImGui_ImplVulkan_SetMinImageCount(m_MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(m_Instance, m_PhysicalDevice, m_Device, wd.get(), m_QueueFamily, m_Allocator, width, height, m_MinImageCount); wd->FrameIndex = 0; m_SwapChainRebuild = false; } } } ImGui_ImplVulkan_NewFrame(); } void VulkanGraphics::Render(ImDrawData *drawData) { VkResult err; VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; err = vkAcquireNextImageKHR(m_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); if (err == VK_ERROR_OUT_OF_DATE_KHR /*|| err == VK_SUBOPTIMAL_KHR*/) { m_SwapChainRebuild = true; return; } //check_vk_result(err); ImGui_ImplVulkanH_Frame *fd = &wd->Frames[wd->FrameIndex]; { err = vkWaitForFences(m_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking check_vk_result(err); err = vkResetFences(m_Device, 1, &fd->Fence); check_vk_result(err); } { err = vkResetCommandPool(m_Device, fd->CommandPool, 0); check_vk_result(err); VkCommandBufferBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(fd->CommandBuffer, &info); check_vk_result(err); } { //透明 默认已经是0了 //memset(wd->ClearValue.color.float32, 0, sizeof(wd->ClearValue.color.float32)); VkRenderPassBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.renderPass = wd->RenderPass; info.framebuffer = fd->Framebuffer; info.renderArea.extent.width = wd->Width; info.renderArea.extent.height = wd->Height; info.clearValueCount = 1; info.pClearValues = &wd->ClearValue; vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } // Record dear imgui primitives into command buffer ImGui_ImplVulkan_RenderDrawData(drawData, fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); { VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; info.waitSemaphoreCount = 1; info.pWaitSemaphores = &image_acquired_semaphore; info.pWaitDstStageMask = &wait_stage; info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; info.signalSemaphoreCount = 1; info.pSignalSemaphores = &render_complete_semaphore; err = vkEndCommandBuffer(fd->CommandBuffer); check_vk_result(err); err = vkQueueSubmit(m_Queue, 1, &info, fd->Fence); check_vk_result(err); } { if (m_SwapChainRebuild) return; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; VkPresentInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.waitSemaphoreCount = 1; info.pWaitSemaphores = &render_complete_semaphore; info.swapchainCount = 1; info.pSwapchains = &wd->Swapchain; info.pImageIndices = &wd->FrameIndex; VkResult err = vkQueuePresentKHR(m_Queue, &info); if (err == VK_ERROR_OUT_OF_DATE_KHR /*|| err == VK_SUBOPTIMAL_KHR*/) { m_SwapChainRebuild = true; return; } //check_vk_result(err); wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores } } void VulkanGraphics::PrepareShutdown() { VkResult err = vkDeviceWaitIdle(m_Device); check_vk_result(err); ImGui_ImplVulkan_Shutdown(); } //==========// void VulkanGraphics::Cleanup() { ImGui_ImplVulkanH_DestroyWindow(m_Instance, m_Device, wd.get(), m_Allocator); vkDestroyDescriptorPool(m_Device, m_DescriptorPool, m_Allocator); #ifdef APP_USE_VULKAN_DEBUG_REPORT // Remove the debug report callback auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // APP_USE_VULKAN_DEBUG_REPORT vkDestroyDevice(m_Device, m_Allocator); vkDestroyInstance(m_Instance, m_Allocator); } //清理释放 // Helper function to find Vulkan memory type bits. See ImGui_ImplVulkan_MemoryType() in imgui_impl_vulkan.cpp uint32_t VulkanGraphics::findMemoryType(uint32_t type_filter, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties mem_properties; vkGetPhysicalDeviceMemoryProperties(m_PhysicalDevice, &mem_properties); for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++) if ((type_filter & (1 << i)) && (mem_properties.memoryTypes[i].propertyFlags & properties) == properties) return i; return 0xFFFFFFFF; // Unable to find memoryType } BaseTexData *VulkanGraphics::LoadTexture(BaseTexData *tex, void *pixel_data) { auto *tex_data = new VulkanTextureData(); tex_data->Width = tex->Width; tex_data->Height = tex->Height; tex_data->Channels = tex->Channels; // tex_data->UserData= // Calculate allocation size (in number of bytes) size_t image_size = tex_data->Width * tex_data->Height * tex_data->Channels; VkResult err; // Create the Vulkan image. { VkImageCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; info.imageType = VK_IMAGE_TYPE_2D; info.format = VK_FORMAT_R8G8B8A8_UNORM; info.extent.width = tex_data->Width; info.extent.height = tex_data->Height; info.extent.depth = 1; info.mipLevels = 1; info.arrayLayers = 1; info.samples = VK_SAMPLE_COUNT_2_BIT; info.tiling = VK_IMAGE_TILING_OPTIMAL; info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; err = vkCreateImage(m_Device, &info, m_Allocator, &tex_data->Image); check_vk_result(err); VkMemoryRequirements req; vkGetImageMemoryRequirements(m_Device, tex_data->Image, &req); VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = req.size; alloc_info.memoryTypeIndex = findMemoryType(req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); err = vkAllocateMemory(m_Device, &alloc_info, m_Allocator, &tex_data->ImageMemory); check_vk_result(err); err = vkBindImageMemory(m_Device, tex_data->Image, tex_data->ImageMemory, 0); check_vk_result(err); } // Create the Image View { VkImageViewCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; info.image = tex_data->Image; info.viewType = VK_IMAGE_VIEW_TYPE_2D; info.format = VK_FORMAT_R8G8B8A8_UNORM; info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; info.subresourceRange.levelCount = 1; info.subresourceRange.layerCount = 1; err = vkCreateImageView(m_Device, &info, m_Allocator, &tex_data->ImageView); check_vk_result(err); } // Create Sampler { VkSamplerCreateInfo sampler_info{}; sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler_info.magFilter = VK_FILTER_LINEAR; sampler_info.minFilter = VK_FILTER_LINEAR; sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; // outside image bounds just use border color sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; sampler_info.minLod = -1000; sampler_info.maxLod = 1000; sampler_info.maxAnisotropy = 1.0f; err = vkCreateSampler(m_Device, &sampler_info, m_Allocator, &tex_data->Sampler); check_vk_result(err); } // Create Descriptor Set using ImGUI's implementation tex_data->DS = (void *) ImGui_ImplVulkan_AddTexture(tex_data->Sampler, tex_data->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); // Create Upload Buffer { VkBufferCreateInfo buffer_info = {}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = image_size; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; err = vkCreateBuffer(m_Device, &buffer_info, m_Allocator, &tex_data->UploadBuffer); check_vk_result(err); VkMemoryRequirements req; vkGetBufferMemoryRequirements(m_Device, tex_data->UploadBuffer, &req); VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = req.size; alloc_info.memoryTypeIndex = findMemoryType(req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); err = vkAllocateMemory(m_Device, &alloc_info, m_Allocator, &tex_data->UploadBufferMemory); check_vk_result(err); err = vkBindBufferMemory(m_Device, tex_data->UploadBuffer, tex_data->UploadBufferMemory, 0); check_vk_result(err); } // Upload to Buffer: { void *map = NULL; err = vkMapMemory(m_Device, tex_data->UploadBufferMemory, 0, image_size, 0, &map); check_vk_result(err); memcpy(map, pixel_data, image_size); VkMappedMemoryRange range[1] = {}; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].memory = tex_data->UploadBufferMemory; range[0].size = image_size; err = vkFlushMappedMemoryRanges(m_Device, 1, range); check_vk_result(err); vkUnmapMemory(m_Device, tex_data->UploadBufferMemory); } // Create a command buffer that will perform following steps when hit in the command queue. // TODO: this works in the example, but may need input if this is an acceptable way to access the pool/create the command buffer. VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; VkCommandBuffer command_buffer; { VkCommandBufferAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.commandPool = command_pool; alloc_info.commandBufferCount = 1; err = vkAllocateCommandBuffers(m_Device, &alloc_info, &command_buffer); check_vk_result(err); VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; err = vkBeginCommandBuffer(command_buffer, &begin_info); check_vk_result(err); } // Copy to Image { VkImageMemoryBarrier copy_barrier[1] = {}; copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; copy_barrier[0].image = tex_data->Image; copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy_barrier[0].subresourceRange.levelCount = 1; copy_barrier[0].subresourceRange.layerCount = 1; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier); VkBufferImageCopy region = {}; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.layerCount = 1; region.imageExtent.width = tex_data->Width; region.imageExtent.height = tex_data->Height; region.imageExtent.depth = 1; vkCmdCopyBufferToImage(command_buffer, tex_data->UploadBuffer, tex_data->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); VkImageMemoryBarrier use_barrier[1] = {}; use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; use_barrier[0].image = tex_data->Image; use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; use_barrier[0].subresourceRange.levelCount = 1; use_barrier[0].subresourceRange.layerCount = 1; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier); } // End command buffer { VkSubmitInfo end_info = {}; end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; end_info.commandBufferCount = 1; end_info.pCommandBuffers = &command_buffer; err = vkEndCommandBuffer(command_buffer); check_vk_result(err); err = vkQueueSubmit(m_Queue, 1, &end_info, VK_NULL_HANDLE); check_vk_result(err); err = vkDeviceWaitIdle(m_Device); check_vk_result(err); } return tex_data; } void VulkanGraphics::RemoveTexture(BaseTexData *tex) { auto *tex_data = (VulkanTextureData *) (tex); vkFreeMemory(m_Device, tex_data->UploadBufferMemory, nullptr); vkDestroyBuffer(m_Device, tex_data->UploadBuffer, nullptr); vkDestroySampler(m_Device, tex_data->Sampler, nullptr); vkDestroyImageView(m_Device, tex_data->ImageView, nullptr); vkDestroyImage(m_Device, tex_data->Image, nullptr); vkFreeMemory(m_Device, tex_data->ImageMemory, nullptr); ImGui_ImplVulkan_RemoveTexture((VkDescriptorSet) tex_data->DS); delete tex_data; } TextureInfo VulkanGraphics::ImAgeHeadFile(const unsigned char *buf, int len) { TextureInfo ret_data{0}; BaseTexData tex_data{}; tex_data.Channels = 4; //unsigned char *image_data = loadFunc(&tex_data); unsigned char *image_data = stbi_load_from_memory((const stbi_uc *) buf, len, &tex_data.Width, &tex_data.Height, nullptr, tex_data.Channels); if (image_data == nullptr) return ret_data; auto result = LoadTexture(&tex_data, image_data); stbi_image_free(image_data); ret_data.textureId = (ImTextureID)result->DS; ret_data.w = tex_data.Width; ret_data.h = tex_data.Height; return ret_data; } 怎么改成 3 合缓冲
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值