# ofVbo + GL_TRIANGLE_STRIP

Hi,

I am trying to build a mesh from a grid of points using the GL_TRIANGLE_STRIP mode so I can apply a texture to it on an iOS device.

I found I really good tutorial to achieve this http://dan.lecocq.us/wordpress/2009/12/25/triangle-strip-for-grids-a-construction/

So far I am getting this results:
0, 4, 1, 5, 2, 6, 3, 7, 7, 11, 6, 10, 5, 9, 4, 8, 14, 18, 15, 19, 16, 20, 17, 21
and it should be:
0, 4, 1, 5, 2, 6, 3, 7, 7, 11, 6, 10, 5, 9, 4, 8, 8, 12, 9, 13, 10, 14, 11, 15

Here is my code

``````
// Mesh indices
int totalQuads		= (cols-1) * (rows-1);
int totalTriangles	= totalQuads * 2;
int totalIndices	= (cols*2) * (rows-1);
cout << "total number of triangles: " << totalTriangles << endl;
cout << "total number of indices: " << totalIndices << endl;

bool isGoingBackwards = false;
int n = 0;
int ind = 0;
vector<int> indices;

for ( int i = 0; i < totalIndices; i++ ) {
// Check if is going forward or backwards
if ( i % (cols*2) == 0 ) {
ind++;
if ( ind%2 == 1 ) {
n = ((cols*2) - 1) * (ind-1);
cout << "forward " << n << endl;
isGoingBackwards = false;
}
else {
n = ((cols*2) - 1) * (ind-1);
cout << "backward " << n << endl;
isGoingBackwards = true;
}
}

// Fills the indices container
indices.push_back( n );

// Performs +4 -3 & -5 operations
if ( i%2 == 0 ) {
n += 4;
}
else {
( isGoingBackwards ) ? n -= 5 :	n -= 3;
}
}

``````

Has anyone manage to implement this?

• rS

Got it!

``````
int n	= 0;
int colSteps = cols * 2;
int rowSteps = rows - 1;
vector<int> indices;
for ( int r = 0; r < rowSteps; r++ ) {
for ( int c = 0; c < colSteps; c++ ) {
int t = c + r * colSteps;

if ( c == colSteps - 1 ) {
indices.push_back( n );
}
else {
indices.push_back( n );

( t%2 == 0 ) ? n += cols : (r%2 == 0) ? n -= (cols-1) : n -= (cols+1);
}
}
}

``````

Fail to build the mesh, using the previously generated indices I am trying to build my mesh like this:

``````
for ( int a = 0; a < indices.size(); a++ ) {
}
// Points positions
for ( int y = 0; y < rows; y++ ) {
for ( int x = 0; x < cols; x++ ) {
ofVec2f point( x * spaceX, y * spaceY );
points.push_back( point );
}
}

vboMesh.setMesh( mesh, GL_DYNAMIC_DRAW );
cout << "mesh number of vertices: " << mesh.getNumVertices() << endl;

``````

Check attach image for the resulting mesh, the red lines represent the vboMesh wireframe

Am I implementing the indices properly? what am I missing?

Fix the problem, I was drawing the vboMesh using:

``````
vboMesh.draw( GL_TRIANGLE_STRIP, 0, mesh.getNumvertice() );

``````

Change it to:

``````
vboMesh.drawElements( GL_TRIANGLE_STRIP, mesh.getNumIndices() );

``````

looks neat!

I’m back this time is a texture issue, I need to texture the mesh using normal text coordinates 0 to 1, I change the code to allo for this but as you can see in the attach image, there is something wrong

Here is my code:
In setup()

``````
ofDisableArbTex();
photoText.allocate( photo.width, photo.height, GL_RGB );
photoText.loadData( photo.getPixels(), photo.width, photo.height, GL_RGB );

...

// Textture coordinates
for ( int y = 0; y < rows; y++ ) {
for ( int x = 0; x < cols; x++ ) {
ofVec2f point( (x * spaceX) / sizeW, (y * spaceY) / sizeH );
int i = x + y * cols;
textCoords[i] = point;
}
}

vboMesh.setMesh( mesh, GL_STATIC_DRAW );

``````

After reading this post http://forum.openframeworks.cc/t/ofxmsashape3d-and-binding-textures-006/1976/0 it looks like I need to use getTextureData()->tex_t and getTextureData()->tex_u but I have no idea how to implement this on my code.

