PDA

View Full Version : Problems with simple OpenGL (core) file



AleaIactaEst
08-12-2011, 03:59 AM
My aim was to write the simplest possible OpenGL program with custom shaders that uses none of the deprecated functionality and can be run using mesa7.7.1 (i.e. OpenGL 2.1 and GLSL 1.2).

My problem is that nothing gets actually drawn to the window (it's just cleared using a blue color).

Compiling and linking the shaders works fine.

I guess there's something wrong about the buffers which causes that no geometry is sent to the shaders, so here's a shortened version of the file:


#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glut.h>

GLuint vertexLoc; //location of vVertex attribute
GLuint vertexArray; //vertex buffer
GLuint vao; //vertex array object
GLuint prog; //Handle to shader prog

void RenderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat vColor[] = { 0.8, 0.7, 0.1, 1.0 };

glUseProgram(prog);
glUniform4fv(glGetUniformLocation(prog, "vColor"), 1, vColor);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

glutSwapBuffers();
}

void SetupRC() {
glClearColor(0.0, 0.0, 1.0, 1.0);

/* Load and compile shaders here */

GLfloat verts[] = { -0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 0.5, 0.0 };

glGenVertexArrays(1, &amp;vao);
glBindVertexArray(vao);

glGenBuffers(1, &amp;vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3, verts, GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(vertexLoc);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindVertexArray(0);
}

int main(int argc, char **argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 200);
glutInitWindowSize(600, 400);
glutCreateWindow("Basic Setup");

glutDisplayFunc(RenderScene);
glutReshapeFunc(ReshapeWindow);

GLenum err = glewInit();
if(err != GLEW_OK) {
cerr << "GLEW Error: " << glewGetErrorString(err) << endl;
return 1;
}

SetupRC(); //Setup rendering context

glutMainLoop();

return 0;
}


This is the whole file:
<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
#include <iostream>
using std::cerr; using std::cout; using std::cin; using std::endl;
#include <fstream>
#include <string>

#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glut.h>

GLuint vertexLoc; //location of vVertex attribute
GLuint vertexArray; //vertex buffer
GLuint vao; //vertex array object
GLuint prog; //Handle to shader prog

int SetupShaders(const GLchar*, const GLchar*);

void RenderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat vColor[] = { 0.8, 0.7, 0.1, 1.0 };

glUseProgram(prog);
glUniform4fv(glGetUniformLocation(prog, "vColor"), 1, vColor);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

glutSwapBuffers();
}

void ReshapeWindow(int w, int h) {
glViewport(0, 0, w, h);
}

void LoadShaderSource(const char* loc, std::string&amp; src) {
std::ifstream file(loc);
std::string line;

if(file.is_open()) {
while(file.good()) {
getline(file, line);
src.append(line);
src.append("\n");
}
file.close();
}
}

void SetupRC() {
glClearColor(0.0, 0.0, 1.0, 1.0);

std::string srcVS, srcFS;
LoadShaderSource("VS.vert", srcVS);
LoadShaderSource("FS.frag", srcFS);
if(SetupShaders(srcVS.c_str(), srcFS.c_str())!=0)
exit(1);

GLfloat verts[] = { -0.5, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 0.5, 0.0 };

glGenVertexArrays(1, &amp;vao);
glBindVertexArray(vao);

glGenBuffers(1, &amp;vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3, verts, GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(vertexLoc);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindVertexArray(0);
}

void printShaderInfoLog(GLuint obj) {
int infologLen = 0;
int charsWritten = 0;
GLchar *infoLog;

glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLen);

if(infologLen > 0) try {
infoLog = new GLchar[infologLen];

glGetShaderInfoLog(obj, infologLen, &amp;charsWritten, infoLog);
cout << infoLog;

delete infoLog;
} catch (...) {
cerr << "\nError allocating memory\n";
}
}

void printProgramInfoLog(GLuint obj) {
int infologLen = 0;
int charsWritten = 0;
GLchar *infoLog;

glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLen);

if(infologLen > 0) try {
infoLog = new GLchar[infologLen];

glGetProgramInfoLog(obj, infologLen, &amp;charsWritten, infoLog);
cout << infoLog;

delete infoLog;
} catch (...) {
cerr << "\nError allocating memory\n";
}
}

