c# - Open GL Positioning Lighting at camera always -
background
i attempting make cad viewer can bring in stl file , rotate, pan, etc. shouldn't advanced game.
i having difficulty lighting can seen in previous post: previous post
problem
basically have light on now, , have pop , push matrix call outs in right place. trying optimize lighting cad environment. correct me if wrong believe best lighting viewing part having light @ camera pointing in direction of object. if not optimal way lighting, means feel free suggest better way.
i think comes down math. don't know if there built in functions camera is, or if have keep track of it.
here have display function:
private sub display() gl.glenable(gl.gl_depth_test) gl.glclear(gl.gl_color_buffer_bit) gl.glclear(gl.gl_depth_buffer_bit) gl.glpushmatrix() gl.glrotatef(rotx, 1.0f, 0.0f, 0.0f) ' rotate on x gl.glrotatef(roty, 0.0f, 1.0f, 0.0f) ' rotate on y gl.glrotatef(rotz, 0.0f, 0.0f, 1.0f) ' rotate on z gl.gltranslatef(x, y, z) 'draw x,y,z axis gl.glbegin(gl.gl_lines) gl.glcolor4f(0.0f, 1.0f, 0.0f, 1.0f) ' green x axis gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glvertex3f(5000.0f, 0.0f, 0.0f) gl.glcolor3f(1.0f, 0.0f, 0.0f) ' red y axis gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glvertex3f(0.0f, 5000.0f, 0.0f) gl.glcolor3f(0.0f, 0.0f, 1.0f) ' blue z axis gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glvertex3f(0.0f, 0.0f, 15.0f) gl.glend() ' dotted lines negative sides of x,y,z gl.glenable(gl.gl_line_stipple) ' enable line stipple ' use dotted pattern ' lines gl.gllinestipple(1, &h101) ' dotted stipple pattern ' lines gl.glbegin(gl.gl_lines) gl.glcolor3f(0.0f, 1.0f, 0.0f) ' green x axis gl.glvertex3f(-5000.0f, 0.0f, 0.0f) gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glcolor3f(1.0f, 0.0f, 0.0f) ' red y axis gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glvertex3f(0.0f, -5000.0f, 0.0f) gl.glcolor3f(0.0f, 0.0f, 1.0f) ' blue z axis gl.glvertex3f(0.0f, 0.0f, 0.0f) gl.glvertex3f(0.0f, 0.0f, -5000.0f) gl.glend() gl.gldisable(gl.gl_line_stipple) ' disable line stipple gl.glcolor3f(1.0f, 1.0f, 1.0f) glut.glutsolidteapot(5) gl.glenable(gl.gl_lighting) label1.text = "x=" & lighting_x & ", y=" & lighting_y & " z=" & lighting_z light1position = {lighting_x, lighting_y, lighting_z, 0.0f} ' enable default light gl.gllightfv(gl.gl_light1, gl.gl_ambient, light1ambient) gl.gllightfv(gl.gl_light1, gl.gl_diffuse, light1diffuse) gl.gllightfv(gl.gl_light1, gl.gl_position, light1position) gl.gllightfv(gl.gl_light1, gl.gl_specular, light1specular) gl.glenable(gl.gl_light1) gl.glpopmatrix() draw_extras() gl.glenable(gl.gl_color_material) gl.glcolormaterial(gl.gl_front, gl.gl_ambient_and_diffuse) gl.glmaterialfv(gl.gl_front, gl.gl_specular, materialspecular) gl.glmaterialfv(gl.gl_front, gl.gl_shininess, surfaceshininess) gl.glenable(gl.gl_color_material) glut.glutswapbuffers() end sub
basically have lighting_x, lighting_y, , lighting_z variables move light around. have variables x, y, , z establish panning (gl.gltranslatef(x, y, z)). variables rotx, roty, , rotz set rotation in main function using gl.glrotatef(rotx, 1.0f, 0.0f, 0.0f).
these variables being applied whole scene makes sense in cad environment axis moves well.
on top of this, using glulookat function create "zoom fit" function. understand, functions in display function move , rotate environment glulookat moving camera. keeping relation between these must needed lighting calculation:
private sub zoom_fit() rotx = 0 roty = 0 rotz = 0 rotlx = 0 rotly = 0 rotlz = 0 dim integer = 1 dim maxz decimal = -10000 until >= listview1.items.count if convert.todecimal(listview1.items.item(i).subitems(2).text) > maxz maxz = convert.todecimal(listview1.items.item(i).subitems(2).text) end if if convert.todecimal(listview1.items.item(i + 1).subitems(2).text) > maxz maxz = convert.todecimal(listview1.items.item(i).subitems(2).text) end if if convert.todecimal(listview1.items.item(i + 2).subitems(2).text) > maxz maxz = convert.todecimal(listview1.items.item(i).subitems(2).text) end if = + 4 loop rotlz = convert.tosingle((maxz - avgz) * 10) gl.glmatrixmode(gl.gl_modelview) gl.glloadidentity() glu.glulookat(rotlx, rotly, 15.0 + rotlz, 0.0, 0.0, 0.0, _ 0.0, 1.0, 0.0) glut.glutpostredisplay() end sub
i don't know environment puts camera relative origin when runs think need taken account.
what can see far:
the light side of teapot:
dark side of moon (teapot):
all code written in vb.net c# answers work too.
the code looks bit rough, , not comment on every detail may have fix. here important aspects , running:
all state needs set before draw calls. in other words, each draw call uses exact state in place @ time of call. example, set material properties @ end of
display()
function, after draw calls have been made. state changes not affect until next draw call.you need careful current transformation when specify light positions. spec:
the current model-view matrix applied position parameter indicated light particular light source when position specified.
so if want light source stationary relative camera, need make
gllightfv(.., gl_position, ..)
call while no model transformations on matrix stack.
i don't think putting light @ camera position common. cad type systems, have seen light source positioned @ top left. or in other words, light source placed negative x-offset , positive y-offset relative camera position. better results, can beneficial use more 1 light source. example, placing (possibly weaker) light source in opposite direction behind objects can good. you'll have play see works best you.
also, though know already, i'll have add (almost) obligatory: of opengl functionality using obsolete , deprecated. if learning, recommend learn "modern opengl", meaning version not using fixed pipeline anymore, , based on programmable shaders.
Comments
Post a Comment