If I dont use ofDisableArbTex(); and calculate the text coordinates whithout the normalization everything works fine, but I need normal text coords, any help will be much appreciated

I don’t know too much about the topic, but what is SpaceX and sizeW? maybe do they have to trade places?
try what happens if you feed a texture with pow(2) dimension.

ofTexture has this method:

``````
ofPoint getCoordFromPercent(float xPts, float yPts);

``````

which returns non- normalize coords from normalized ones for that texture, you can also use

``````
void ofEnableNormalizedTexCoords();

``````

to enable normalized coordinates for everything

``````
ofEnableNormalizedTexCoords();

``````

did the trick

Thanks

I am getting an error if I declare:

``````
mesh.setMode( OF_TRIANGLE_STRIP_MODE );

``````

**Error 1: **invalid conversion from ‘int’ to ‘ofPrimitiveMode’
**Error 2: **initializing argument 1 of ‘void ofMesh::setMode(ofPrimitiveMode)’

it should be OF_PRIMITIVE_TRIANGLE_STRIP. don’t know why those defines are still there but they shouldn’t

@nardove thanks for this post, it really helped me

I am trying to calculate the normals for the grid now, as I want to animate the vertices and apply some lighting.

1. I calculate the normals of the triangles using this function:
``````
ofVec3f testApp::getNormalFromTriangleVertices(vector<ofVec3f> triangleVertices)
{
ofVec3f u = triangleVertices[0] - triangleVertices[1];
ofVec3f v = triangleVertices[1] - triangleVertices[2];
return u.getPerpendicular(v);
}

``````
1. I calculate the normal for each vertex doing the average of the normals of the triangles that are touching that vertex as follow:
``````
ofVec3f sumNormals;
for (int h = 0; h < normalsVector.size(); h++) {
sumNormals += normalsVector[h];
}
averageNormals.push_back(sumNormals / normalsVector.size());

``````

where normalsVector is the vector with all the normals for that vertex.

1. I add the average normals of each vertex to the mesh using:
``````

``````

I think I am doing something wrong because I don’t get the right lighting. Am I following the right process to calculate the normals for each vertex?

Does this trace of what I am getting make any sense?

``````
///////// TRACE /////////
NUM VERTEX: 16
Vertex 0: 0, 0, 133.339
Vertex 1: 100, 0, 36.5464
Vertex 2: 200, 0, 36.145
Vertex 3: 300, 0, 88.9084
Vertex 4: 0, 100, 83.4531
Vertex 5: 100, 100, 196.625
Vertex 6: 200, 100, 71.2214
Vertex 7: 300, 100, 18.126
Vertex 8: 0, 200, 44.0374
Vertex 9: 100, 200, 137.094
Vertex 10: 200, 200, 138.619
Vertex 11: 300, 200, 174.264
Vertex 12: 0, 300, 60.526
Vertex 13: 100, 300, 60.1892
Vertex 14: 200, 300, 199.051
Vertex 15: 300, 300, 44.9147

NUM INDICES: 24
Index 0: 0
Index 1: 4
Index 2: 1
Index 3: 5
Index 4: 2
Index 5: 6
Index 6: 3
Index 7: 7
Index 8: 7
Index 9: 11
Index 10: 6
Index 11: 10
Index 12: 5
Index 13: 9
Index 14: 4
Index 15: 8
Index 16: 8
Index 17: 12
Index 18: 9
Index 19: 13
Index 20: 10
Index 21: 14
Index 22: 11
Index 23: 15

NUM VERTEX NORMALS: 16
Vertex Normal 0: -0.654702, -0.337428, -0.676393
Vertex Normal 1: -0.390357, -0.0722323, -0.250604
Vertex Normal 2: 0.402458, 0.310257, -0.255153
Vertex Normal 3: 0.421672, 0.413199, -0.0479028
Vertex Normal 4: -0.302893, -0.243831, -0.0773375
Vertex Normal 5: 0.047362, -0.104177, 0.144211
Vertex Normal 6: 0.481116, -0.00803751, 0.135218
Vertex Normal 7: 0.336466, -0.139729, 0.633702
Vertex Normal 8: 0.665428, -0.0787004, -0.715079
Vertex Normal 9: 0.11026, -0.0503534, -0.278879
Vertex Normal 10: 0.0926802, -0.13513, -0.356643
Vertex Normal 11: 0.384129, 0.199192, -0.162578
Vertex Normal 12: 0.339498, 0.364727, 0.0329507
Vertex Normal 13: -0.250136, -0.110984, 0.183695
Vertex Normal 14: 0.0708656, 0.245788, 0.0591525
Vertex Normal 15: 0.685969, 0.57566, 0.445042

