PDA

View Full Version : opengl framebuffer works on mac but not on linux



dkon365
02-14-2017, 01:36 PM
HI all. I am newbie to opengl and a first time poster here. so please forgive my mistakes
I am rendering a cube and writing the rendered frame back as png.
a
i am able to successfully run it on mac with the output test,png containing the cube.
But when I run it on a linux machine the test.png is blank.

i am unable to attch the zip file of the project
here is the code for the fbo:


//
// fbo_test.cpp

#include "fbo_test.hpp"

int fbo_test( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);

// Open a window and create its OpenGL context
GLFWwindow* window = glfwCreateWindow( 256, 256, "Tutorial 04 - Colored Cube", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
glewExperimental = GL_TRUE; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// Dark background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);

unsigned int color_tex = 0;
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//NULL means reserve texture memory, but texels are undefined
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
//-------------------------
unsigned int fb;
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
//Attach 2D texture to this FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);
//-------------------------
unsigned int depth_rb;
glGenRenderbuffersEXT(1, &depth_rb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
//-------------------------
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
//-------------------------
//Does the GPU support current FBO configuration?
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
std::cout<<"good" << std::endl;
}


//and now you can render to GL_TEXTURE_2D
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//-------------------------
glViewport(0, 0, 256, 256);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 256.0, 0.0, 256.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//-------------------------
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
//glEnable(GL_DEPTH_TEST);


GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// Create and compile our GLSL program from the shaders
GLuint programID = loadShaders( "TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader" );

// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");

// Projection matrix : 45∞ Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View = glm::lookAt(
glm::vec3(4,3,-3), // Camera is at (4,3,-3), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);

// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around

// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};

// One color for each vertex. They were generated randomly.
static const GLfloat g_color_buffer_data[] = {
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);

// allocate buffer memory to store all rendered frames
unsigned char *pixel_data = new unsigned char[3 * 256 * 256];
// For speed computation
double last_time = glfwGetTime();
int frame_count = 0;

do{

// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Use our shader
glUseProgram(programID);

// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);

// 2nd attribute buffer : colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
frame_count++;

glReadPixels(0, 0, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, pixel_data);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 && frame_count <=1 );
write_png_file("test.png", pixel_data ,
256, 256);
double current_time = glfwGetTime();
std::cout << "Finished rendering: " << frame_count - 1 << " frames in\t" << \
current_time - last_time << "s" << std::endl;
std::cout << "Average fps: " << (frame_count - 1)/(current_time-last_time) << std::endl;
// Cleanup VBO and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteProgram(programID);
glDeleteVertexArrays(1, &VertexArrayID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}


color shader

#version 410 core

// Interpolated values from the vertex shaders
in vec3 fragmentColor;

// Ouput data
out vec3 color;

void main(){

// Output color = color specified in the vertex shader,
// interpolated between all 3 surrounding vertices
color = fragmentColor;

}


vertex shader

#version 410 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;

// Output data ; will be interpolated for each fragment.
out vec3 fragmentColor;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

// Output position of the vertex, in clip space : MVP * position
gl_Position = MVP * vec4(vertexPosition_modelspace,1);

// The color of each vertex will be interpolated
// to produce the color of each fragment
fragmentColor = vertexColor;
}



i forked most of the code from opengl-tutorial dt org

the only difference i see from my mac to linux machine is the opengl version string OpenGL version
on Linux: supported 3.3.0 NVIDIA 361.93.02
on Mac : supported 4.1 NVIDIA-10.14.20 355.10.05.15f03

Does any one have any suggestions on why it would work on mac and not on linux, or any fix.
Thanks in advance

dkon365
02-14-2017, 01:37 PM
Here is the link to the complete project files:
https://drive.google.com/open?id=0B9JzRqJueIWtTnJQNlhzTVdLWk0

Osbios
02-14-2017, 03:41 PM
Try to change your shader headers to the lower GL version. Maybe also get some error checking/output for your shader loading?


#version 330 core

mhagain
02-15-2017, 02:36 AM
Yes, what OpenGL features are or are not available are nothing to do with your OS and everything to do with your hardware and drivers.

dkon365
02-15-2017, 10:40 AM
the change to version 330 in shader also doesnt have any output.
the shaders are producing errors out when i change the version to 310.
so that eliminates the shader

ALso, I ran another test without framebuffer. just rendered to screen and use glReadPixels()
and it works fine without any issues.

here is the output when changed version to 310.

Compiling vertex shader : TransformVertexShader.vertexshader
0(3) : error C0201: unsupported version 310
0(5) : error C0000: syntax error, unexpected '(', expecting "::" at token "("
0(9) : error C7532: global type vec3 requires "#version 100" or later
0(9) : error C5060: out can't be used with non-varying fragmentColor
0(11) : error C7532: global type mat4 requires "#version 100" or later
0(16) : error C7532: global variable gl_Position requires "#version 100" or later
0(16) : error C7532: global type vec4 requires "#version 100" or later

Compiling fragment shader : ColorFragmentShader.fragmentshader
0(3) : error C0201: unsupported version 310
0(5) : error C7532: global type vec3 requires "#version 100" or later
0(8) : error C5060: out can't be used with non-varying color

Linking program
Vertex info
-----------
0(3) : error C0201: unsupported version 310
0(5) : error C0000: syntax error, unexpected '(', expecting "::" at token "("
0(9) : error C7532: global type vec3 requires "#version 100" or later
0(9) : error C5060: out can't be used with non-varying fragmentColor
0(11) : error C7532: global type mat4 requires "#version 100" or later
0(16) : error C7532: global variable gl_Position requires "#version 100" or later
0(16) : error C7532: global type vec4 requires "#version 100" or later

Fragment info
-------------
0(3) : error C0201: unsupported version 310
0(5) : error C7532: global type vec3 requires "#version 100" or later
0(8) : error C5060: out can't be used with non-varying color

mhagain
02-15-2017, 12:17 PM
There's no GLSL version 310; the next version below 330 is 150. https://en.wikipedia.org/wiki/OpenGL_Shading_Language#Versions

Osbios
02-15-2017, 01:16 PM
Maybe try to not use the EXT verson of the frame buffer? GL_ARB_framebuffer_object is core since 3.0.

You may also want to take a look at debug output, makes error hunting way easier: https://www.khronos.org/opengl/wiki/Debug_Output

dkon365
02-15-2017, 01:19 PM
never mind.. i solved it. the glm on my mac differed from my linux machine.
the linux machine had new glm version and was defaulting to radians . while my input was degrees.
i explicitly converted my angles to radians on linux. that fixed it.
thank you all


here the fix

glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);
instead of
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);

dkon365
02-15-2017, 01:22 PM
Maybe try to not use the EXT verson of the frame buffer? GL_ARB_framebuffer_object is core since 3.0.

You may also want to take a look at debug output, makes error hunting way easier: https://www.khronos.org/opengl/wiki/Debug_Output

i will keep this in mind. thank you