void TinyRenderer::renderObject(TinyRenderObjectData& renderData) { int width = renderData.m_rgbColorBuffer.get_width(); int height = renderData.m_rgbColorBuffer.get_height(); Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0],renderData.m_lightDirWorld[1],renderData.m_lightDirWorld[2]); Vec3f light_color = Vec3f(renderData.m_lightColor[0],renderData.m_lightColor[1],renderData.m_lightColor[2]); float light_distance = renderData.m_lightDistance; Model* model = renderData.m_model; if (0==model) return; renderData.m_viewportMatrix = viewport(0,0,width, height); b3AlignedObjectArray<float>& zbuffer = renderData.m_depthBuffer; b3AlignedObjectArray<float>* shadowBufferPtr = renderData.m_shadowBuffer; int* segmentationMaskBufferPtr = (renderData.m_segmentationMaskBufferPtr && renderData.m_segmentationMaskBufferPtr->size())?&renderData.m_segmentationMaskBufferPtr->at(0):0; TGAImage& frame = renderData.m_rgbColorBuffer; { // light target is set to be the origin, and the up direction is set to be vertical up. Matrix lightViewMatrix = lookat(light_dir_local*light_distance, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,1.0)); Matrix lightModelViewMatrix = lightViewMatrix*renderData.m_modelMatrix; Matrix modelViewMatrix = renderData.m_viewMatrix*renderData.m_modelMatrix; Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]); Shader shader(model, light_dir_local, light_color, modelViewMatrix, lightModelViewMatrix, renderData.m_projectionMatrix,renderData.m_modelMatrix, renderData.m_viewportMatrix, localScaling, model->getColorRGBA(), width, height, shadowBufferPtr, renderData.m_lightAmbientCoeff, renderData.m_lightDiffuseCoeff, renderData.m_lightSpecularCoeff); for (int i=0; i<model->nfaces(); i++) { for (int j=0; j<3; j++) { shader.vertex(i, j); } mat<4,3,float> stackTris[3]; b3AlignedObjectArray< mat<4,3,float> > clippedTriangles; clippedTriangles.initializeFromBuffer(stackTris,0,3); bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri,clippedTriangles); if (hasClipped) { for (int t=0;t<clippedTriangles.size();t++) { triangleClipped(clippedTriangles[t], shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex); } } else { triangle(shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex); } } } }
void TinyRenderer::renderObject(TinyRenderObjectData& renderData) { B3_PROFILE("renderObject"); int width = renderData.m_rgbColorBuffer.get_width(); int height = renderData.m_rgbColorBuffer.get_height(); Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0],renderData.m_lightDirWorld[1],renderData.m_lightDirWorld[2]); Vec3f light_color = Vec3f(renderData.m_lightColor[0],renderData.m_lightColor[1],renderData.m_lightColor[2]); float light_distance = renderData.m_lightDistance; Model* model = renderData.m_model; if (0==model) return; //discard invisible objects (zero alpha) if (model->getColorRGBA()[3]==0) return; renderData.m_viewportMatrix = viewport(0,0,width, height); b3AlignedObjectArray<float>& zbuffer = renderData.m_depthBuffer; b3AlignedObjectArray<float>* shadowBufferPtr = renderData.m_shadowBuffer; int* segmentationMaskBufferPtr = (renderData.m_segmentationMaskBufferPtr && renderData.m_segmentationMaskBufferPtr->size())?&renderData.m_segmentationMaskBufferPtr->at(0):0; TGAImage& frame = renderData.m_rgbColorBuffer; { // light target is set to be the origin, and the up direction is set to be vertical up. Matrix lightViewMatrix = lookat(light_dir_local*light_distance, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,1.0)); Matrix lightModelViewMatrix = lightViewMatrix*renderData.m_modelMatrix; Matrix modelViewMatrix = renderData.m_viewMatrix*renderData.m_modelMatrix; Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]); Matrix viewMatrixInv = renderData.m_viewMatrix.invert(); btVector3 P(viewMatrixInv[0][3], viewMatrixInv[1][3], viewMatrixInv[2][3]); Shader shader(model, light_dir_local, light_color, modelViewMatrix, lightModelViewMatrix, renderData.m_projectionMatrix,renderData.m_modelMatrix, renderData.m_viewportMatrix, localScaling, model->getColorRGBA(), width, height, shadowBufferPtr, renderData.m_lightAmbientCoeff, renderData.m_lightDiffuseCoeff, renderData.m_lightSpecularCoeff); { B3_PROFILE("face"); for (int i=0; i<model->nfaces(); i++) { for (int j=0; j<3; j++) { shader.vertex(i, j); } // backface culling btVector3 v0(shader.world_tri.col(0)[0], shader.world_tri.col(0)[1], shader.world_tri.col(0)[2]); btVector3 v1(shader.world_tri.col(1)[0], shader.world_tri.col(1)[1], shader.world_tri.col(1)[2]); btVector3 v2(shader.world_tri.col(2)[0], shader.world_tri.col(2)[1], shader.world_tri.col(2)[2]); btVector3 N = (v1-v0).cross(v2-v0); if ((v0-P).dot(N) >= 0) continue; mat<4,3,float> stackTris[3]; b3AlignedObjectArray< mat<4,3,float> > clippedTriangles; clippedTriangles.initializeFromBuffer(stackTris,0,3); bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri,clippedTriangles); if (hasClipped) { for (int t=0;t<clippedTriangles.size();t++) { triangleClipped(clippedTriangles[t], shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex); } } else { triangle(shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex); } } } } }