fltk/examples/OpenGL3-glut-test.cxx

227 lines
6.2 KiB
C++

//
// Tiny OpenGL v3 + glut demo program for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2024 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include <FL/platform.H>
#if defined(__APPLE__)
# define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED 1
# include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions
#else
// Note: GLEW_STATIC is defined by CMake if the static lib is linked
# include <GL/glew.h>
#endif
#include <FL/glut.H>
#include <FL/fl_ask.H>
#include <stdio.h>
#include <stdlib.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 fullscreen = 0;
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
#ifdef FLTK_USE_WAYLAND
if (fl_wl_display() && err == GLEW_ERROR_NO_GLX_DISPLAY) err = GLEW_OK;
#endif
if (err != GLEW_OK) 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);
sscanf(glv, "%d", &gl_version_major);
fprintf(stderr, "OpenGL version %s supported\n", glv);
if (gl_version_major < 3) {
fprintf(stderr, "\nThis platform does not support OpenGL V3\n\n");
fflush(stderr);
// ensure that users see a message on Windows w/o console output:
fl_alert("OpenGL version %s supported.\n"
"This platform does not support OpenGL V3!",glv);
exit(1);
}
initShaders();
init();
glutDisplayFunc(display);
if (fullscreen) Fl::first_window()->fullscreen();
glutMainLoop();
return 0;
}