Hey guys. I mixed two “tutorials” together to get the advantage of both, but this doesn’t work for me.
It’s Glutdualwindow.c by Eric Stringer 2002 to get 2 Windows. And [URL=“OpenGL Programming/Modern OpenGL Tutorial 06 - Wikibooks, open books for an open world”]. Since I am not very experienced, I am really stuck now.
Somewhere I seem to crash the program by overwriting a buffer or something.
Basically I just want to put the texture stuff into the second window, while void display_1(void)
remains unchanged.
Both tutorials alone work proper.
// Glutdualwindow.c
// By Eric Stringer 2002
// Simple examples of OpenGL and Glut usage.
// Keyboard input
// 'v' = view ortho/perspective
// 'l' = lighting on/off
//#include <windows.h> // This header file will be needed for some windows compilers
//#include <GL/gl.h> // gl.h and glu.h also maybe needed for some compilers
//#include <GL/glu.h>
//USE FREEGLUT//#include <GL/glut.h> // glut (gl utility toolkit) basic windows functions, keyboard, mouse.
#include <stdio.h> // standard (I/O library)
#include <stdlib.h> // standard library (set of standard C functions
#include <math.h> // Math library (Higher math functions )
#include <cstring>
/* Use glew.h instead of gl.h to get all the GL prototypes declared */
#include <GL/glew.h>
/* Using the GLUT library for the base windowing setup */
#include <GL/freeglut.h>
/* GLM */
// #define GLM_MESSAGES
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "shader_utils.h"
#include "res_texture.c"
int screen_width=800, screen_height=600;
GLuint vbo_cube_vertices, vbo_cube_texcoords;
GLuint ibo_cube_elements;
GLuint program;
GLuint texture_id;
GLint attribute_coord3d, attribute_texcoord;
GLint uniform_mvp, uniform_mytexture;
// lighting
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightDiffuse[]= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightPosition[]= { 5.0f, 5.0f, -10.0f, 1.0f };
GLfloat mat_specular[] = { 0.2, 0.2, 0.2, 1.0 };
int window_1, window_2;
static int view_state = 0, light_state = 0;
int spin;
int shape;
int init_resources()
{
GLfloat cube_vertices[] = {
// front
-1.5, -0.8, 0.8,
1.5, -0.8, 0.8,
1.5, 0.8, 0.8,
-1.5, 0.8, 0.8,
// top
-1.5, 0.8, 0.8,
1.5, 0.8, 0.8,
1.5, 0.8, -0.8,
-1.5, 0.8, -0.8,
// back
1.5, -0.8, -0.8,
-1.5, -0.8, -0.8,
-1.5, 0.8, -0.8,
1.5, 0.8, -0.8,
// bottom
-1.5, -0.8, -0.8,
1.5, -0.8, -0.8,
1.5, -0.8, 0.8,
-1.5, -0.8, 0.8,
// left
-1.5, -0.8, -0.8,
-1.5, -0.8, 0.8,
-1.5, 0.8, 0.8,
-1.5, 0.8, -0.8,
// right
1.4, -0.8, 0.8,
1.4, -0.8, -0.8,
1.4, 0.8, -0.8,
1.4, 0.8, 0.8,
};
glGenBuffers(1, &vbo_cube_vertices);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
GLfloat cube_texcoords[2*4*6] = {
// front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
};
for (int i = 1; i < 6; i++)
memcpy(&cube_texcoords[i*4*2], &cube_texcoords[0], 2*4*sizeof(GLfloat));
glGenBuffers(1, &vbo_cube_texcoords);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_texcoords), cube_texcoords, GL_STATIC_DRAW);
GLushort cube_elements[] = {
// front
0, 1, 2,
2, 3, 0,
// top
4, 5, 6,
6, 7, 4,
// back
8, 9, 10,
10, 11, 8,
// bottom
12, 13, 14,
14, 15, 12,
// left
16, 17, 18,
18, 19, 16,
// right
20, 21, 22,
22, 23, 20,
};
glGenBuffers(1, &ibo_cube_elements);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, // target
0, // level, 0 = base, no minimap,
GL_RGB, // internalformat
res_texture.width, // width
res_texture.height, // height
0, // border, always 0 in OpenGL ES
GL_RGB, // format
GL_UNSIGNED_BYTE, // type
res_texture.pixel_data);
GLint link_ok = GL_FALSE;
GLuint vs, fs;
if ((vs = create_shader("cube.v.glsl", GL_VERTEX_SHADER)) == 0) return 0;
if ((fs = create_shader("cube.f.glsl", GL_FRAGMENT_SHADER)) == 0) return 0;
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
fprintf(stderr, "glLinkProgram:");
print_log(program);
return 0;
}
const char* attribute_name;
attribute_name = "coord3d";
attribute_coord3d = glGetAttribLocation(program, attribute_name);
if (attribute_coord3d == -1) {
fprintf(stderr, "Could not bind attribute %s
", attribute_name);
return 0;
}
attribute_name = "texcoord";
attribute_texcoord = glGetAttribLocation(program, attribute_name);
if (attribute_texcoord == -1) {
fprintf(stderr, "Could not bind attribute %s
", attribute_name);
return 0;
}
const char* uniform_name;
uniform_name = "mvp";
uniform_mvp = glGetUniformLocation(program, uniform_name);
if (uniform_mvp == -1) {
fprintf(stderr, "Could not bind uniform %s
", uniform_name);
return 0;
}
uniform_name = "mytexture";
uniform_mytexture = glGetUniformLocation(program, uniform_name);
if (uniform_mytexture == -1) {
fprintf(stderr, "Could not bind uniform %s
", uniform_name);
return 0;
}
return 1;
}
// I use this to put text on the screen
void Sprint( int x, int y, char *st)
{
int l,i;
l=strlen( st ); // see how many characters are in text string.
glRasterPos2i( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
}
}
// This creates the spinning of the cube.
static void TimeEvent(int te)
{
spin++; // increase cube rotation by 1
if (spin > 360) spin = 0; // if over 360 degress, start back at zero.
glutSetWindow( window_1 );
glutPostRedisplay(); // Update screen with new rotation data
glutSetWindow( window_2 );
glutPostRedisplay(); // Update screen with new rotation data
glutTimerFunc( 100, TimeEvent, 1); // Reset our timmer.
}
// Setup our Opengl world, called once at startup.
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); // When screen cleared, use black.
glShadeModel (GL_SMOOTH); // How the object color will be rendered smooth or flat
glEnable(GL_DEPTH_TEST); // Check depth when rendering
// Lighting is added to scene
glLightfv(GL_LIGHT1 ,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1 ,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1 ,GL_POSITION, LightPosition);
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_LIGHT1); // Turn on light 1
}
// Draw our world
void display_1(void)
{
char *p;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glColor3f(1.0, 1.0, 1.0);
if (shape == 0) Sprint(-3, -7 ,"Solid Cube");
if (shape == 1) Sprint(-3, -7 ,"Solid Cone");
if (shape == 2) Sprint(-3, -7 ,"Solid Sphere");
if (shape == 3) Sprint(-3, -7 ,"Solid Torus");
if (shape == 4) Sprint(-3, -7 ,"Solid Dodecahedron");
if (shape == 5) Sprint(-3, -7 ,"Solid Octahedron");
if (shape == 6) Sprint(-3, -7 ,"Solid Tetrahedron");
if (shape == 7) Sprint(-3, -7 ,"Solid Icosahedron");
if (shape == 8) Sprint(-3, -7 ,"Solid Teapot");
// Setup view, and print view state on screen
if (view_state == 1)
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Perspective view");
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}else
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");
}
glColor3f( 0.0, 0.0, 1.0); // Cube color
// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING); // Turn off lighting
glDisable(GL_COLOR_MATERIAL); // Turn off material, which needs lighting to work
}else
{
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Turn on material settings
glColorMaterial(GL_FRONT, GL_AMBIENT);
glColor4f(0.65, 0.65, 0.65, 0.4);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor4f(0.10, 0.10, 0.10, 0.0);
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor4f(0.5, 0.5, 0.5, 0.4);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(0.85, 0.85, 0.85, 0.4);
}
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0);
//glRotatef( 45, 1.0, 1.0, 0.0); // rotate cube
glRotatef( spin++, 1.0, 1.0, 1.0); // spin cube
if (shape == 0) glutSolidCube(10); // Draw a cube
if (shape == 1) glutSolidCone(5,10, 16,16); // Draw a Cone
if (shape == 2) glutSolidSphere(5, 16,16 ); // Draw a Sphere
if (shape == 3) glutSolidTorus( 2.5, 5, 16, 16);
if (shape == 4)
{
glScalef( 3.5, 3.5, 3.5);
glutSolidDodecahedron();
}
if (shape == 5)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidOctahedron();
}
if (shape == 6)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidTetrahedron();
}
if (shape == 7)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidIcosahedron();
}
if (shape == 8) glutSolidTeapot( 5 );
glutSwapBuffers();
}
void display_2(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
glUniform1i(uniform_mytexture, /*GL_TEXTURE*/0);
glEnableVertexAttribArray(attribute_coord3d);
// Describe our vertices array to OpenGL (it can't guess its format automatically)
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices);
glVertexAttribPointer(
attribute_coord3d, // attribute
3, // number of elements per vertex, here (x,y,z)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
glEnableVertexAttribArray(attribute_texcoord);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);
glVertexAttribPointer(
attribute_texcoord, // attribute
2, // number of elements per vertex, here (x,y)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
/* Push each element in buffer_vertices to the vertex shader */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
int size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(attribute_coord3d);
glDisableVertexAttribArray(attribute_texcoord);
glutSwapBuffers();
}
// This is called when the window has been resized.
void reshape_1 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// This is called when the window has been resized.
void reshape_2 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// Read the keyboard
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 'v':
case 'V':
view_state = abs(view_state -1);
break;
case 'l':
case 'L':
light_state = abs(light_state -1);
break;
case 's':
case 'S':
shape++;
break;
case 27:
exit(0); // exit program when [ESC] key presseed
break;
default:
break;
}
if (shape > 8) shape = 0;
}
// Main program
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (10, 10);
glutTimerFunc( 10, TimeEvent, 1);
window_1 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 1");
init ();
glutDisplayFunc(display_1);
glutReshapeFunc(reshape_1);
glutKeyboardFunc(keyboard);
window_2 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 2");
init ();
glutDisplayFunc(display_2);
glutReshapeFunc(reshape_2);
glutMainLoop();
return 0;
}