int SetupShaders(const GLchar* VS_src, const GLchar* FS_src) {
GLuint VS, FS; //handles to objects
GLint vertCompiled, fragCompiled; //status values
GLint linked;

VS = glCreateShader(GL_VERTEX_SHADER);
FS = glCreateShader(GL_FRAGMENT_SHADER);

glShaderSource(VS, 1, &amp;VS_src, NULL);
glShaderSource(FS, 1, &amp;FS_src, NULL);

glCompileShader(VS);
glGetShaderiv(VS, GL_COMPILE_STATUS, &amp;vertCompiled);
cout << "Vertex Shader Info Log: \n";
printShaderInfoLog(VS);
glCompileShader(FS);
glGetShaderiv(FS, GL_COMPILE_STATUS, &amp;fragCompiled);
printShaderInfoLog(FS);
cout << "Fragment Shader Info Log: \n";

if((vertCompiled==GL_FALSE) || (fragCompiled==GL_FALSE)) {
glDeleteShader(VS);
glDeleteShader(FS);
return 1;
}

prog = glCreateProgram();
glAttachShader(prog, VS);
glAttachShader(prog, FS);

glBindAttribLocation(prog, 1, "vVertex");
vertexLoc = 1;

glLinkProgram(prog);
glGetProgramiv(prog, GL_LINK_STATUS, &amp;linked);
printProgramInfoLog(prog);

glDeleteShader(VS); //These are no longer needed
glDeleteShader(FS);

if(linked==GL_FALSE) {
glDeleteProgram(prog);
return 2;
}

return 0;
}

int main(int argc, char **argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 200);
glutInitWindowSize(600, 400);
glutCreateWindow("Basic Setup");

glutDisplayFunc(RenderScene);
glutReshapeFunc(ReshapeWindow);

GLenum err = glewInit();
if(err != GLEW_OK) {
cerr << "GLEW Error: " << glewGetErrorString(err) << endl;
return 1;
}

SetupRC(); //Setup rendering context

glutMainLoop();

//
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &amp;vertexArray);
glDeleteVertexArrays(1, &amp;vao);

return 0;
}[/QUOTE]</div>
Vertex Shader:
<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
attribute vec4 vVertex;

void main() {
gl_Position = vVertex;
}[/QUOTE]</div>
Fragment Shader:
<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
uniform vec4 vColor;

void main() {
gl_FragColor = vColor;
}[/QUOTE]</div>

V-man
08-12-2011, 05:54 AM
Maybe your polygon gets clipped because it isn't in the viewport. Change your z values. Perhaps -0.5.

Perhaps disable culling.

AleaIactaEst
08-12-2011, 06:59 AM
Good ideas but neither of them did solve the problem.

Afaik the triangle doesnt get clipped because the "default" view volume of OpenGL is a Cube with x,y,z in [-1,1]

I disabled GL_CULL_FACE in the SetupRC() function but that also didnt make the triangle appear.

marshats
08-12-2011, 07:22 AM
I compiled and ran your code without any changes on my Ubuntu box and saw a yellow triangle centered in a blue background. What is your hardware, os, compile tool?

My Computer info:
OS: Ubuntu 10.04 32-bit
Compiler: gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Vendor: NVIDIA Corporation
Renderer: GeForce GTX 465/PCI/SSE2/3DNOW!
Version: 3.1.0 NVIDIA 280.13
GLSL: 1.40 NVIDIA via Cg compiler

AleaIactaEst
08-12-2011, 08:27 AM
That's good to hear that the program actually works :) although im a bit surprised now...

Well thats my computer info:
OS: Debian 6.0.2 (squeeze)
Compiler: gcc (Debian 4.4.5-8) 4.4.5
Vendor: Tungsten Graphics, Inc
Renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20091221 2009Q4
Version: 2.1 Mesa 7.7.1
GLSL: 1.2

Compiling the cpp file as well as the shaders works fine.

marshats
08-12-2011, 04:56 PM
My suspicion is either the Mesa library or the intel Chipset is causing the problem.

Did you install and compile the newest Mesa 7.11 library... try not using the DRI (Direct rendering) with the latest Mesa source code.

Lots of people have complained on this forum about Intel support for the openGL 2.1+ ... I haven't had an integrated intel GPU ever so I can't say how to fix that problem.

AleaIactaEst
08-13-2011, 06:38 AM
i doubt that this is the problem since i kind of 'derived' my program from another, more complex one which works, so it should work with mesa and direct rendering enabled.

AleaIactaEst
08-14-2011, 07:56 AM
Well i've rewritten the entire file from scratch and it's working now, although i have absolutely no idea why it's working.
It's pretty much the same as the previous program just with some other variable names.

Thats the file:
<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
#include <iostream>
using std::cerr; using std::cout; using std::cin;
using std::endl;
#include <fstream>
#include <string>

#include <GL/glew.h>
#include <GL/glut.h>

const int vertexLoc = 0;
GLuint prog;
GLuint vao;
GLuint nVerts;

void ChangeSize(int w, int h) {
glViewport(0, 0, w, h);
}

void LoadFile(const char* loc, char** src) {
std::ifstream file(loc, std::ios::ate | std::ios::in | std::ios::binary);
std::string line;

if(file.is_open()) {
std::ifstream::pos_type size = file.tellg();
*src = new char[size];
file.seekg(0, std::ios::beg);
file.read(*src, size);
file.close();
}
}

