I'm attempting too add basic lighting to my scene. So far even without GLSL. It appears that my lighting doesn't work. And what I mean by that is everything has no shade at all (everything is lit up).
I know the picture isn't the best, but thats partly because of the texture is shaded in the image.
Here is my init code:
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear to black with full alpha
glEnable(GL_DEPTH_TEST); // Enable depth testing
glDepthFunc(GL_LEQUAL); // Specify depth testing function
glClearDepth(1.0); // Clear the full extent of the depth buffer (default)
glEnable(GL_CULL_FACE); // Enable face culling
glCullFace(GL_BACK); // Cull back faces of polygons
glFrontFace(GL_CCW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
glEnable ( GL_COLOR_MATERIAL );
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 0.2f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position[] = {0, 100.0f, 0, 1.0f };
glLightModelfv(GL_AMBIENT, ambientLight);
glLightModelfv(GL_DIFFUSE, ambientLight);
glLightModelfv(GL_SPECULAR, specularLight);
glLightModelfv(GL_POSITION, position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
Draw code:
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
//For loop of the lights...
glLightfv(GL_LIGHT0+m_lights.at(i)->id, GL_POSITION, glm_to_array(m_lights.at(i)->position));
glEnable(GL_LIGHT0+m_lights.at(i)->id);
//Draw geometry here...
And yes, I am retrieving the normals from the mesh file and inserting the glNormal3f of every face. (GL_TRIANGLES) And even the plane the model sits on never gets affected even if I completely change the normal to random values.
Plane Example:
if(m_shader_programme){
glUseProgram(m_shader_programme);
}
if(m_texture_id){
glBindTexture(GL_TEXTURE_2D, m_texture_id);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}
glBegin(GL_TRIANGLES);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, m_sizey/10);
glVertex3f(m_sizex, m_height, m_sizey);
glTexCoord2f(m_sizex/10, m_sizey/10);
glVertex3f(m_sizex, m_height, -m_sizey);
glTexCoord2f(m_sizex/10, 0.0f);
glVertex3f(-m_sizex, m_height, -m_sizey);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(m_sizex/10, 0.0f);
glVertex3f(-m_sizex, m_height, -m_sizey);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-m_sizex, m_height, m_sizey);
glTexCoord2f(0.0f, m_sizey/10);
glVertex3f(m_sizex, m_height, m_sizey);
glEnd();
if(m_shader_programme){
glUseProgram(0);
}
if(m_texture_id){
glBindTexture(GL_TEXTURE_2D, 0);
}
GLSL Fragment Shader:
#version 120
uniform sampler2D tex;
void main()
{
vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color;
}
Vertex Shader:
#version 120
void main() {
vec3 normal, lightDir;
vec4 diffuse, ambient, globalAmbient;
float NdotL;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
NdotL = max(dot(normal, lightDir), 0.0);
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
/* Compute the ambient and globalAmbient terms */
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_FrontColor = NdotL * diffuse + globalAmbient + ambient;
gl_Position = ftransform();
}
System Specs
OS X (Yosemite) 10.10.13 (64bit)
Renderer: NVIDIA GeForce GTX 780M
OpenGL Engine OpenGL version supported 2.1 NVIDIA-10.2.7 310.41.25f01
Just encase anyone is wondering why I'm not using OpenGL 3.x is because GL 3.x doesn't appear to play nice on my machine.
Your fragment shader:
vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color;
Simply discards all the computations you did in the vertex shader and samples the texture color. You need to multiply the texture sample by the interpolated color value:
vec4 color = texture2D(tex, gl_TexCoord[0].st) * gl_Color;
^~~~~~
gl_FragColor = color;
Related
I wanted to ask you about texture and lighting.
I am using a 3ds Object in OpenGL, and a BITMAP texture. It is working perfectly. When I use lighting it didn't reflect the light. While I was searching I just commented the line: glEnable(GL_TEXTURE_2D); and the Texture was gone but lighting works!
Is there any opportunity that I can leave TEXTURE and also add lighting? Why is this happening? Anyone any idea?
EDITED
this is in INIT() function
void initialize(){
glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
glEnable(GL_TEXTURE_2D); // This Enable the Texture mapping
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
// Light model parameters:
// -------------------------------------------
GLfloat lmKa[] = {0.0, 0.0, 0.0, 0.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmKa);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 0.0);
// -------------------------------------------
// Spotlight Attenuation
GLfloat spot_direction[] = {1.0, -1.0, -1.0 };
GLint spot_exponent = 30;
GLint spot_cutoff = 180;
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, spot_exponent);
glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, spot_cutoff);
GLfloat Kc = 1.0;
GLfloat Kl = 0.0;
GLfloat Kq = 0.0;
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,Kc);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq);
// -------------------------------------------
// Lighting parameters:
GLfloat light_pos[] = {0.0f, 5.0f, 5.0f, 1.0f};
GLfloat light_Ka[] = {1.0f, 0.5f, 0.5f, 1.0f};
GLfloat light_Kd[] = {1.0f, 0.1f, 0.1f, 1.0f};
GLfloat light_Ks[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_Ka);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_Kd);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks);
// -------------------------------------------
// Material parameters:
GLfloat material_Ka[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat material_Kd[] = {0.4f, 0.4f, 0.5f, 1.0f};
GLfloat material_Ks[] = {0.8f, 0.8f, 0.0f, 1.0f};
GLfloat material_Ke[] = {0.1f, 0.0f, 0.0f, 0.0f};
GLfloat material_Se = 20.0f;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_Ka);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_Ks);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_Ke);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material_Se);
}
this is the DISPLAY() function (I am using QT)
void pointGL(){
if(change)
{
ThreeDModels objectClass;
objectClass.SpaceShip();
change = false;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glScalef(0.05, 0.05, 0.05);
ThreeDModels objectiModel;
objectiModel.objectCreation(l_index);
glPopMatrix();
}
Method which other method for Loading 3ds object and add Texture
void ThreeDModels::SpaceShip()
{
Load3DS(&objecti, "C:/Users/Documents/3DModelRendering/3DModels/Spaceship/spaceship.3ds");
int a = LoadBitmap2("C:/Users/Documents/3DModelRendering/3DModels/Spaceship/spaceshiptexture.bmp");
}
void ThreeDModels::objectCreation(int l_index)
{
glBegin(GL_TRIANGLES); // glBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
for (l_index = 0; l_index<objecti.polygons_qty; l_index++)
{
//----------------- FIRST VERTEX -----------------
// Texture coordinates of the first vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].a].u,
objecti.mapcoord[objecti.polygon[l_index].a].v);
// Coordinates of the first vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].a].x,
objecti.vertex[objecti.polygon[l_index].a].y,
objecti.vertex[objecti.polygon[l_index].a].z); //Vertex definition
//----------------- SECOND VERTEX -----------------
// Texture coordinates of the second vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].b].u,
objecti.mapcoord[objecti.polygon[l_index].b].v);
// Coordinates of the second vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].b].x,
objecti.vertex[objecti.polygon[l_index].b].y,
objecti.vertex[objecti.polygon[l_index].b].z);
//----------------- THIRD VERTEX -----------------
// Texture coordinates of the third vertex
glTexCoord2f(objecti.mapcoord[objecti.polygon[l_index].c].u,
objecti.mapcoord[objecti.polygon[l_index].c].v);
// Coordinates of the Third vertex
glVertex3f(objecti.vertex[objecti.polygon[l_index].c].x,
objecti.vertex[objecti.polygon[l_index].c].y,
objecti.vertex[objecti.polygon[l_index].c].z);
}
glEnd();
}
I found the Answer guys:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); was in the LoadBitmap() method, just removing this one, and it worked ;D
I've been trying to implement lighting for my OpenGL project, but so far I haven't been able to get any lighting effects.
I know that many things could go wrong, so I've tried hardcoding my normals (and using only a few triangles), but still I don't get anything.
In my scene, I have a few objects laying down along the "ground" at 0,0,0, hoping to see light coming down from above on them. They have a very basic texture on them which would easily show if they were lit up or not.
I initialize my scene like this:
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glTranslatef(0,0,0);
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 0.2f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position[] = {0, 100.0f, 0, 1.0f };
glLightModelfv(GL_AMBIENT, ambientLight);
glLightModelfv(GL_DIFFUSE, ambientLight);
glLightModelfv(GL_SPECULAR, specularLight);
glLightModelfv(GL_POSITION, position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
GLfloat shine [] = {50};
GLfloat diffuse[] = {1.0f, 0.f, 0.f, 1.0f};
GLfloat spec[] = {1.0f, 0.f, 0.f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,spec);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS,shine);
And when I go to render:
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tiles[x]->image.width(), tiles[x]->image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tiles[x]->image.bits());
glNormal3d(0,1,0); //Will eventually calculate
glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawArrays(GL_TRIANGLES, 3, 3);
"Tiles" is just a class of mine that holds an image and corresponding vectors for my objects. The "vertices" that are called is just a list of vectors (so each object has 6 vectors = 2 triangles.
My fragment shader:
uniform sampler2D texture;
in vec4 gl_Color;
in vec2 varyingTextureCoordinate;
out vec4 fragColor;
void main(void)
{
fragColor = texture2D(texture, varyingTextureCoordinate);
}
And my vertex shader:
uniform mat4 mvpMatrix;
in vec4 vertex;
in vec2 textureCoordinate;
out vec2 varyingTextureCoordinate;
void main(void)
{
varyingTextureCoordinate = textureCoordinate;
gl_Position = mvpMatrix * vertex;
}
Is my lack of lighting due to a conflict with the texture? No matter how I change that normal, I don't get any lighting.
I think you're trying to combine pre-programmable shader opengl and shader open gl here. I recommend learning how to implement lighting by utilizing as much shader code as possible
BennyBox has a great youtube series on OpenGL covering shaders and engine design
Here is his git repo and the java version.
I am struggling with coding this simple boat scene. It is a homework question but I am truly stumped. I have two models which I upload. One is a cube which has a fragment shader to color itself blue. The second is a boat which has a fragment shader to color itself white. When I use two different shaders the boat model is invisible. With much struggling and searching
I am stumped so I am trying plan B which is find a way to change the colors of a fragment shader between rendering the two objects, but I can't find out how to do so.
void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//BOAT START
//Rocks the ship, simulating ocean rocking
if(shiprocker < 5000){
shiprocker++;
theta += 0.00002f;
}
if(shiprocker ==15000){
shiprocker = -5000;
}
if(shiprocker > 4999){
shiprocker++;
theta -= 0.00002f;
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
boat_model->mR = glm::rotate(
glm::mat4( 1.0f ),
glm::degrees( theta ),
glm::vec3(0.0f, 0.0f, 1.0f)
);
glm::mat4 mtx_trans = glm::translate(
glm::mat4(1.0f),
glm::vec3( 0.0f, 0.0f, -15.0f )
);
boat_model->mM = mtx_trans * boat_model->mR;
boat_model->render();
//BOAT END
//OCEAN CUBE START
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glm::mat4 mtx_trans_cube = glm::translate(
glm::mat4( 1.0f ),
glm::vec3( -20.0f, -50.0f, -50.0f )
);
plane_model->mM = glm::scale(
mtx_trans_cube,
glm::vec3( 10.0f, 10.0f, 10.0f )
);
//gl_FragColor = (0.0f, 0.0f, 1.0f , 1.0f); wont compile
//glColor3f(0.0f, 0.0f, 1.0f); changes nothing
camera->set_uniform_view_perspective( plane_model->shader->program_ID );
plane_model->render();
//OCEAN CUBE END
glutSwapBuffers();
}
int main (int argc, char** argv) {
// Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_MULTISAMPLE | GLUT_RGB);
//WINDOW SETTINGS
glutInitWindowSize(1000, 1000);
glutCreateWindow("SailBoat");
//PASSIVE FUNCS
glutReshapeFunc(change_viewport);
glutDisplayFunc(render);
glutIdleFunc( animate );
//ERROR CHECK
if (GLEW_OK != glewInit()) {
exit(1);
}
//Clear color used for sky tones.
glClearColor(0.529f, 0.807f, .98f, 1.0f);
glEnable (GL_DEPTH_TEST);
glEnable (GL_MULTISAMPLE);
Shader* boatShader = new Shader( VERTEX_SHADER, BOAT_FRAGMENT_SHADER );
Shader* cubeShader = new Shader( VERTEX_SHADER, CUBE_FRAGMENT_SHADER );
//BOAT
boat_model = new Model(boatShader);
load_model(boat_model ,MODEL_BOAT_FILENAME);
boat_model->upload_2_server();
//OCEAN CUBE
plane_model = new Model( boatShader );
load_model(plane_model ,MODEL_PLANE_FILENAME);
plane_model->upload_2_server();
// Set up the camera
theta = 0.0f;
shiprocker = 0;
camera = new FPSCamera(60.0f, 1.0f, 1.0f, 10000.0f, true);
glutMainLoop();
return 0;
}
FRAGMENT SHADER
#version 150
in vec4 color;
out vec4 fColor;
void main () {
fColor = vec4(1.0, 1.0, 1.0, 0.5);
}
You can use uniform variables in GLSL to pass in values in between render calls. Set up your fragment shader like so:
#version 150
in vec4 color;
out vec4 fColor;
uniform vec3 boatColor;
void main () {
fColor = vec4(boatColor, 0.5);
}
And in your C++ code:
glUseProgram(program); // Where program is your shader program
GLint uniform = glGetUniformLocation(program, "boatColor"); // since boatColor is what we called the uniform variable in our fragment shader
glUniform3f(uniform, 1.0f, 0.0f, 0.0f); // Set the boatColor variable to be a solid red
// Render your first boat
glUniform3f(uniform, 0.0f, 0.0f, 1.0f); // Set the second boat to be a solid blue
// Render your second boat
glUseProgram(0);
And that should work nicely. If anyone else here has a better way, please let me know; I'm relatively new to GLSL.
here is my Setup() function:
void Setup() // TOUCH IT !!
{
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
//Parameter handling
glShadeModel (GL_SMOOTH);
//glEnable(GL_NORMALIZE);
glDepthFunc(GL_LEQUAL); //renders a fragment if its z value is less or equal of the stored value
glClearDepth(1);
//Set up light source
GLfloat light_position[] = { 20.0, 0.0, 0.0, 0.0 };
GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light_position);
glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight );
glEnable(GL_LIGHT0);
// polygon rendering mode
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glColorMaterial( GL_FRONT, GL_EMISSION );
// material identities
float specReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float ambReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float diffReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
glMaterialfv(GL_FRONT, GL_AMBIENT, ambReflection);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffReflection);
glMateriali(GL_FRONT,GL_SHININESS,20);
//// about texture
//glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// Black background
glClearColor(0.0f,0.0f,0.0f,1.0f);
}
here is my CalcNormal() function, where normals are being calculated. v1 and v2 are two vectors of a triangle:
Point CalcNormal(Point v1, Point v2)
{
Point normal;
normal.x = v1.y*v2.z - v1.z*v2.y;
normal.y = -v1.x*v2.z + v2.x*v1.z;
normal.z = v1.x*v2.y - v2.x*v1.y;
float dist1 = sqrt( pow(v1.x,2) + pow(v1.y,2) + pow(v1.z,2));
float dist2 = sqrt( pow(v2.x,2) + pow(v2.y,2) + pow(v2.z,2));
float dist = dist1*dist2;
normal.x = normal.x/dist;
normal.y = normal.y/dist;
normal.z = normal.z/dist;
return normal;
}
here is the vectors i send to CalcNormal():
Point n;
Point a1, a2;
a1.x=triangles.at(i).p2.x-triangles.at(i).p1.x; a1.y=triangles.at(i).p2.y-triangles.at(i).p1.y; a1.z=triangles.at(i).p2.z-triangles.at(i).p1.z;
a2.x=triangles.at(i).p3.x-triangles.at(i).p1.x; a2.y=triangles.at(i).p3.y-triangles.at(i).p1.y; a2.z=triangles.at(i).p3.z-triangles.at(i).p1.z;
n = CalcNormal(a1, a2);
and the result is like this:
rendering result
For smooth shading to be effective, you also need smooth normals - per vertex. The code you have posted so far shown only per-triangle normal calculations. In that case, the result will still look flat.
The easiest way to get smooth normals is, after you have calculated a normal per triangle, to average all normals of the adjacent triangles of each vertex. More complex schemes use a weighted average based on some function of the area of the triangles. There are also some heuristics whcih try to conserve hard edges, but as it is always the case with heuristics, there will always be some corner cases. Ideally, the normals are created when the model is created and stored in the file.
I'm working in OpenGL, with VBOs, and I have a set of three lines (along the X, Y and Z axes - think Czech hedgehog). The lines are grey by default, but I want them bright red so I can see them better. Unfortunately, though I added color information as vertex data, the lines still appear grey. I'm probably missing something basic, but I can't see it. Here is how I create the VBO:
//Position data
sf::Vector3<float> Top = sf::Vector3<float>(0.0, 1.0, 0.0);
sf::Vector3<float> Front = sf::Vector3<float>(0.0, 0.0, -1.0);
sf::Vector3<float> Right = sf::Vector3<float>(1.0, 0.0, 0.0);
sf::Vector3<float> Back = sf::Vector3<float>(0.0, 0.0, 1.0);
sf::Vector3<float> Left = sf::Vector3<float>(-1.0, 0.0, 0.0);
sf::Vector3<float> Bottom = sf::Vector3<float>(0.0, -1.0, 0.0);
//Color data
//Just to be clear, I also tried with 255.0, although I'm rather certain OpenGL
//does its colors on a 0-1 scale.
sf::Vector3<float> Color = sf::Vector3<float>(1.0, 0.0, 0.0);
//Create vector
std::vector<float> LineArray;
//Top
LineArray.push_back(Top.x);
LineArray.push_back(Top.y);
LineArray.push_back(Top.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Bottom
LineArray.push_back(Bottom.x);
LineArray.push_back(Bottom.y);
LineArray.push_back(Bottom.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Front
LineArray.push_back(Front.x);
LineArray.push_back(Front.y);
LineArray.push_back(Front.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Back
LineArray.push_back(Back.x);
LineArray.push_back(Back.y);
LineArray.push_back(Back.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Right
LineArray.push_back(Right.x);
LineArray.push_back(Right.y);
LineArray.push_back(Right.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Left
LineArray.push_back(Left.x);
LineArray.push_back(Left.y);
LineArray.push_back(Left.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Create buffer
glGenBuffers(1, &m_Buffer);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
int SizeInBytes = LineArray.size() * 6 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);
//Upload buffer data
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * LineArray.size(), &LineArray[0]);
And this is how I display it every tick:
glPushMatrix();
//Translate
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
//Rotate
glMultMatrixf(m_RotationMatrix);
//Bind buffers for vertex and color arrays
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), 0);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 6 * sizeof(float), (void*)12);
//Draw
glDrawArrays(GL_LINES, 0, 36);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
//Unbind the buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glPopMatrix();
I've never used GL_COLOR_ARRAY before, but I based the code off of successful use of GL_NORMAL_ARRAY. Can someone point out what's wrong?
EDIT: On the offchance that I'm setting up my basic OpenGL parameters wrong (lighting in particular), here are those:
m_AmbientLight = {0.5f, 0.5f, 0.5f, 1.0f};
m_DiffuseLight = {1.0f, 1.0f, 1.0f, 1.0f};
m_LightPos = {8.0f, -16.0f, 8.0f, 0.0f};
//Smooth Shading
glShadeModel(GL_SMOOTH);
// Set color and depth clear value
glClearDepth(1.f);
//Color here is in RGB, converted to a 0-1 scale.
glClearColor(0.3f, 0.3f, 0.3f, 1.f);
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
///
///LIGHTING
///
//Set up lighting.
//This activates the ambient light.
glLightfv(GL_LIGHT0, GL_AMBIENT, m_AmbientLight);
//This activates the diffuse light.
glLightfv(GL_LIGHT1, GL_DIFFUSE, m_DiffuseLight);
//This sets the position of the diffuse light.
glLightfv(GL_LIGHT1, GL_POSITION, m_LightPos);
//This enables the light.
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
//Enables all lighting...?
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
//glEnable(GL_NORMALIZE);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.f, 1.33f, 0.1f, 512.f);
EDIT 2: Having established that glColor3f() also doesn't have any effect, I wonder if my shaders are the problem:
Vert shader:
void main()
{
vec3 normal, lightDir;
vec4 diffuse;
float NdotL;
normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
NdotL = max(dot(normal, lightDir), 0.0);
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
gl_FrontColor = NdotL * diffuse;
gl_Position = ftransform();
}
Frag shader:
void main()
{
gl_FragColor = gl_Color;
}
Not 100% positive, but I don't believe you should have GL_COLOR_MATERIAL enabled while you draw the lines. Try disabling that.
edit (copied from comment):
Your shader doesn't make sense to me. You should just be passing in a color, and then passing that color straight to the fragment shader. Why are you using a lighting shader to draw lines? You should create a different shader that doesn't use any of that materials stuff. Enabling/disabling lighting has no effect unless you're using fixed function pipeline. I think you're mixing up fixed function commands with your shaders and getting confused.
Sounds to me like you've got lighting enabled while drawing the lines, hence the color of the vertex data being overridden by the color of the illumination calculation. Add a glDisable(GL_LIGHTING) right before the glDrawArrays.