func newCullInfo() *cullInfo { info := &cullInfo{} // First, just read out the current OpenGL matrices...do this once at setup because it's not the fastest thing to do. gl.GetFloatv(gl.MODELVIEW_MATRIX, &(info.model_view[0])) gl.GetFloatv(gl.PROJECTION_MATRIX, &(info.proj[0])) // Now...what the heck is this? Here's the deal: the clip planes have values in "clip" coordinates of: Left = (1,0,0,1) // Right = (-1,0,0,1), Bottom = (0,1,0,1), etc. (Clip coordinates are coordinates from -1 to 1 in XYZ that the driver // uses. The projection matrix converts from eye to clip coordinates.) // // How do we convert a plane backward from clip to eye coordinates? Well, we need the transpose of the inverse of the // inverse of the projection matrix. (Transpose of the inverse is needed to transform a plane, and the inverse of the // projection is the matrix that goes clip -> eye.) Well, that cancels out to the transpose of the projection matrix, // which is nice because it means we don't need a matrix inversion in this bit of sample code. // So this nightmare down here is simply: // clip plane * transpose (proj_matrix) // worked out for all six clip planes. If you squint you can see the patterns: // L: 1 0 0 1 // R: -1 0 0 1 // B: 0 1 0 1 // T: 0 -1 0 1 // etc. info.lft_clip[0] = info.proj[0] + info.proj[3] info.lft_clip[1] = info.proj[4] + info.proj[7] info.lft_clip[2] = info.proj[8] + info.proj[11] info.lft_clip[3] = info.proj[12] + info.proj[15] info.rgt_clip[0] = -info.proj[0] + info.proj[3] info.rgt_clip[1] = -info.proj[4] + info.proj[7] info.rgt_clip[2] = -info.proj[8] + info.proj[11] info.rgt_clip[3] = -info.proj[12] + info.proj[15] info.bot_clip[0] = info.proj[1] + info.proj[3] info.bot_clip[1] = info.proj[5] + info.proj[7] info.bot_clip[2] = info.proj[9] + info.proj[11] info.bot_clip[3] = info.proj[13] + info.proj[15] info.top_clip[0] = -info.proj[1] + info.proj[3] info.top_clip[1] = -info.proj[5] + info.proj[7] info.top_clip[2] = -info.proj[9] + info.proj[11] info.top_clip[3] = -info.proj[13] + info.proj[15] info.nea_clip[0] = info.proj[2] + info.proj[3] info.nea_clip[1] = info.proj[6] + info.proj[7] info.nea_clip[2] = info.proj[10] + info.proj[11] info.nea_clip[3] = info.proj[14] + info.proj[15] info.far_clip[0] = -info.proj[2] + info.proj[3] info.far_clip[1] = -info.proj[6] + info.proj[7] info.far_clip[2] = -info.proj[10] + info.proj[11] info.far_clip[3] = -info.proj[14] + info.proj[15] return info }
func (self *DefaultRenderer) drawPlaneLabels(renderList *renderList, cullInfo *cullInfo, labelDist float32) { var vp [4]float32 gl.GetFloatv(gl.VIEWPORT, &vp[0]) gl.MatrixMode(gl.PROJECTION) gl.PushMatrix() gl.LoadIdentity() gl.Ortho(0, float64(vp[2]), 0, float64(vp[3]), -1, 1) gl.MatrixMode(gl.MODELVIEW) gl.PushMatrix() gl.LoadIdentity() c := []float32{1, 1, 0, 1} for _, plane := range renderList.GetAllPlanes() { if plane.dist < labelDist { x, y := cullInfo.convertTo2d(vp, plane.x, plane.y, plane.z, 1.0) rat := 1.0 - (plane.dist / MAX_LABEL_DIST) c[0] = 0.5 + 0.5*rat c[1] = c[0] c[2] = 0.5 - 0.5*rat // gray -> yellow - no alpha in the SDK - foo! graphics.DrawString(color.RGBA{uint8(255.0 * c[0]), uint8(255.0 * c[1]), uint8(255.0 * c[2]), 0}, int(x), int(y+10), plane.plane.PositionData.Label, []int32{}, graphics.Font_Basic) } } gl.MatrixMode(gl.PROJECTION) gl.PopMatrix() gl.MatrixMode(gl.MODELVIEW) gl.PopMatrix() }