NUM TRIANGLES: 18
Triangle 0: 0 , 4 , 1 ,
Triangle 1: 4 , 1 , 5 ,
Triangle 2: 1 , 5 , 2 ,
Triangle 3: 5 , 2 , 6 ,
Triangle 4: 2 , 6 , 3 ,
Triangle 5: 6 , 3 , 7 ,
Triangle 6: 7 , 11 , 6 ,
Triangle 7: 11 , 6 , 10 ,
Triangle 8: 6 , 10 , 5 ,
Triangle 9: 10 , 5 , 9 ,
Triangle 10: 5 , 9 , 4 ,
Triangle 11: 9 , 4 , 8 ,
Triangle 12: 8 , 12 , 9 ,
Triangle 13: 12 , 9 , 13 ,
Triangle 14: 9 , 13 , 10 ,
Triangle 15: 13 , 10 , 14 ,
Triangle 16: 10 , 14 , 11 ,
Triangle 17: 14 , 11 , 15 ,

NUM TRIANGLE NORMALS: 18
Triangle 0 Normal: -0.654702, -0.337428, -0.676393
Triangle 1 Normal: -0.514242, -0.727382, 0.454391
Triangle 2 Normal: -0.00212701, 0.848113, -0.529811
Triangle 3 Normal: 0.763798, -0.213641, 0.609073
Triangle 4 Normal: 0.445704, 0.296298, -0.844722
Triangle 5 Normal: 0.39764, 0.530101, 0.748916
Triangle 6 Normal: 0.275293, -0.809558, 0.518488
Triangle 7 Normal: 0.28346, 0.535967, -0.795229
Triangle 8 Normal: 0.720798, -0.387392, 0.574784
Triangle 9 Normal: 0.0131053, -0.511484, -0.859193
Triangle 10 Normal: -0.697161, 0.366722, 0.616021
Triangle 11 Normal: 0.654531, -0.277238, -0.703369
Triangle 12 Normal: 0.676325, 0.119837, -0.72679
Triangle 13 Normal: 0.00267007, 0.609618, 0.792691
Triangle 14 Normal: 0.0120901, -0.609575, -0.792636
Triangle 15 Normal: -0.765168, -0.332995, 0.551029
Triangle 16 Normal: 0.291795, 0.4947, -0.818613
Triangle 17 Normal: 0.685969, 0.57566, 0.445042

``````

Thanks a lot guys! Sorry if it’s an obvious question, I’m a lighting newbie

/roger

Hi Roger,

I am new in the lighting field as well, I manage to get it working in Cinder using their VBO class, have a look at this post http://forum.libcinder.org/#topic/23286000000203001 were discuss how to calculate vertex normals, hope it helps

Will you be able to show an image of your results so far?

Cheers

Hey,

Thanks a lot! I’m going on holidays now, but I’ll check it when I come back, really helpful

Here you have what I have for now, it starts looking how it should!

If you are interested I can send you the code, sharing is caring!

thanks again,

/roger

Hi Roger

That would be really useful. Please send the code to - me [at] jamesalliban dot co dot uk

Thanks very much

Hi Roger, yes I would like to see the code

Thanks!

Could I see the code as well Roger. Would love to have a look at how you implemented the lighting. Thanks.

Sorry guys, I completely miss that you wanted the code, somehow checking my old emails I saw a notification.
Not sure it will help now but here you have:

``````
#include "testApp.h"

#define USE_TRIANGLE_STRIPS 1

