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
This commit is contained in:
parent
43e4f8a661
commit
7e025aac22
@ -1094,7 +1094,8 @@ enum Fl_Mode {
|
|||||||
FL_RGB8 = 64,
|
FL_RGB8 = 64,
|
||||||
FL_MULTISAMPLE= 128,
|
FL_MULTISAMPLE= 128,
|
||||||
FL_STEREO = 256,
|
FL_STEREO = 256,
|
||||||
FL_FAKE_SINGLE = 512 // Fake single buffered windows using double-buffer
|
FL_FAKE_SINGLE = 512, // Fake single buffered windows using double-buffer
|
||||||
|
FL_OPENGL3 = 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
// image alpha blending
|
// image alpha blending
|
||||||
|
@ -149,6 +149,7 @@ public:
|
|||||||
- \c FL_DEPTH - depth buffer
|
- \c FL_DEPTH - depth buffer
|
||||||
- \c FL_STENCIL - stencil buffer
|
- \c FL_STENCIL - stencil buffer
|
||||||
- \c FL_MULTISAMPLE - multisample antialiasing
|
- \c FL_MULTISAMPLE - multisample antialiasing
|
||||||
|
- \c FL_OPENGL3 - use OpenGL version 3.0 or more when running Mac OS.
|
||||||
|
|
||||||
FL_RGB and FL_SINGLE have a value of zero, so they
|
FL_RGB and FL_SINGLE have a value of zero, so they
|
||||||
are "on" unless you give FL_INDEX or FL_DOUBLE.
|
are "on" unless you give FL_INDEX or FL_DOUBLE.
|
||||||
@ -167,6 +168,19 @@ public:
|
|||||||
|
|
||||||
mode() must not be called within draw() since it
|
mode() must not be called within draw() since it
|
||||||
changes the current context.
|
changes the current context.
|
||||||
|
|
||||||
|
\note On the <b>MSWindows and Unix/Linux platforms</b>, FLTK produces
|
||||||
|
contexts for the highest OpenGL version supported by the hardware. Such contexts
|
||||||
|
are also compatible with lower OpenGL versions. On the <b>Apple OS X
|
||||||
|
platform</b>, it is necessary to decide whether the source code targets
|
||||||
|
OpenGL versions higher or lower than 3.0. By default, FLTK
|
||||||
|
creates contexts adequate for OpenGL versions 1 and 2. To get contexts
|
||||||
|
for OpenGL 3.0 or higher, the <tt>FL_OPENGL3</tt> flag and Mac OS
|
||||||
|
version 10.7 or higher are required (in that case the context is NOT
|
||||||
|
compatible with OpenGL versions 1 or 2). The <tt>FL_OPENGL3</tt> flag has no
|
||||||
|
effect on non-Apple platforms.
|
||||||
|
|
||||||
|
\version the <tt>FL_OPENGL3</tt> flag appeared in version 1.3.4
|
||||||
*/
|
*/
|
||||||
int mode(int a) {return mode(a,0);}
|
int mode(int a) {return mode(a,0);}
|
||||||
/** Set the OpenGL capabilites of the window using platform-specific data.
|
/** Set the OpenGL capabilites of the window using platform-specific data.
|
||||||
@ -179,8 +193,6 @@ public:
|
|||||||
<p><b>Mac OS X platform</b>: attributes belong to the <tt>CGLPixelFormatAttribute</tt> enumeration
|
<p><b>Mac OS X platform</b>: attributes belong to the <tt>CGLPixelFormatAttribute</tt> enumeration
|
||||||
(defined by including <tt><OpenGL/OpenGL.h></tt>, e.g., <tt>kCGLPFADoubleBuffer</tt>)
|
(defined by including <tt><OpenGL/OpenGL.h></tt>, e.g., <tt>kCGLPFADoubleBuffer</tt>)
|
||||||
and may be followed by adequate attribute values.
|
and may be followed by adequate attribute values.
|
||||||
The pair <tt>kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core</tt> allows to create an OpenGL V3.2 profile
|
|
||||||
under Mac OS X 10.7 and above (and include <OpenGL/gl3.h> to define OpenGL 3 symbols).
|
|
||||||
*/
|
*/
|
||||||
int mode(const int *a) {return mode(0, a);}
|
int mode(const int *a) {return mode(0, a);}
|
||||||
/** Returns a pointer to the GLContext that this window is using.
|
/** Returns a pointer to the GLContext that this window is using.
|
||||||
|
@ -449,6 +449,73 @@ The \p scene() method sets the scene to be drawn. The scene is
|
|||||||
a collection of 3D objects in a \p csGroup. The scene is redrawn
|
a collection of 3D objects in a \p csGroup. The scene is redrawn
|
||||||
after this call.
|
after this call.
|
||||||
|
|
||||||
|
\section opengl3 Using OpenGL 3.0 (or higher versions)
|
||||||
|
|
||||||
|
The examples subdirectory contains OpenGL3test.cxx, a toy program
|
||||||
|
showing how to use OpenGL 3.0 (or higher versions) with FLTK in a cross-platform fashion.
|
||||||
|
It contains also OpenGL3-glut-test.cxx which shows how to use FLTK's GLUT compatibility
|
||||||
|
and OpenGL 3.
|
||||||
|
|
||||||
|
<b>On the MSWindows and Unix/Linux platforms</b>, FLTK creates contexts implementing
|
||||||
|
the highest OpenGL version supported by the hardware,
|
||||||
|
which are also compatible with lower OpenGL versions. Thus, FLTK allows
|
||||||
|
source code targeting any version of OpenGL. Access to functions from OpenGL versions above 1.1 requires to load function pointers at runtime on these platforms. FLTK recommends to use the GLEW library to perform this. It is therefore
|
||||||
|
necessary to install the GLEW library (see below). <b>On the Mac OS X platform</b>,
|
||||||
|
FLTK creates by default contexts implementing OpenGL versions 1 or 2.
|
||||||
|
To access OpenGL 3.0 (or higher versions), use the <tt>FL_OPENGL3</tt> flag (see below).
|
||||||
|
Mac OS 10.7 or above is required; GLEW is possible but not necessary.
|
||||||
|
|
||||||
|
\par GLEW installation (Unix/Linux and MSWindows platforms)
|
||||||
|
GLEW is available as a package for most Linux distributions and in source form at http://glew.sourceforge.net/.
|
||||||
|
For the MSWindows platform, a Visual Studio static library (glew32.lib) can be downloaded from the same web site; a MinGW-style static library (libglew32.a) can be built from source with the make command.
|
||||||
|
|
||||||
|
\par Source-level changes for OpenGL 3:
|
||||||
|
\li Put this in all OpenGL-using source files (instead of \#include <FL/gl.h>,
|
||||||
|
and before \#include <FL/glut.h> if you use GLUT):
|
||||||
|
\code
|
||||||
|
#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
|
||||||
|
\endcode
|
||||||
|
\li Add the <tt>FL_OPENGL3</tt> flag when calling Fl_Gl_Window::mode(int a)
|
||||||
|
or glutInitDisplayMode().
|
||||||
|
\li Put this in the <tt>handle(int event)</tt> member function of the first to be created
|
||||||
|
among your Fl_Gl_Window-derived classes:
|
||||||
|
\code
|
||||||
|
#ifndef __APPLE__
|
||||||
|
static int first = 1;
|
||||||
|
if (first && event == FL_SHOW && shown()) {
|
||||||
|
first = 0;
|
||||||
|
make_current();
|
||||||
|
glewInit(); // defines pters to functions of OpenGL V 1.2 and above
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
\endcode
|
||||||
|
\li Alternatively, if you use GLUT, put
|
||||||
|
\code
|
||||||
|
#ifndef __APPLE__
|
||||||
|
glewInit(); // defines pters to functions of OpenGL V 1.2 and above
|
||||||
|
#endif
|
||||||
|
\endcode
|
||||||
|
after the first glutCreateWindow() call.
|
||||||
|
|
||||||
|
If GLEW is installed on the Mac OS development platform, it is possible
|
||||||
|
to use the same code for all platforms, with one exception: put
|
||||||
|
\code
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glewExperimental = TRUE;
|
||||||
|
#endif
|
||||||
|
\endcode
|
||||||
|
before the glewInit() call.
|
||||||
|
|
||||||
|
\par Changes in the build process
|
||||||
|
Link with libGLEW.so (on Unix/Linux), libglew32.a (with MinGW) or glew32.lib
|
||||||
|
(with MS Visual Studio); no change is needed on the Mac OS platform.
|
||||||
|
|
||||||
\htmlonly
|
\htmlonly
|
||||||
<hr>
|
<hr>
|
||||||
|
199
examples/OpenGL3-glut-test.cxx
Normal file
199
examples/OpenGL3-glut-test.cxx
Normal file
@ -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;
|
||||||
|
}
|
209
examples/OpenGL3test.cxx
Normal file
209
examples/OpenGL3test.cxx
Normal file
@ -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();
|
||||||
|
}
|
@ -2718,11 +2718,12 @@ NSOpenGLPixelFormat* Fl_X::mode_to_NSOpenGLPixelFormat(int m, const int *alistp)
|
|||||||
#define NSOpenGLPFAOpenGLProfile (NSOpenGLPixelFormatAttribute)99
|
#define NSOpenGLPFAOpenGLProfile (NSOpenGLPixelFormatAttribute)99
|
||||||
#define kCGLPFAOpenGLProfile NSOpenGLPFAOpenGLProfile
|
#define kCGLPFAOpenGLProfile NSOpenGLPFAOpenGLProfile
|
||||||
#define NSOpenGLProfileVersionLegacy (NSOpenGLPixelFormatAttribute)0x1000
|
#define NSOpenGLProfileVersionLegacy (NSOpenGLPixelFormatAttribute)0x1000
|
||||||
|
#define NSOpenGLProfileVersion3_2Core (NSOpenGLPixelFormatAttribute)0x3200
|
||||||
#define kCGLOGLPVersion_Legacy NSOpenGLProfileVersionLegacy
|
#define kCGLOGLPVersion_Legacy NSOpenGLProfileVersionLegacy
|
||||||
#endif
|
#endif
|
||||||
if (fl_mac_os_version >= 100700) {
|
if (fl_mac_os_version >= 100700) {
|
||||||
attribs[n++] = NSOpenGLPFAOpenGLProfile;
|
attribs[n++] = NSOpenGLPFAOpenGLProfile;
|
||||||
attribs[n++] = NSOpenGLProfileVersionLegacy; // for now, no public FLTK API for OpenGL v3 profiles
|
attribs[n++] = (m & FL_OPENGL3) ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (alistp[n] && n < 30) {
|
while (alistp[n] && n < 30) {
|
||||||
|
Loading…
Reference in New Issue
Block a user