diff options
| author | Manolo Gouy <Manolo> | 2015-10-27 08:40:56 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2015-10-27 08:40:56 +0000 |
| commit | 7e025aac22338ae573174d67e0c03e085c16630f (patch) | |
| tree | ceed51c15e935fc4a404bd4bb217f01aa55cdc79 /examples | |
| parent | 43e4f8a6615892a5169f4e713a0d7a2a2e2d86e1 (diff) | |
Added support for OpenGL V3 and higher.
On the X11/MSWindows platforms, this requires external installation of the GLEW library.
This fixes STR#3198 and STR#3257.
Added two new examples programs.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10876 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/OpenGL3-glut-test.cxx | 199 | ||||
| -rw-r--r-- | examples/OpenGL3test.cxx | 209 |
2 files changed, 408 insertions, 0 deletions
diff --git a/examples/OpenGL3-glut-test.cxx b/examples/OpenGL3-glut-test.cxx new file mode 100644 index 000000000..f455eaf56 --- /dev/null +++ b/examples/OpenGL3-glut-test.cxx @@ -0,0 +1,199 @@ +#include <stdio.h> +#if defined(__APPLE__) +# include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions +#else +# if defined(WIN32) +# define GLEW_STATIC 1 +# endif +# include <GL/glew.h> +#endif +#include <FL/glut.H> + + +// Globals +// Real programs don't use globals :-D +// Data would normally be read from files +GLfloat vertices[] = { -1.0f,0.0f,0.0f, + 0.0f,1.0f,0.0f, + 0.0f,0.0f,0.0f }; +GLfloat colours[] = { 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f }; +GLfloat vertices2[] = { 0.0f,0.0f,0.0f, + 0.0f,-1.0f,0.0f, + 1.0f,0.0f,0.0f }; + +// two vertex array objects, one for each object drawn +unsigned int vertexArrayObjID[2]; +// three vertex buffer objects in this example +unsigned int vertexBufferObjID[3]; + + +void printShaderInfoLog(GLint shader) +{ + int infoLogLen = 0; + GLchar *infoLog; + + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen); + if (infoLogLen > 0) + { + infoLog = new GLchar[infoLogLen]; + // error check for fail to allocate memory omitted + glGetShaderInfoLog(shader,infoLogLen, NULL, infoLog); + fprintf(stderr, "InfoLog:\n%s\n", infoLog); + delete [] infoLog; + } +} + + +void init(void) +{ + // Would load objects from file here - but using globals in this example + + // Allocate Vertex Array Objects + glGenVertexArrays(2, &vertexArrayObjID[0]); + // Setup first Vertex Array Object + glBindVertexArray(vertexArrayObjID[0]); + glGenBuffers(2, vertexBufferObjID); + + // VBO for vertex data + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[0]); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW); + glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + // VBO for colour data + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[1]); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), colours, GL_STATIC_DRAW); + glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(1); + + // Setup second Vertex Array Object + glBindVertexArray(vertexArrayObjID[1]); + glGenBuffers(1, &vertexBufferObjID[2]); + + // VBO for vertex data + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[2]); + glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices2, GL_STATIC_DRAW); + glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glBindVertexArray(0); +} + + +void initShaders(void) +{ + GLuint p, f, v; + glClearColor (1.0, 1.0, 1.0, 0.0); + + v = glCreateShader(GL_VERTEX_SHADER); + f = glCreateShader(GL_FRAGMENT_SHADER); + +#ifdef __APPLE__ +#define SHADING_LANG_VERS "140" +#else +#define SHADING_LANG_VERS "130" +#endif + // load shaders + const char *vv = "#version "SHADING_LANG_VERS"\n\ + in vec3 in_Position;\ + in vec3 in_Color;\ + out vec3 ex_Color;\ + void main(void)\ + {\ + ex_Color = in_Color;\ + gl_Position = vec4(in_Position, 1.0);\ + }"; + + const char *ff = "#version "SHADING_LANG_VERS"\n\ + precision highp float;\ + in vec3 ex_Color;\ + out vec4 out_Color;\ + void main(void)\ + {\ + out_Color = vec4(ex_Color,1.0);\ + }"; + + glShaderSource(v, 1, &vv,NULL); + glShaderSource(f, 1, &ff,NULL); + + GLint compiled; + + glCompileShader(v); + glGetShaderiv(v, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + fprintf(stderr, "Vertex shader not compiled.\n"); + printShaderInfoLog(v); + } + + glCompileShader(f); + glGetShaderiv(f, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + fprintf(stderr, "Fragment shader not compiled.\n"); + printShaderInfoLog(f); + } + + p = glCreateProgram(); + + glAttachShader(p,v); + glAttachShader(p,f); + glBindAttribLocation(p,0, "in_Position"); + glBindAttribLocation(p,1, "in_Color"); + + glLinkProgram(p); + glGetProgramiv(p, GL_LINK_STATUS, &compiled); + if (compiled != GL_TRUE) { + GLchar *infoLog; GLint length; + glGetProgramiv(p, GL_INFO_LOG_LENGTH, &length); + infoLog = new GLchar[length]; + glGetProgramInfoLog(p, length, NULL, infoLog); + fprintf(stderr, "Link log=%s\n", infoLog); + delete[] infoLog; + } + glUseProgram(p); +} + + +void display(void) +{ + // clear the screen + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArray(vertexArrayObjID[0]); // First VAO + glDrawArrays(GL_TRIANGLES, 0, 3); // draw first object + + glBindVertexArray(vertexArrayObjID[1]); // select second VAO + glVertexAttrib3f((GLuint)1, 1.0, 0.0, 0.0); // set constant color attribute + glDrawArrays(GL_TRIANGLES, 0, 3); // draw second object + } + + +int main (int argc, char* argv[]) +{ + Fl::use_high_res_GL(true); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | FL_OPENGL3); + glutInitWindowSize(400,400); + glutCreateWindow("Triangle Test"); +#ifndef __APPLE__ + GLenum err = glewInit(); // defines pters to functions of OpenGL V 1.2 and above + if (err) Fl::error("glewInit() failed returning %u", err); + fprintf(stderr, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); +#endif + int gl_version_major; + const char *glv = (const char*)glGetString(GL_VERSION); + fprintf(stderr, "OpenGL version %s supported\n", glv); + sscanf(glv, "%d", &gl_version_major); + if (gl_version_major < 3) { + fprintf(stderr, "\nThis platform does not support OpenGL V3\n\n"); + exit(1); + } + initShaders(); + init(); + glutDisplayFunc(display); + glutMainLoop(); + return 0; +} diff --git a/examples/OpenGL3test.cxx b/examples/OpenGL3test.cxx new file mode 100644 index 000000000..0699d39cb --- /dev/null +++ b/examples/OpenGL3test.cxx @@ -0,0 +1,209 @@ +#include <stdarg.h> +#include <FL/Fl.H> +#include <FL/x.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Gl_Window.H> +#include <FL/Fl_Light_Button.H> +#include <FL/Fl_Text_Display.H> +#include <FL/Fl_Text_Buffer.H> +#if defined(__APPLE__) +# include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions +#else +# if defined(WIN32) +# define GLEW_STATIC 1 +# endif +# include <GL/glew.h> +#endif + + +void add_output(const char *format, ...); + + +class SimpleGL3Window : public Fl_Gl_Window { + GLuint shaderProgram; + GLuint vertexArrayObject; + GLuint vertexBuffer; + GLint positionUniform; + GLint colourAttribute; + GLint positionAttribute; + int gl_version_major; +public: + SimpleGL3Window(int x, int y, int w, int h) : Fl_Gl_Window(x, y, w, h) { + mode(FL_RGB8 | FL_DOUBLE | FL_OPENGL3); + shaderProgram = 0; + } + void draw(void) { + if (gl_version_major < 3) return; + if (!shaderProgram) { + GLuint vs; + GLuint fs; + int Mslv, mslv; // major and minor version numbers of the shading language + sscanf((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), "%d.%d", &Mslv, &mslv); + add_output("Shading Language Version=%d.%d\n",Mslv, mslv); + const char *vss_format="#version %d%d\n\ + uniform vec2 p;\ + in vec4 position;\ + in vec4 colour;\ + out vec4 colourV;\ + void main (void)\ + {\ + colourV = colour;\ + gl_Position = vec4(p, 0.0, 0.0) + position;\ + }"; + char vss_string[300]; const char *vss = vss_string; + sprintf(vss_string, vss_format, Mslv, mslv); + const char *fss_format="#version %d%d\n\ + in vec4 colourV;\ + out vec4 fragColour;\ + void main(void)\ + {\ + fragColour = colourV;\ + }"; + char fss_string[200]; const char *fss = fss_string; + sprintf(fss_string, fss_format, Mslv, mslv); + GLint err; GLchar CLOG[1000]; GLsizei length; + vs = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vs, 1, &vss, NULL); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &err); + if (err != GL_TRUE) { + glGetShaderInfoLog(vs, sizeof(CLOG), &length, CLOG); + add_output("vs ShaderInfoLog=%s\n",CLOG); + } + fs = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fs, 1, &fss, NULL); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &err); + if (err != GL_TRUE) { + glGetShaderInfoLog(fs, sizeof(CLOG), &length, CLOG); + add_output("fs ShaderInfoLog=%s\n",CLOG); + } + // Attach the shaders + shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vs); + glAttachShader(shaderProgram, fs); + glBindFragDataLocation(shaderProgram, 0, "fragColour"); + glLinkProgram(shaderProgram); + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &err); + if (err != GL_TRUE) { + glGetProgramInfoLog(shaderProgram, sizeof(CLOG), &length, CLOG); + add_output("link log=%s\n", CLOG); + } + // Get pointers to uniforms and attributes + positionUniform = glGetUniformLocation(shaderProgram, "p"); + colourAttribute = glGetAttribLocation(shaderProgram, "colour"); + positionAttribute = glGetAttribLocation(shaderProgram, "position"); + glDeleteShader(vs); + glDeleteShader(fs); + // Upload vertices (1st four values in a row) and colours (following four values) + GLfloat vertexData[]= { -0.5,-0.5,0.0,1.0, 1.0,0.0,0.0,1.0, + -0.5, 0.5,0.0,1.0, 0.0,1.0,0.0,1.0, + 0.5, 0.5,0.0,1.0, 0.0,0.0,1.0,1.0, + 0.5,-0.5,0.0,1.0, 1.0,1.0,1.0,1.0}; + glGenVertexArrays(1, &vertexArrayObject); + glBindVertexArray(vertexArrayObject); + + glGenBuffers(1, &vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, 4*8*sizeof(GLfloat), vertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray((GLuint)positionAttribute); + glEnableVertexAttribArray((GLuint)colourAttribute ); + glVertexAttribPointer((GLuint)positionAttribute, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), 0); + glVertexAttribPointer((GLuint)colourAttribute , 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0+4*sizeof(GLfloat)); + } + else if ((!valid())) { + glViewport(0, 0, pixel_w(), pixel_h()); + } + glClearColor(0.08, 0.8, 0.8, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(shaderProgram); + GLfloat p[]={0,0}; + glUniform2fv(positionUniform, 1, (const GLfloat *)&p); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + virtual int handle(int event) { + static int first = 1; + if (first && event == FL_SHOW && shown()) { + first = 0; + make_current(); +#ifndef __APPLE__ + GLenum err = glewInit(); // defines pters to functions of OpenGL V 1.2 and above + if (err) Fl::warning("glewInit() failed returning %u", err); + else add_output("Using GLEW %s\n", glewGetString(GLEW_VERSION)); +#endif + const uchar *glv = glGetString(GL_VERSION); + add_output("GL_VERSION=%s\n", glv); + sscanf((const char *)glv, "%d", &gl_version_major); + if (gl_version_major < 3) add_output("\nThis platform does not support OpenGL V3\n\n"); + } + + if (event == FL_PUSH && gl_version_major >= 3) { + static float factor = 1.1; + GLfloat data[4]; + glGetBufferSubData(GL_ARRAY_BUFFER, 0, 4*sizeof(GLfloat), data); + if (data[0] < -0.88 || data[0] > -0.5) factor = 1/factor; + data[0] *= factor; + glBufferSubData(GL_ARRAY_BUFFER, 0, 4*sizeof(GLfloat), data); + glGetBufferSubData(GL_ARRAY_BUFFER, 24*sizeof(GLfloat), 4*sizeof(GLfloat), data); + data[0] *= factor; + glBufferSubData(GL_ARRAY_BUFFER, 24*sizeof(GLfloat), 4*sizeof(GLfloat), data); + redraw(); + add_output("push\n"); + return 1; + } + return Fl_Gl_Window::handle(event); + } + void reset(void) { shaderProgram = 0; } +}; + + +void toggle_double(Fl_Widget *wid, void *data) { + static bool doublebuff = true; + doublebuff = !doublebuff; + SimpleGL3Window *glwin = (SimpleGL3Window*)data; + int flags = glwin->mode(); + if (doublebuff) flags |= FL_DOUBLE; else flags &= ~FL_DOUBLE; + glwin->mode(flags); + glwin->reset(); +} + + +Fl_Text_Display *output; // shared between output_win() and add_output() + +void output_win(SimpleGL3Window *gl) +{ + output = new Fl_Text_Display(300,0,500, 280); + Fl_Light_Button *lb = new Fl_Light_Button(300, 280, 500, 20, "Double-Buffered"); + lb->callback(toggle_double); + lb->user_data(gl); + lb->value(1); + output->buffer(new Fl_Text_Buffer()); +} + + +void add_output(const char *format, ...) +{ + va_list args; + char line_buffer[10000]; + va_start(args, format); + vsnprintf(line_buffer, sizeof(line_buffer)-1, format, args); + va_end(args); + output->insert(line_buffer); + output->redraw(); +} + + +int main(int argc, char **argv) +{ + Fl::use_high_res_GL(1); + Fl_Window *topwin = new Fl_Window(800, 300); + SimpleGL3Window *win = new SimpleGL3Window(0, 0, 300, 300); + win->end(); + output_win(win); + topwin->end(); + topwin->resizable(win); + topwin->label("Click GL panel to reshape"); + topwin->show(argc, argv); + Fl::run(); +} |