void printShaderInfoLog(GLuint obj) {
int infologLen = 0;
int charsWritten = 0;
GLchar *infoLog;

glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLen);

if(infologLen > 0) try {
infoLog = new GLchar[infologLen];

glGetShaderInfoLog(obj, infologLen, &amp;charsWritten, infoLog);
cout << infoLog;

delete infoLog;
} catch (...) {
cerr << "\nError allocating memory\n";
}
}

void printProgramInfoLog(GLuint obj) {
int infologLen = 0;
int charsWritten = 0;
GLchar *infoLog;

glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLen);

if(infologLen > 0) try {
infoLog = new GLchar[infologLen];

glGetProgramInfoLog(obj, infologLen, &amp;charsWritten, infoLog);
cout << infoLog;

delete infoLog;
} catch (...) {
cerr << "\nError allocating memory\n";
}
}

GLuint SetupShaders(const char *szVertexSrc, const char *szFragmentSrc) {
// Temporary Shader objects
GLuint hVertexShader, hFragmentShader, hProg = 0;
GLint testVal;

// Create shader objects
hVertexShader = glCreateShader(GL_VERTEX_SHADER);
hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

// Load them.
glShaderSource(hVertexShader, 1, &amp;szVertexSrc, NULL);
glShaderSource(hFragmentShader, 1, &amp;szFragmentSrc, NULL);

// Compile them
glCompileShader(hVertexShader);
glCompileShader(hFragmentShader);

// Check for errors
glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &amp;testVal);
if(testVal == GL_FALSE) {
cout << "Vertex Shader Info Log: \n";
printShaderInfoLog(hVertexShader);
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);
return static_cast<GLuint>(-1);
}

glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &amp;testVal);
if(testVal == GL_FALSE) {
cout << "Fragment Shader Info Log: \n";
printShaderInfoLog(hFragmentShader);
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);
return static_cast<GLuint>(-1);
}

hProg = glCreateProgram();
glAttachShader(hProg, hVertexShader);
glAttachShader(hProg, hFragmentShader);

glBindAttribLocation(hProg, vertexLoc, "vVertex");

glLinkProgram(hProg);

// These are no longer needed
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);

glGetProgramiv(hProg, GL_LINK_STATUS, &amp;testVal);
if(testVal == GL_FALSE) {
cout << "Program Info Log: \n";
printProgramInfoLog(hProg);
glDeleteProgram(hProg);
return static_cast<GLuint>(-1);
}

return hProg;
}

void SetupRC() {
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );

char *VS_source, *FS_source;
LoadFile("vs.vert", &amp;VS_source);
LoadFile("fs.frag", &amp;FS_source);

prog = SetupShaders(VS_source, FS_source);

// Triangle vertex data
GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f };
nVerts = 3;

GLuint vertArray;
glGenVertexArrays(1, &amp;vao);
glGenBuffers(1, &amp;vertArray);
glBindBuffer(GL_ARRAY_BUFFER, vertArray);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * nVerts, vVerts, GL_DYNAMIC_DRAW);
glBindVertexArray(vao);
glEnableVertexAttribArray(vertexLoc);
glBindBuffer(GL_ARRAY_BUFFER, vertArray);
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
}

void RenderScene() {
GLint iColor;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

GLfloat vYellow[] = { 0.8f, 0.7f, 0.1f, 1.0f };
glUseProgram(prog);
iColor = glGetUniformLocation(prog, "vColor");
glUniform4fv(iColor, 1, vYellow);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, nVerts);
glBindVertexArray(0);

// Perform the buffer swap to display back buffer
glutSwapBuffers();
}

int main(int argc, char **argv) {
glutInit(&amp;argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);

GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}

SetupRC();

glutMainLoop();
return 0;
}
[/QUOTE]</div>

I still wanna know why that works now so anyone who has a good idea is welcome :)

Avithohol
08-16-2011, 02:21 AM
Hello AleaIactaEst,

we do chat on another thread, looks like we are side by side :) on the journey with SuperBible 5th:

If you have rewritten the whole program, have you checked the source files side by side (Total Commander has nice option to do text file content comparison)

AleaIactaEst
08-16-2011, 02:54 AM
I found the error in my first program.
If i bind the vVertex attrib to 'location' 0 instead of 1 everything works fine, and i can see the yellow triangle.
I guess that's because of the old opengl version im using ( mesa7.7.1 (i.e. OpenGL 2.1 / GLSL 1.2))

Avithohol
08-16-2011, 03:11 AM
This is also what i do precisely: Write Library according to the core profile, and try to make it so simple that Opengl 2.1 hardware might be able to run it.

I also spotted, that if i want to have the vertex position anything but "vertex attrib 0" the object is not drawn.
Sorry that i didnot spot this in your code :(

I have Win7 and ATI X1600 (gl v2.1 max) newest driver and behaves the same.