//--------------------------------------------------------------
void testApp::setup(){

ofSetLogLevel(OF_LOG_VERBOSE);
ofBackground(255, 255, 255);
ofSetVerticalSync(false);
ofEnableAlphaBlending();

glEnable(GL_DEPTH_TEST);

//we load a font and tell OF to make outlines so we can draw it as GL shapes rather than textures
font.loadFont("type/verdana.ttf", 100, true, false, true, 0.4, 72);

else

int cols = 8;
int rows = 8;

// Mesh indices
int totalQuads		= (cols-1) * (rows-1);
int totalTriangles	= totalQuads * 2;
int totalIndices	= (cols*2) * (rows-1);
cout << "total number of triangles: " << totalTriangles << endl;
cout << "total number of indices: " << totalIndices << endl;

int n	= 0;
int colSteps = cols * 2;
int rowSteps = rows - 1;
vector<int> indices;
for ( int r = 0; r < rowSteps; r++ ) {
for ( int c = 0; c < colSteps; c++ ) {
int t = c + r * colSteps;

if ( c == colSteps - 1 ) {
indices.push_back( n );
}
else {
indices.push_back( n );

( t%2 == 0 ) ? n += cols : (r%2 == 0) ? n -= (cols-1) : n -= (cols+1);
}
}
}

for ( int a = 0; a < indices.size(); a++ ) {
}

int spaceX = 100;
int spaceY = 100;

for ( int y = 0; y < rows; y++ ) {
for ( int x = 0; x < cols; x++ ) {

ofVec3f point( x * spaceX, y * spaceY, ofRandom(200) );

}
}

vector<ofVec3f> triangleVertices;
vector<ofVec3f> triangleNormals;

vector<int> triangleVerticesIndices;
vector< vector<int> > vectorTriangleVerticesIndices;

int l = 0;
for (int h = 0; h < indices.size(); h++) {
triangleVertices.clear();
triangleVerticesIndices.clear();

if (l == cols * 2 - 2) {
h+= 2;
l = 0;
}

triangleVertices.push_back( mesh.getVertex(indices[h]) );
triangleVertices.push_back( mesh.getVertex(indices[h+1]) );
triangleVertices.push_back( mesh.getVertex(indices[h+2]) );

ofVec3f normal = getNormalFromTriangleVertices(triangleVertices);
triangleNormals.push_back(normal);

triangleVerticesIndices.push_back( indices[h] );
triangleVerticesIndices.push_back( indices[h+1] );
triangleVerticesIndices.push_back( indices[h+2]);
vectorTriangleVerticesIndices.push_back(triangleVerticesIndices);

if(!USE_TRIANGLE_STRIPS){
}

if (indices[h+2] == (cols * rows - 1)) {
break;
}
l++;

}

vector<ofVec3f> averageNormals;
for (int k = 0; k < mesh.getNumVertices(); k++) {
vector<ofVec3f> normalsVector;
for (int i = 0; i < vectorTriangleVerticesIndices.size(); i++) {
for ( int j = 0; j < 3; j++ ) {
if(vectorTriangleVerticesIndices[i][j] == k){
normalsVector.push_back(triangleNormals[i]);
}
}
}
ofVec3f sumNormals;
for (int h = 0; h < normalsVector.size(); h++) {
sumNormals += normalsVector[h];
}
averageNormals.push_back(sumNormals / normalsVector.size());
}

int colorCount = 0;

for ( int y = 0; y < rows; y++ ) {
for ( int x = 0; x < cols; x++ ) {

if (colorCount % 3 == 0) {
}else if( colorCount % 2 == 0){
}else {
}

colorCount++;

}
}

vbo.setMesh(mesh, GL_DYNAMIC_DRAW);

//////// TRACE //////

cout << "///////// TRACE ///////// " << endl;

cout << "NUM VERTEX: " << mesh.getNumVertices() << endl;
int i;
for (i = 0; i < mesh.getNumVertices(); i++) {
cout << "		Vertex " << i << ": " << mesh.getVertex(i) << endl;
}
cout << endl;

cout << "NUM INDICES: " << mesh.getNumIndices() << endl;
for (i = 0; i < mesh.getNumIndices(); i++) {
cout << "		Index " << i << ": " << mesh.getIndex(i) << endl;
}
cout << endl;

cout << "NUM VERTEX NORMALS: " << mesh.getNumNormals() << endl;

for (i = 0; i < mesh.getNumNormals(); i++) {
cout << "		Vertex Normal " << i << ": " << mesh.getNormal(i) << endl;
}
cout << endl;

cout << "NUM TRIANGLES: " << vectorTriangleVerticesIndices.size() << endl;

for (i = 0; i < vectorTriangleVerticesIndices.size(); i++) {
cout << "		Triangle " << i << ": " << vectorTriangleVerticesIndices[i][0] << " , " << vectorTriangleVerticesIndices[i][1] << " , " << vectorTriangleVerticesIndices[i][2] << " , " << endl;
}
cout << endl;

cout << "NUM TRIANGLE NORMALS: " << triangleNormals.size() << endl;

for (i = 0; i < triangleNormals.size(); i++) {
cout << "		Triangle " << i << " Normal: " << triangleNormals[i] << endl;
}
cout << endl;

cout << "//////// END TRACE ////// " << endl;

gui.show();

}

