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
#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
#version 150 in vec3 Color; out vec4 outputF; void main() { outputF = vec4(Color,1.0); }
And now the OpenGL 3.3 code:
/* 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); }
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
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);
}
}
Thanks. Great work.
Now runs, but crash everytime in this line: memcpy(&faceArray[faceIndex], face->mIndices,3 * sizeof(float));
Do you have a solution maybe?
Hi, Where is that line?
Somewhere in project. Anyway thanks for your help, but I already use another tutorial.
textfile.h not found, ERROR! 🙁
Hi,
There is a link on the top of the page to download both textfile header and source.
near and far are reserved keywords, at least in VS2010
Thanks. Fixed it.
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 🙂
” 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.
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
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.