Help end child hunger

OpenGL 3.3 + GLSL 1.5 Sample

 

This is a simple, yet complete, sample of code to draw two triangles using OpenGL 3.3 and GLSL 1.5. As far as I know the sample does not use any deprecated functions.

The sample covers Vertex Objects, Vertex Array Objects, Uniform and Attribute variables, shader setting, and definition of the camera and perspective matrices.

It uses GLUT to keep things simple (check out the GLUT tutorial if you’re not familiar with GLUT).

GLEW is also being used to provide access to the new OpenGL functions.

To load the shader text files we’re using simple C routines available in here.

First the shaders. These are an updated version of the color shader available in the GLSL 1.2 tutorial.

Vertex Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#version 150
 
uniform mat4 viewMatrix, projMatrix;
 
in vec4 position;
in vec3 color;
 
out vec3 Color;
 
void main()
{
    Color = color;
    gl_Position = projMatrix * viewMatrix * position ;
}

Fragment Shader

1
2
3
4
5
6
7
8
9
#version 150
 
in vec3 Color;
out vec4 outputF;
 
void main()
{
    outputF = vec4(Color,1.0);
}

And now the OpenGL 3.3 code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/*
 
  Simple GLSL 1.5 Demo
 
  www.lighthouse3d.com
 
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
 
#include "textfile.h"
 
#define M_PI       3.14159265358979323846
 
// Data for drawing Axis
float verticesAxis[] = {-20.0f, 0.0f, 0.0f, 1.0f,
            20.0f, 0.0f, 0.0f, 1.0f,
 
            0.0f, -20.0f, 0.0f, 1.0f,
            0.0f,  20.0f, 0.0f, 1.0f,
 
            0.0f, 0.0f, -20.0f, 1.0f,
            0.0f, 0.0f,  20.0f, 1.0f};
 
float colorAxis[] = {   0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f};
 
// Data for triangle 1
float vertices1[] = {   -3.0f, 0.0f, -5.0f, 1.0f,
            -1.0f, 0.0f, -5.0f, 1.0f,
            -2.0f, 2.0f, -5.0f, 1.0f};
 
float colors1[] = { 0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f,0.0f, 1.0f, 1.0f};
 
// Data for triangle 2
float vertices2[] = {   1.0f, 0.0f, -5.0f, 1.0f,
            3.0f, 0.0f, -5.0f, 1.0f,
            2.0f, 2.0f, -5.0f, 1.0f};
 
float colors2[] = { 1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f,0.0f, 0.0f, 1.0f};
 
// Shader Names
char *vertexFileName = "color.vert";
char *fragmentFileName = "color.frag";
 
// Program and Shader Identifiers
GLuint p,v,f;
 
// Vertex Attribute Locations
GLuint vertexLoc, colorLoc;
 
// Uniform variable Locations
GLuint projMatrixLoc, viewMatrixLoc;
 
// Vertex Array Objects Identifiers
GLuint vao[3];
 
// storage for Matrices
float projMatrix[16];
float viewMatrix[16];
 
// ----------------------------------------------------
// VECTOR STUFF
//
 
// res = a cross b;
void crossProduct( float *a, float *b, float *res) {
 
    res[0] = a[1] * b[2]  -  b[1] * a[2];
    res[1] = a[2] * b[0]  -  b[2] * a[0];
    res[2] = a[0] * b[1]  -  b[0] * a[1];
}
 
// Normalize a vec3
void normalize(float *a) {
 
    float mag = sqrt(a[0] * a[0]  +  a[1] * a[1]  +  a[2] * a[2]);
 
    a[0] /= mag;
    a[1] /= mag;
    a[2] /= mag;
}
 
// ----------------------------------------------------
// MATRIX STUFF
//
 
// sets the square matrix mat to the identity matrix,
// size refers to the number of rows (or columns)
void setIdentityMatrix( float *mat, int size) {
 
    // fill matrix with 0s
    for (int i = 0; i < size * size; ++i)
            mat[i] = 0.0f;
 
    // fill diagonal with 1s
    for (int i = 0; i < size; ++i)
        mat[i + i * size] = 1.0f;
}
 
//
// a = a * b;
//
void multMatrix(float *a, float *b) {
 
    float res[16];
 
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            res[j*4 + i] = 0.0f;
            for (int k = 0; k < 4; ++k) {
                res[j*4 + i] += a[k*4 + i] * b[j*4 + k];
            }
        }
    }
    memcpy(a, res, 16 * sizeof(float));
 
}
 
// Defines a transformation matrix mat with a translation
void setTranslationMatrix(float *mat, float x, float y, float z) {
 
    setIdentityMatrix(mat,4);
    mat[12] = x;
    mat[13] = y;
    mat[14] = z;
}
 
// ----------------------------------------------------
// Projection Matrix
//
 
void buildProjectionMatrix(float fov, float ratio, float nearP, float farP) {
 
    float f = 1.0f / tan (fov * (M_PI / 360.0));
 
    setIdentityMatrix(projMatrix,4);
 
    projMatrix[0] = f / ratio;
    projMatrix[1 * 4 + 1] = f;
    projMatrix[2 * 4 + 2] = (farP + nearP) / (nearP - farP);
    projMatrix[3 * 4 + 2] = (2.0f * farP * nearP) / (nearP - farP);
    projMatrix[2 * 4 + 3] = -1.0f;
    projMatrix[3 * 4 + 3] = 0.0f;
}
 
// ----------------------------------------------------
// View Matrix
//
// note: it assumes the camera is not tilted,
// i.e. a vertical up vector (remmeber gluLookAt?)
//
 
void setCamera(float posX, float posY, float posZ,
               float lookAtX, float lookAtY, float lookAtZ) {
 
    float dir[3], right[3], up[3];
 
    up[0] = 0.0f;   up[1] = 1.0f;   up[2] = 0.0f;
 
    dir[0] =  (lookAtX - posX);
    dir[1] =  (lookAtY - posY);
    dir[2] =  (lookAtZ - posZ);
    normalize(dir);
 
    crossProduct(dir,up,right);
    normalize(right);
 
    crossProduct(right,dir,up);
    normalize(up);
 
    float aux[16];
 
    viewMatrix[0]  = right[0];
    viewMatrix[4]  = right[1];
    viewMatrix[8]  = right[2];
    viewMatrix[12] = 0.0f;
 
    viewMatrix[1]  = up[0];
    viewMatrix[5]  = up[1];
    viewMatrix[9]  = up[2];
    viewMatrix[13] = 0.0f;
 
    viewMatrix[2]  = -dir[0];
    viewMatrix[6]  = -dir[1];
    viewMatrix[10] = -dir[2];
    viewMatrix[14] =  0.0f;
 
    viewMatrix[3]  = 0.0f;
    viewMatrix[7]  = 0.0f;
    viewMatrix[11] = 0.0f;
    viewMatrix[15] = 1.0f;
 
    setTranslationMatrix(aux, -posX, -posY, -posZ);
 
    multMatrix(viewMatrix, aux);
}
 
// ----------------------------------------------------
 
void changeSize(int w, int h) {
 
    float ratio;
    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(h == 0)
        h = 1;
 
    // Set the viewport to be the entire window
    glViewport(0, 0, w, h);
 
    ratio = (1.0f * w) / h;
    buildProjectionMatrix(53.13f, ratio, 1.0f, 30.0f);
}
 
void setupBuffers() {
 
    GLuint buffers[2];
 
    glGenVertexArrays(3, vao);
    //
    // VAO for first triangle
    //
    glBindVertexArray(vao[0]);
    // Generate two slots for the vertex and color buffers
    glGenBuffers(2, buffers);
    // bind buffer for vertices and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
    glEnableVertexAttribArray(vertexLoc);
    glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);
 
    // bind buffer for colors and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors1), colors1, GL_STATIC_DRAW);
    glEnableVertexAttribArray(colorLoc);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
 
    //
    // VAO for second triangle
    //
    glBindVertexArray(vao[1]);
    // Generate two slots for the vertex and color buffers
    glGenBuffers(2, buffers);
 
    // bind buffer for vertices and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
    glEnableVertexAttribArray(vertexLoc);
    glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);
 
    // bind buffer for colors and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW);
    glEnableVertexAttribArray(colorLoc);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
 
    //
    // This VAO is for the Axis
    //
    glBindVertexArray(vao[2]);
    // Generate two slots for the vertex and color buffers
    glGenBuffers(2, buffers);
    // bind buffer for vertices and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesAxis), verticesAxis, GL_STATIC_DRAW);
    glEnableVertexAttribArray(vertexLoc);
    glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, 0, 0, 0);
 
    // bind buffer for colors and copy data into buffer
    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colorAxis), colorAxis, GL_STATIC_DRAW);
    glEnableVertexAttribArray(colorLoc);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
 
}
 
void setUniforms() {
 
    // must be called after glUseProgram
    glUniformMatrix4fv(projMatrixLoc,  1, false, projMatrix);
    glUniformMatrix4fv(viewMatrixLoc,  1, false, viewMatrix);
}
 
void renderScene(void) {
 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    setCamera(10,2,10,0,2,-5);
 
    glUseProgram(p);
    setUniforms();
 
    glBindVertexArray(vao[0]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
 
    glBindVertexArray(vao[1]);
    glDrawArrays(GL_TRIANGLES, 0, 3);
 
    glBindVertexArray(vao[2]);
    glDrawArrays(GL_LINES, 0, 6);
 
    glutSwapBuffers();
}
 
void processNormalKeys(unsigned char key, int x, int y) {
 
    if (key == 27) {
        glDeleteVertexArrays(3,vao);
        glDeleteProgram(p);
        glDeleteShader(v);
        glDeleteShader(f);
        exit(0);
    }
}
 
#define printOpenGLError() printOglError(__FILE__, __LINE__)
 
int printOglError(char *file, int line)
{
    //
    // Returns 1 if an OpenGL error occurred, 0 otherwise.
    //
    GLenum glErr;
    int    retCode = 0;
 
    glErr = glGetError();
    while (glErr != GL_NO_ERROR)
    {
        printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    }
    return retCode;
}
 
void printShaderInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;
 
    glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
 
    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
        printf("%s\n",infoLog);
        free(infoLog);
    }
}
 
void printProgramInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;
 
    glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
 
    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
        printf("%s\n",infoLog);
        free(infoLog);
    }
}
 
GLuint setupShaders() {
 
    char *vs = NULL,*fs = NULL,*fs2 = NULL;
 
    GLuint p,v,f;
 
    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);
 
    vs = textFileRead(vertexFileName);
    fs = textFileRead(fragmentFileName);
 
    const char * vv = vs;
    const char * ff = fs;
 
    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);
 
    free(vs);free(fs);
 
    glCompileShader(v);
    glCompileShader(f);
 
    printShaderInfoLog(v);
    printShaderInfoLog(f);
 
    p = glCreateProgram();
    glAttachShader(p,v);
    glAttachShader(p,f);
 
    glBindFragDataLocation(p, 0, "outputF");
    glLinkProgram(p);
    printProgramInfoLog(p);
 
    vertexLoc = glGetAttribLocation(p,"position");
    colorLoc = glGetAttribLocation(p, "color");
 
    projMatrixLoc = glGetUniformLocation(p, "projMatrix");
    viewMatrixLoc = glGetUniformLocation(p, "viewMatrix");
 
    return(p);
}
 
int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("Lighthouse 3D");
 
    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutKeyboardFunc(processNormalKeys);
 
    glewInit();
    if (glewIsSupported("GL_VERSION_3_3"))
        printf("Ready for OpenGL 3.3\n");
    else {
        printf("OpenGL 3.3 not supported\n");
        exit(1);
    }
 
    glEnable(GL_DEPTH_TEST);
    glClearColor(1.0,1.0,1.0,1.0);
 
    p = setupShaders();
    setupBuffers();
 
    glutMainLoop();
 
    return(0);
}

  16 Responses to “OpenGL 3.3 + GLSL 1.5 Sample”

  1. Thanks for this great Tutorial and also thanks to @swilson for the port – its not really often that you paste a code and it works immediately. Very helpful!!! Since there isnt much on the net for jogl and OpenGL 3 upwards.

    So keep up the good work!
    Greets from Austria

  2. Quick java port using Jogl2.0rc11 for anyone interested:

    import static javax.media.opengl.GL.*;

    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;

    import javax.media.opengl.*;
    import javax.media.opengl.awt.*;

    import com.jogamp.common.nio.*;

    /**
    * This is a port of some sample code from:
    * http://www.lighthouse3d.com/cg-topics/code-samples/opengl-3-3-glsl-1-5-sample/
    */
    public class Gl3Sample implements GLEventListener {
    // Data for drawing Axis
    float verticesAxis[] = { -20.0f, 0.0f, 0.0f, 1.0f, 20.0f, 0.0f, 0.0f, 1.0f,

    0.0f, -20.0f, 0.0f, 1.0f, 0.0f, 20.0f, 0.0f, 1.0f,

    0.0f, 0.0f, -20.0f, 1.0f, 0.0f, 0.0f, 20.0f, 1.0f };

    float colorAxis[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.0f };

    // Data for triangle 1
    float vertices1[] = { -3.0f, 0.0f, -5.0f, 1.0f, -1.0f, 0.0f, -5.0f, 1.0f,
    -2.0f, 2.0f, -5.0f, 1.0f };

    float colors1[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 1.0f };

    // Data for triangle 2
    float vertices2[] = { 1.0f, 0.0f, -5.0f, 1.0f, 3.0f, 0.0f, -5.0f, 1.0f,
    2.0f, 2.0f, -5.0f, 1.0f };

    float colors2[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
    0.0f, 0.0f, 1.0f };

    // Shader Names
    String vertexFileName = “color.vert”;
    String fragmentFileName = “color.frag”;

    // Program and Shader Identifiers
    int p, v, f;

    // Vertex Attribute Locations
    int vertexLoc, colorLoc;

    // Uniform variable Locations
    int projMatrixLoc, viewMatrixLoc;

    // Vertex Array Objects Identifiers
    int vao[] = new int[3];

    // storage for Matrices
    float projMatrix[] = new float[16];
    float viewMatrix[] = new float[16];

    // —————————————————-
    // VECTOR STUFF
    //

    // res = a cross b;
    void crossProduct(float a[], float b[], float res[]) {

    res[0] = a[1] * b[2] – b[1] * a[2];
    res[1] = a[2] * b[0] – b[2] * a[0];
    res[2] = a[0] * b[1] – b[0] * a[1];
    }

    // Normalize a vec3
    void normalize(float a[]) {

    float mag = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);

    a[0] /= mag;
    a[1] /= mag;
    a[2] /= mag;
    }

    // —————————————————-
    // MATRIX STUFF
    //

    // sets the square matrix mat to the identity matrix,
    // size refers to the number of rows (or columns)
    void setIdentityMatrix(float[] mat, int size) {

    // fill matrix with 0s
    for (int i = 0; i < size * size; ++i)
    mat[i] = 0.0f;

    // fill diagonal with 1s
    for (int i = 0; i < size; ++i)
    mat[i + i * size] = 1.0f;
    }

    //
    // a = a * b;
    //
    void multMatrix(float[] a, float[] b) {

    float[] res = new float[16];

    for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
    res[j * 4 + i] = 0.0f;
    for (int k = 0; k < 4; ++k) {
    res[j * 4 + i] += a[k * 4 + i] * b[j * 4 + k];
    }
    }
    }

    System.arraycopy(res, 0, a, 0, 16);
    }

    // Defines a transformation matrix mat with a translation
    void setTranslationMatrix(float[] mat, float x, float y, float z) {

    setIdentityMatrix(mat, 4);
    mat[12] = x;
    mat[13] = y;
    mat[14] = z;
    }

    // —————————————————-
    // Projection Matrix
    //

    void buildProjectionMatrix(float fov, float ratio, float nearP, float farP) {

    float f = 1.0f / (float) Math.tan(fov * (Math.PI / 360.0));

    setIdentityMatrix(projMatrix, 4);

    projMatrix[0] = f / ratio;
    projMatrix[1 * 4 + 1] = f;
    projMatrix[2 * 4 + 2] = (farP + nearP) / (nearP – farP);
    projMatrix[3 * 4 + 2] = (2.0f * farP * nearP) / (nearP – farP);
    projMatrix[2 * 4 + 3] = -1.0f;
    projMatrix[3 * 4 + 3] = 0.0f;
    }

    // —————————————————-
    // View Matrix
    //
    // note: it assumes the camera is not tilted,
    // i.e. a vertical up vector (remmeber gluLookAt?)
    //

    void setCamera(float posX, float posY, float posZ, float lookAtX,
    float lookAtY, float lookAtZ) {

    float[] dir = new float[3];
    float[] right = new float[3];
    float[] up = new float[3];

    up[0] = 0.0f;
    up[1] = 1.0f;
    up[2] = 0.0f;

    dir[0] = (lookAtX – posX);
    dir[1] = (lookAtY – posY);
    dir[2] = (lookAtZ – posZ);
    normalize(dir);

    crossProduct(dir, up, right);
    normalize(right);

    crossProduct(right, dir, up);
    normalize(up);

    float[] aux = new float[16];

    viewMatrix[0] = right[0];
    viewMatrix[4] = right[1];
    viewMatrix[8] = right[2];
    viewMatrix[12] = 0.0f;

    viewMatrix[1] = up[0];
    viewMatrix[5] = up[1];
    viewMatrix[9] = up[2];
    viewMatrix[13] = 0.0f;

    viewMatrix[2] = -dir[0];
    viewMatrix[6] = -dir[1];
    viewMatrix[10] = -dir[2];
    viewMatrix[14] = 0.0f;

    viewMatrix[3] = 0.0f;
    viewMatrix[7] = 0.0f;
    viewMatrix[11] = 0.0f;
    viewMatrix[15] = 1.0f;

    setTranslationMatrix(aux, -posX, -posY, -posZ);

    multMatrix(viewMatrix, aux);
    }

    // —————————————————-

    void changeSize(GL3 gl, int w, int h) {

    float ratio;
    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if (h == 0)
    h = 1;

    // Set the viewport to be the entire window
    gl.glViewport(0, 0, w, h);

    ratio = (1.0f * w) / h;
    buildProjectionMatrix(53.13f, ratio, 1.0f, 30.0f);
    }

    void setupBuffers(GL3 gl) {

    int buffers[] = new int[2];
    gl.glGenVertexArrays(3, vao, 0);
    //
    // VAO for first triangle
    //
    gl.glBindVertexArray(vao[0]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);
    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, vertices1.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(vertices1), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colors1.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colors1), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    //
    // VAO for second triangle
    //
    gl.glBindVertexArray(vao[1]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);

    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, vertices2.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(vertices2), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colors2.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colors2), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    //
    // This VAO is for the Axis
    //
    gl.glBindVertexArray(vao[2]);
    // Generate two slots for the vertex and color buffers
    gl.glGenBuffers(2, buffers, 0);
    // bind buffer for vertices and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    gl.glBufferData(GL_ARRAY_BUFFER, verticesAxis.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(verticesAxis), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(vertexLoc);
    gl.glVertexAttribPointer(vertexLoc, 4, GL_FLOAT, false, 0, 0);

    // bind buffer for colors and copy data into buffer
    gl.glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    gl.glBufferData(GL_ARRAY_BUFFER, colorAxis.length * Float.SIZE / 8,
    Buffers.newDirectFloatBuffer(colorAxis), GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(colorLoc);
    gl.glVertexAttribPointer(colorLoc, 4, GL_FLOAT, false, 0, 0);

    }

    void setUniforms(GL3 gl) {

    // must be called after glUseProgram
    gl.glUniformMatrix4fv(projMatrixLoc, 1, false, projMatrix, 0);
    gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix, 0);
    }

    void renderScene(GL3 gl) {

    gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    setCamera(10, 2, 10, 0, 2, -5);

    gl.glUseProgram(p);
    setUniforms(gl);

    gl.glBindVertexArray(vao[0]);
    gl.glDrawArrays(GL_TRIANGLES, 0, 3);

    gl.glBindVertexArray(vao[1]);
    gl.glDrawArrays(GL_TRIANGLES, 0, 3);

    gl.glBindVertexArray(vao[2]);
    gl.glDrawArrays(GL_LINES, 0, 6);
    }

    /** Retrieves the info log for the shader */
    public String printShaderInfoLog(GL3 gl, int obj) {
    // Otherwise, we'll get the GL info log
    final int logLen = getShaderParameter(gl, obj, GL3.GL_INFO_LOG_LENGTH);
    if (logLen <= 0)
    return "";

    // Get the log
    final int[] retLength = new int[1];
    final byte[] bytes = new byte[logLen + 1];
    gl.glGetShaderInfoLog(obj, logLen, retLength, 0, bytes, 0);
    final String logMessage = new String(bytes);

    return String.format("ShaderLog: %s", logMessage);
    }

    /** Get a shader parameter value. See 'glGetShaderiv' */
    private int getShaderParameter(GL3 gl, int obj, int paramName) {
    final int params[] = new int[1];
    gl.glGetShaderiv(obj, paramName, params, 0);
    return params[0];
    }

    /** Retrieves the info log for the program */
    public String printProgramInfoLog(GL3 gl, int obj) {
    // get the GL info log
    final int logLen = getProgramParameter(gl, obj, GL3.GL_INFO_LOG_LENGTH);
    if (logLen <= 0)
    return "";

    // Get the log
    final int[] retLength = new int[1];
    final byte[] bytes = new byte[logLen + 1];
    gl.glGetProgramInfoLog(obj, logLen, retLength, 0, bytes, 0);
    final String logMessage = new String(bytes);

    return logMessage;
    }

    /** Gets a program parameter value */
    public int getProgramParameter(GL3 gl, int obj, int paramName) {
    final int params[] = new int[1];
    gl.glGetProgramiv(obj, paramName, params, 0);
    return params[0];
    }

    public String textFileRead(String filePath) {
    // Read the data in
    BufferedReader reader = null;
    try {
    // Read in the source
    reader = new BufferedReader(new FileReader(filePath));
    final StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null)
    sb.append(line).append("\n");
    final String text = sb.toString();

    return text;

    } catch (final Exception ex) {
    ex.printStackTrace();

    } finally {
    try {
    reader.close();
    } catch (final Exception ex) {
    }
    }

    return "";
    }

    int setupShaders(GL3 gl) {

    String vs = null;
    String fs = null;
    String fs2 = null;

    int p, v, f;

    v = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
    f = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);

    vs = textFileRead(vertexFileName);
    fs = textFileRead(fragmentFileName);

    String vv = vs;
    String ff = fs;

    gl.glShaderSource(v, 1, new String[] { vv }, null);
    gl.glShaderSource(f, 1, new String[] { ff }, null);

    gl.glCompileShader(v);
    gl.glCompileShader(f);

    printShaderInfoLog(gl, v);
    printShaderInfoLog(gl, f);

    p = gl.glCreateProgram();
    gl.glAttachShader(p, v);
    gl.glAttachShader(p, f);

    gl.glBindFragDataLocation(p, 0, "outputF");
    gl.glLinkProgram(p);
    printProgramInfoLog(gl, p);

    vertexLoc = gl.glGetAttribLocation(p, "position");
    colorLoc = gl.glGetAttribLocation(p, "color");

    projMatrixLoc = gl.glGetUniformLocation(p, "projMatrix");
    viewMatrixLoc = gl.glGetUniformLocation(p, "viewMatrix");

    return (p);
    }

    /** GL Init */
    @Override
    public void init(GLAutoDrawable drawable) {
    GL3 gl = drawable.getGL().getGL3();
    gl.glEnable(GL_DEPTH_TEST);
    gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

    p = setupShaders(gl);
    setupBuffers(gl);
    }

    /** GL Window Reshape */
    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width,
    int height) {
    GL3 gl = drawable.getGL().getGL3();
    changeSize(gl, width, height);
    }

    /** GL Render loop */
    @Override
    public void display(GLAutoDrawable drawable) {
    GL3 gl = drawable.getGL().getGL3();
    renderScene(gl);
    }

    /** GL Complete */
    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

    /** Main entry point for the application */
    public static void main(String[] args) {
    Gl3Sample sample = new Gl3Sample();

    GLProfile glp = GLProfile.get(GLProfile.GL3);
    GLCapabilities glCapabilities = new GLCapabilities(glp);
    final GLCanvas glCanvas = new GLCanvas(glCapabilities);
    final Frame frame = new Frame("GL3 Test");
    glCanvas.addGLEventListener(sample);

    frame.add(glCanvas);
    frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent windowevent) {
    frame.remove(glCanvas);
    frame.dispose();
    System.exit(0);
    }
    });

    frame.setSize(320, 320);
    frame.setVisible(true);
    }
    }

  3. Now runs, but crash everytime in this line: memcpy(&faceArray[faceIndex], face->mIndices,3 * sizeof(float));

    Do you have a solution maybe?

  4. textfile.h not found, ERROR! 🙁

  5. near and far are reserved keywords, at least in VS2010

  6. Hi!
    This is super interesting suff 😀 I’m mosly new to all of this so I’m not sure how this works. When compiling and running your program I get a blank white screen, even tho it semes to succesfully load the object. Have his something to do with the output being a reserved word error (fragment sahder compilation error #133) or is it the cameras default possition or somehing? I have not edited the code in any way. Tnx 🙂

  7. ” gl_Position = projMatrix * viewMatrix * position ; ”

    ^^ the projection matrix and modelview matrices are probably in the wrong order

    • The projection matrix is the last matrix to be applied. The point (position) must be first transformed by the view matrix.

  8. I am new to open gl and trying to implement a code where i load obj ussing assimp and perform transformation on it, i am getting struck since my basic r not very clear is this the right forum to get help

    My code compile in debug it displays the model take the key input but never performs any transformation

  9. Just tried the shaders in Shader Maker and got:
    Fragment shader failed to compile with the following errors:
    ERROR: 0:5: error(#133) Reserved word: output
    ERROR: 0:5: error(#132) Syntax error: ‘output’ parse error
    ERROR: error(#273) 2 compilation errors. No code generated
    The GL info shows
    ….
    Renderer: ATI Radeon HD 4550
    Version: 3.3.11079 Compatibility Profile Context

    • Yes, you’re right. It works fine with NVIDIA, but not with ATI. Actually ATI is right, since “output” is a reserved word.

      Thanks for the comment.

Leave a Reply to wolfgaung Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: