@@ -83,10 +83,18 @@ ColorPass::ColorPass(RenderContext &renderContext, const std::filesystem::path &
8383
8484 // Create sampler
8585 m_sampler = std::make_unique<Sampler>();
86- m_sampler->set (GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
86+ m_sampler->set (GL_TEXTURE_MIN_FILTER, GL_LINEAR );
8787 m_sampler->set (GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8888 m_sampler->set (GL_TEXTURE_WRAP_S, GL_REPEAT);
8989 m_sampler->set (GL_TEXTURE_WRAP_T, GL_REPEAT);
90+
91+ // Create default white texture for missing textures
92+ m_defaultTexture = std::make_unique<Texture>(GL_TEXTURE_2D);
93+ std::vector<unsigned char > white = {255 , 255 , 255 , 255 };
94+ m_defaultTexture->set_storage_2d (1 , GL_RGBA8, 1 , 1 );
95+ m_defaultTexture->set_sub_image_2d (0 , 0 , 0 , 1 , 1 , GL_RGBA, GL_UNSIGNED_BYTE, white.data ());
96+
97+ LOG_INFO (" ColorPass initialized successfully" );
9098}
9199
92100NodeId ColorPass::registerPass (
@@ -98,9 +106,6 @@ NodeId ColorPass::registerPass(
98106 Buffer *materialUBO,
99107 Buffer *lightingUBO) {
100108
101- NodeId colorOutput;
102- NodeId depthOutput;
103-
104109 auto &passData = fg.create_pass <Data>(
105110 " ColorPass" ,
106111 [&](FrameGraph::Builder &builder, Data &data) {
@@ -123,15 +128,11 @@ NodeId ColorPass::registerPass(
123128 // Mark as write targets
124129 builder.write (data.colorOutput );
125130 builder.write (data.depthOutput );
126-
127- // Capture NodeIds for execute phase
128- colorOutput = data.colorOutput ;
129- depthOutput = data.depthOutput ;
130131 },
131- [&](FrameGraphResources &resources, void *context) {
132+ [&](const Data &data, FrameGraphResources &resources, void *context) {
132133 // Get textures from frame graph
133- auto & colorTexture = fg.get <FrameGraphTexture>(colorOutput);
134- auto & depthTexture = fg.get <FrameGraphTexture>(depthOutput);
134+ auto * colorTexture = fg.get <FrameGraphTexture>(data. colorOutput ). getTexture ( );
135+ auto * depthTexture = fg.get <FrameGraphTexture>(data. depthOutput ). getTexture ( );
135136
136137 // Setup rendering info for FBO
137138 RenderingInfo renderingInfo;
@@ -140,14 +141,14 @@ NodeId ColorPass::registerPass(
140141
141142 // Setup color attachment
142143 renderingInfo.colorAttachments .emplace_back (
143- *colorTexture. getTexture () ,
144+ *colorTexture,
144145 AttachmentLoadOp::Clear,
145146 AttachmentStoreOp::Store,
146147 ClearValue::Color (0 .1f , 0 .1f , 0 .1f , 1 .0f ));
147148
148149 // Setup depth attachment
149150 renderingInfo.depthAttachment .emplace (
150- *depthTexture. getTexture () ,
151+ *depthTexture,
151152 AttachmentLoadOp::Clear,
152153 AttachmentStoreOp::Store,
153154 ClearValue::DepthStencil (1 .0f , 0 ));
@@ -161,71 +162,102 @@ NodeId ColorPass::registerPass(
161162 // Set viewport
162163 m_renderContext.setViewport (0 , 0 , size.x , size.y );
163164
165+ // Bind UBOs
166+ if (transformUBO) {
167+ m_renderContext.bindUniformBuffer (0 , *transformUBO, 0 , sizeof (TransformUBO));
168+ }
169+ if (lightingUBO) {
170+ m_renderContext.bindUniformBuffer (2 , *lightingUBO, 0 , sizeof (LightingUBO));
171+ }
172+
173+ LOG_INFO (" ColorPass: Rendering {} meshes" , meshDataList.size ());
174+
164175 // Render each mesh
165176 for (const auto &meshData : meshDataList) {
177+ if (meshData.index_count == 0 ) {
178+ LOG_WARN (" Skipping mesh with 0 indices" );
179+ continue ;
180+ }
181+
166182 m_renderContext.bindVertexBuffer (0 , meshData.position_buffer , 0 , sizeof (glm::vec3));
167183 m_renderContext.bindVertexBuffer (1 , meshData.normal_buffer , 0 , sizeof (glm::vec3));
168184 m_renderContext.bindVertexBuffer (2 , meshData.texcoord_buffer , 0 , sizeof (glm::vec2));
169185 m_renderContext.bindIndexBuffer (meshData.index_buffer , GL_UNSIGNED_INT);
170186
171187 // Update material UBO and bind textures
188+ MaterialUBO materialData;
189+ materialData.baseColorFactor = glm::vec4 (1 .0f );
190+ materialData.emissiveFactor = glm::vec3 (0 .0f );
191+ materialData.metallicFactor = 1 .0f ;
192+ materialData.roughnessFactor = 1 .0f ;
193+
172194 if (meshData.material ) {
173195 const auto &mat = meshData.material ;
174196 const auto &pbr = mat->pbr_metallic_roughness ;
175197
176- // Prepare material data
177- MaterialUBO materialData;
198+ // Update material data from actual material
178199 materialData.baseColorFactor = pbr.base_color_factor ;
179200 materialData.emissiveFactor = mat->emissive_factor ;
180201 materialData.metallicFactor = pbr.metallic_factor ;
181202 materialData.roughnessFactor = pbr.roughness_factor ;
203+ }
182204
183- // Update material UBO
184- if (materialUBO) {
185- materialUBO->set_sub_data (0 , sizeof (MaterialUBO), &materialData);
186- }
205+ // Update material UBO
206+ if (materialUBO) {
207+ materialUBO->set_sub_data (0 , sizeof (MaterialUBO), &materialData);
208+ m_renderContext.bindUniformBuffer (1 , *materialUBO, 0 , sizeof (MaterialUBO));
209+ }
210+
211+ // Bind textures with sampler - use default texture if not available
212+ if (meshData.material ) {
213+ const auto &mat = meshData.material ;
214+ const auto &pbr = mat->pbr_metallic_roughness ;
187215
188- // Bind textures with sampler
216+ // Bind textures with sampler - use default texture if not available
189217 // Base color (unit 0)
190- Texture *tex = nullptr ;
191218 if (pbr.base_color_texture && textureMap.count (pbr.base_color_texture )) {
192- tex = textureMap.at (pbr.base_color_texture );
193- m_renderContext.bindTexture (0 , *tex, *m_sampler);
219+ m_renderContext.bindTexture (0 , *textureMap.at (pbr.base_color_texture ), *m_sampler);
220+ } else {
221+ m_renderContext.bindTexture (0 , *m_defaultTexture, *m_sampler);
194222 }
195223
196224 // Metallic roughness (unit 1)
197- tex = nullptr ;
198225 if (pbr.metallic_roughness_texture && textureMap.count (pbr.metallic_roughness_texture )) {
199- tex = textureMap.at (pbr.metallic_roughness_texture );
200- m_renderContext.bindTexture (1 , *tex, *m_sampler);
226+ m_renderContext.bindTexture (1 , *textureMap.at (pbr.metallic_roughness_texture ), *m_sampler);
227+ } else {
228+ m_renderContext.bindTexture (1 , *m_defaultTexture, *m_sampler);
201229 }
202230
203231 // Normal (unit 2)
204- tex = nullptr ;
205232 if (mat->normal_texture && textureMap.count (mat->normal_texture )) {
206- tex = textureMap.at (mat->normal_texture );
207- m_renderContext.bindTexture (2 , *tex, *m_sampler);
233+ m_renderContext.bindTexture (2 , *textureMap.at (mat->normal_texture ), *m_sampler);
234+ } else {
235+ m_renderContext.bindTexture (2 , *m_defaultTexture, *m_sampler);
208236 }
209237
210238 // Emissive (unit 3)
211- tex = nullptr ;
212239 if (mat->emissive_texture && textureMap.count (mat->emissive_texture )) {
213- tex = textureMap.at (mat->emissive_texture );
214- m_renderContext.bindTexture (3 , *tex, *m_sampler);
240+ m_renderContext.bindTexture (3 , *textureMap.at (mat->emissive_texture ), *m_sampler);
241+ } else {
242+ m_renderContext.bindTexture (3 , *m_defaultTexture, *m_sampler);
215243 }
216244
217245 // Occlusion (unit 4)
218- tex = nullptr ;
219246 if (mat->occlusion_texture && textureMap.count (mat->occlusion_texture )) {
220- tex = textureMap.at (mat->occlusion_texture );
221- m_renderContext.bindTexture (4 , *tex, *m_sampler);
247+ m_renderContext.bindTexture (4 , *textureMap.at (mat->occlusion_texture ), *m_sampler);
248+ } else {
249+ m_renderContext.bindTexture (4 , *m_defaultTexture, *m_sampler);
250+ }
251+ } else {
252+ // No material - bind default textures to all units
253+ for (int i = 0 ; i < 5 ; ++i) {
254+ m_renderContext.bindTexture (i, *m_defaultTexture, *m_sampler);
222255 }
223256 }
224257
225258 // Draw indexed
226- if (meshData.index_count > 0 ) {
227- m_renderContext.drawElements (meshData.index_count , nullptr );
228- }
259+ LOG_INFO (" Drawing mesh with {} indices" , meshData.index_count );
260+ m_renderContext.drawElements (meshData.index_count , nullptr );
229261 }
230262
231263 // End rendering to FBO
0 commit comments