| // Copyright 2023 The Dawn Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| #include "Renderer.h" // NOLINT |
| #include "dawn/common/Log.h" |
| |
| void Renderer::Init() { |
| device = CreateCppDawnDeviceForAndroid(androidDesc); |
| queue = device.GetQueue(); |
| swapChain = GetSwapChain(); |
| const char shaderSource[] = R"( |
| @vertex fn vertexMain(@builtin(vertex_index) i : u32) -> |
| @builtin(position) vec4f { |
| const pos = array(vec2f(-0.5, -0.5), vec2f(0.5, -0.5), vec2f(0.0, 0.5)); |
| return vec4f(pos[i], 0, 1); |
| } |
| @fragment fn fragmentMain() -> @location(0) vec4f { |
| return vec4f(0.0, 0.4, 1.0, 1.0); |
| } |
| )"; |
| |
| wgpu::ShaderModuleWGSLDescriptor shaderCodeDesc; |
| shaderCodeDesc.code = shaderSource; |
| wgpu::ShaderModuleDescriptor shaderDesc; |
| shaderDesc.nextInChain = &shaderCodeDesc; |
| wgpu::ShaderModule shaderModule = device.CreateShaderModule(&shaderDesc); |
| wgpu::RenderPipelineDescriptor pipelineDesc; |
| |
| // Vertex shader |
| pipelineDesc.vertex.module = shaderModule; |
| pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList; |
| |
| // Fragment shader |
| wgpu::FragmentState fragmentState; |
| pipelineDesc.fragment = &fragmentState; |
| fragmentState.module = shaderModule; |
| |
| |
| wgpu::ColorTargetState colorTarget; |
| colorTarget.format = GetPreferredSwapChainTextureFormat(); |
| |
| fragmentState.targetCount = 1; |
| fragmentState.targets = &colorTarget; |
| pipeline = device.CreateRenderPipeline(&pipelineDesc); |
| } |
| |
| void Renderer::Frame() { |
| wgpu::TextureView nextTexture = swapChain.GetCurrentTextureView(); |
| wgpu::RenderPassColorAttachment renderPassColorAttachment; |
| renderPassColorAttachment.view = nextTexture; |
| renderPassColorAttachment.loadOp = wgpu::LoadOp::Clear; |
| renderPassColorAttachment.storeOp = wgpu::StoreOp::Store; |
| renderPassColorAttachment.clearValue = wgpu::Color{0.9, 0.1, 0.2, 1.0}; |
| |
| wgpu::RenderPassDescriptor renderPassDesc; |
| renderPassDesc.colorAttachmentCount = 1; |
| renderPassDesc.colorAttachments = &renderPassColorAttachment; |
| |
| wgpu::CommandEncoderDescriptor commandEncoderDesc; |
| commandEncoderDesc.label = "Command Encoder"; |
| wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&commandEncoderDesc); |
| wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDesc); |
| |
| renderPass.SetPipeline(pipeline); |
| renderPass.Draw(3); |
| renderPass.End(); |
| |
| wgpu::CommandBuffer commands = encoder.Finish(); |
| |
| device.GetQueue().Submit(1, &commands); |
| swapChain.Present(); |
| } |
| |
| void Renderer::GameLoop() { |
| if (!deviceInitialised) { |
| Init(); |
| deviceInitialised = true; |
| } |
| Frame(); |
| } |