ofVec3f testApp::getNormalFromTriangleVertices(vector<ofVec3f> triangleVertices)
{
// now is same as RedBook (OpenGL Programming Guide)
ofVec3f u = triangleVertices[0] - triangleVertices[1];
ofVec3f v = triangleVertices[1] - triangleVertices[2];

/*cout << " triangleVertices[0].x: " << triangleVertices[0].x << " triangleVertices[0].y: " << triangleVertices[0].y << " triangleVertices[0].z: " << triangleVertices[0].z << endl;
cout << " triangleVertices[1].x: " << triangleVertices[1].x << " triangleVertices[1].y: " << triangleVertices[1].y << " triangleVertices[1].z: " << triangleVertices[1].z << endl;
cout << " triangleVertices[2].x: " << triangleVertices[2].x << " triangleVertices[2].y: " << triangleVertices[2].y << " triangleVertices[2].z: " << triangleVertices[2].z << endl;

cout << " u.x: " << u.x << " u.y: " << u.y << " u.z: " << u.z << endl;
cout << " v.x: " << v.x << " v.y: " << v.y << " v.z: " << v.z << endl;*/

ofVec3f normal = u.getPerpendicular(v);
//cout << " normal.x: " << normal.x << " normal.y: " << normal.y << " normal.z: " << normal.z << endl;
return normal;
}

//--------------------------------------------------------------
void testApp::update(){
//light.setPosition(0, 100 * sin(ofGetElapsedTimef()), -150);

}

//--------------------------------------------------------------
void testApp::draw(){

ofSetColor(225);

ofSetColor(245, 58, 135);
ofFill();

ofPushMatrix();
//glEnable(GL_LIGHTI)

//we also pass in the mouse position
//we have to transform the coords to what the shader is expecting which is 0,0 in the center and y axis flipped.
shader.setUniform2f("mouse", mouseX - ofGetWidth()/2, ofGetHeight()/2-mouseY );
//we also pass in the mouse position
//we have to transform the coords to what the shader is expecting which is 0,0 in the center and y axis flipped.
shader.setUniform2f("mouse", mouseX - ofGetWidth()/2, ofGetHeight()/2-mouseY );
}else{
//we want to pass in some varrying values to animate our type / color

}

}

ofTranslate(ofGetWidth() / 4, ofGetHeight() / 4, 0);

if(isRotatingActive){
rotationX = mouseY;
rotationY = mouseX;
}

ofRotateX(rotationX);
ofRotateY(rotationY);

}else{
ofTranslate(ofGetWidth() / 3, ofGetHeight() / 3, 0);
}

//finally draw our text
//font.drawStringAsShapes("openFrameworks", 90, 260);

mesh.drawWireframe();

//ofSphere(200, 200, 0, 200);

if(USE_TRIANGLE_STRIPS)
vbo.drawElements(GL_TRIANGLE_STRIP, mesh.getNumIndices());
else
vbo.drawElements(GL_TRIANGLES, mesh.getNumIndices());

}
ofPopMatrix();

gui.draw();
}

//--------------------------------------------------------------
void testApp::keyPressed  (int key){
if( key == 's' ){
}

if( key == 'r' ){
isRotatingActive = !isRotatingActive;
}
}

``````

``````
#version 120

varying vec3 normal;
varying vec3 vertex_to_light_vector;
uniform int applyLighting;

void main(){
//this is where the pixel level drawing happens
//gl_FragCoord gives us the x and y of the current pixel its drawing

//we grab the x and y and store them in an int
//int xVal = int(gl_FragCoord.x);
//int yVal = int(gl_FragCoord.y);

//we use the mod function to only draw pixels if they are every 2 in x or every 4 in y
//if( mod(xVal, 2) == 0 && mod(yVal, 4) == 0 ){

if (applyLighting == 1) {
// Defining The Material Colors
vec4 AmbientColor = vec4(0.0, 0.0, 1.0, 1.0);
const vec4 DiffuseColor = vec4(1.0, 0.0, 0.0, 1.0);

// Scaling The Input Vector To Length 1
vec3 normalized_normal = normalize(normal);
vec3 normalized_vertex_to_light_vector = normalize(vertex_to_light_vector);

// Calculating The Diffuse Term And Clamping It To [0;1]
float DiffuseTerm = clamp(dot(normalized_normal, normalized_vertex_to_light_vector), 0.0, 1.0);

// Calculating The Final Color
gl_FragColor = AmbientColor + DiffuseColor * DiffuseTerm;
}else {
gl_FragColor = gl_Color;
}

//gl_FragColor = gl_Color;
//}

}

