PDA

View Full Version : Help with light on textured surfaces



art-ganseforth
04-16-2016, 05:31 AM
Hi there,

i'm first time trying to combine textures and light, but i dont get it.
My project is something like a modular-synthesizer for video-arts, using wxWidgets for the gui. Currently it is able to generate compex objects and to position them. It also creates and merges textures by offscreen rendering. In fact (this may be importent for my problem) all renderings are performed offscreen first and while rendering to the screen is a second step.
As a modular program, different openGL parameter-groups (like i.e. positioning-operations or blending-settings) can be added dynamically and linked to a chain, defining the settings of a rendered object.

Now i'm trying to create a light-and-material module - at first in a simple version for testing, but when i link it to the chain everything gets black only if GL_TEXTURE_ENV_MODE = GL_MODULATE or = GL_BLEND (note that texture- and blend-modes can be changed while runnung, so i tested different combinations) and at GL_TEXTURE_ENV_MODE = GL_DECAL nothing changes at all. :confused:

Here ist the code:


float ambientLight[] = {0,0,0, 1.0f};
float diffuseLight[] = {1.0*ccColor1->R/255, 1.0*ccColor1->G/255, 1.0*ccColor1->B/255, 1.0f};
float specularLight[] = {1.0*ccColor2->R/255, 1.0*ccColor2->G/255, 1.0*ccColor1->B/255, 1.0f};
float lightPosition[] = {1.0f, 1.0f, 0.0f};

glPushMatrix ();
//glEnable(GL_CULL_FACE);

if (selPosition->GetValue() > 0) selPosition->GetWindow()->Apply();

glLightfv (GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv (GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
glPopMatrix ();

glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);//glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);

GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
// GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
// GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
// GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.0 };
// GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };

glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, no_mat);

glEnable(GL_COLOR_MATERIAL);


The line


if (selPosition->GetValue() > 0) selPosition->GetWindow()->Apply();
calls a positioning-module (if there is linked one) to set the light's position, so glPushMatrix and glPopMatrix are needed.

EDIT:
1. Note that rendering is performed in memory (offscreen). Do i need a special buffer (like a stencilbuffer for shadows)??
2. Do i need to call glNormal3f before drawing a primitive?

Wolud be nice if someone has an idea what i do wrong...


Regards,
Frank

GClements
04-17-2016, 06:01 AM
Now i'm trying to create a light-and-material module - at first in a simple version for testing, but when i link it to the chain everything gets black only if GL_TEXTURE_ENV_MODE = GL_MODULATE or = GL_BLEND

This suggests that either the lighting is black, the texture is black, or the lighting and texture colours are disjoint primary colours (e.g. if you illuminate a pure-red texture with pure-green light, you'll get black).



1. Note that rendering is performed in memory (offscreen). Do i need a special buffer (like a stencilbuffer for shadows)??

There are two basic ways to implement shadows: shadow volumes or shadow maps. The former uses stencilling to compute the intersection of the geometry with a light (or shadow) volume. The latter uses a depth buffer generated by rendering as if the light was a camera.



2. Do i need to call glNormal3f before drawing a primitive?

You need to supply a normal for each vertex if you want to use lighting. The diffuse and specular components depend upon the normal.

Beyond that: I strongly suggest that you forget about the fixed-function pipeline and use shaders instead. Any OpenGL version which supports framebuffer objects also supports shaders. Shader-based rendering is much easier to modularise, and the code will be more portable. In particular, OpenGL ES 2+ doesn't have the fixed-function pipeline, and MacOS X doesn't support the compatibility profile, so you have to choose between OpenGL 2.1 (which doesn't have framebuffer objects) or OpenGL 3+ core profile (which doesn't have the fixed-function pipeline)

Also, once you've learned how to create and use shaders, they're much easier to understand than glTexEnv() (particularly if multi-texturing is involved).