``````

``````
#version 120

uniform float timeValX = 1.0;
uniform float timeValY = 1.0;
uniform vec4 lightPosition;
uniform vec2 mouse;
varying vec3 normal;
varying vec3 vertex_to_light_vector;

//generate a random value from four points
vec4 rand(vec2 A,vec2 B,vec2 C,vec2 D){

vec2 s=vec2(12.9898,78.233);
vec4 tmp=vec4(dot(A,s),dot(B,s),dot(C,s),dot(D,s));

return fract(sin(tmp) * 43758.5453)* 2.0 - 1.0;
}

//this is similar to a perlin noise function
float noise(vec2 coord,float d){

vec2 C[4];

float d1 = 1.0/d;

C[0]=floor(coord*d)*d1;

C[1]=C[0]+vec2(d1,0.0);

C[2]=C[0]+vec2(d1,d1);

C[3]=C[0]+vec2(0.0,d1);

vec2 p=fract(coord*d);

vec2 q=1.0-p;

vec4 w=vec4(q.x*q.y,p.x*q.y,p.x*p.y,q.x*p.y);

return dot(vec4(rand(C[0],C[1],C[2],C[3])),w);
}

void main(){

gl_TexCoord[0] = gl_MultiTexCoord0;

//get our current vertex position so we can modify it
vec4 pos = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

//generate some noise values based on vertex position and the time value which comes in from our OF app
float noiseAmntX = noise( vec2(-timeValX + pos.x / 1000.0f, 100.0f), 20.0 );
float noiseAmntY = noise( vec2(timeValY + pos.y / 1000.0f, pos.x / 2000.0f), 20.0 );

//generate noise for our blue pixel value
float noiseB = noise( vec2(timeValY * 0.25, pos.y / 2000.0f), 20.0 );

//lets also figure out the distance between the mouse and the vertex and apply a repelling force away from the mouse
vec2 d = vec2(pos.x, pos.y) - mouse;
float len =  sqrt(d.x*d.x + d.y*d.y);
if( len < 300 && len > 0  ){

//lets get the distance into 0-1 ranges
float pct = len / 300.0;

//this turns our linear 0-1 value into a curved 0-1 value
pct *= pct;

//flip it so the closer we are the greater the repulsion
pct = 1.0 - pct;

//normalize our repulsion vector
d /= len;

//apply the repulsion to our position
pos.x += d.x * pct * 90.0f;
pos.y += d.y * pct * 90.0f;
}

//modify our position with the smooth noise
//pos.x += noiseAmntX * 20.0;
//pos.y += noiseAmntY * 10.0;

//finally set the pos to be that actual position rendered
gl_Position = pos;

//modify our color
vec4 col = gl_Color;
//col.b += noiseB;

// Transforming The Normal To ModelView-Space
normal = gl_NormalMatrix * gl_Normal;

// Transforming The Vertex Position To ModelView-Space
vec4 vertex_in_modelview_space = gl_ModelViewMatrix * gl_Vertex;

// Calculating The Vector From The Vertex Position To The Light Position
//vertex_to_light_vector = vec3(gl_LightSource[0].position - vertex_in_modelview_space);
//vec4 lightPosition = vec4(sin(timeValX), 1.0, -1.0, 0.0);
vertex_to_light_vector = vec3(lightPosition - vertex_in_modelview_space);

//vertex_to_light_vector = vec3(lightPosition - vertex_in_modelview_space);

//vertex_to_light_vector = normalize(vec3(gl_LightSource[0].position));

gl_FrontColor =  col;
}

``````

Sorry again for the SUPER delay

hi @rogerpala, i think could be useful anyway. In this post i learnt a lot trying to implement (with success!) the VBO by myself . Also could be fine if you post also the TestApp.h file and the other shader for convenience, or if you can put the files in a zipped form or on a github repo could be better.
best regards