Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: GLFW+VBO+Shader = black screen?

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2008
    Posts
    4

    GLFW+VBO+Shader = black screen?

    I've created a window with GLFW and can successfully draw some primitive things on it (glBegin/glVertex/glEnd).

    Now I took a working tutorial on VBO with vertex and fragment shader and simply copied the relevant code into my GLFW framework. But nothing shows up. The shader files are loaded correctly, no error messages. Just a black window. I'm trying to fix this problem for 3 days.

    Here's the code:

    Code :
    #include "StdAfx.h"
    #include "Renderer.h"
    #include <GL/GLU.h>
    #include <stdlib.h>
    #include <iostream>
    #include <fstream>
    #include <math.h>
     
     
    GLuint vertBuffer, colorBuffer;
    GLhandleARB shaderProgram;
     
    PFNGLGENBUFFERSARBPROC		glGenBuffersARB;
    PFNGLBINDBUFFERARBPROC		glBindBufferARB;
    PFNGLBUFFERDATAARBPROC		glBufferDataARB;
    PFNGLDELETEBUFFERSARBPROC	glDeleteBuffersARB;
     
    PFNGLCREATEPROGRAMOBJECTARBPROC		glCreateProgramObjectARB;
    PFNGLDELETEOBJECTARBPROC			glDeleteObjectARB;
    PFNGLUSEPROGRAMOBJECTARBPROC		glUseProgramObjectARB;
    PFNGLCREATESHADEROBJECTARBPROC		glCreateShaderObjectARB;
    PFNGLSHADERSOURCEARBPROC			glShaderSourceARB;
    PFNGLCOMPILESHADERARBPROC			glCompileShaderARB;
    PFNGLGETOBJECTPARAMETERIVARBPROC	glGetObjectParameterivARB;
    PFNGLATTACHOBJECTARBPROC			glAttachObjectARB;
    PFNGLGETINFOLOGARBPROC				glGetInfoLogARB;
    PFNGLLINKPROGRAMARBPROC				glLinkProgramARB;
     
     
    Renderer::Renderer(void)
    {	
    }
     
    Renderer::~Renderer(void)
    {
    }
     
    void Renderer::init(void) 
    {
    	vertBuffer = NULL;
    	colorBuffer = NULL;
    	shaderProgram = NULL;
     
    	if(glfwExtensionSupported("GL_ARB_vertex_buffer_object")==GL_FALSE)
    		throw std::exception("Vertex Buffer Objects not supported by the current driver");
     
    	// Retrieve the function pointers for each of the extension functions we will be using
    	glGenBuffersARB		= (PFNGLGENBUFFERSARBPROC) glfwGetProcAddress("glGenBuffersARB");			
    	glBindBufferARB		= (PFNGLBINDBUFFERARBPROC) glfwGetProcAddress("glBindBufferARB");
    	glBufferDataARB		= (PFNGLBUFFERDATAARBPROC) glfwGetProcAddress("glBufferDataARB");
    	glDeleteBuffersARB	= (PFNGLDELETEBUFFERSARBPROC) glfwGetProcAddress("glDeleteBuffersARB");
     
    	if(glfwExtensionSupported("GL_ARB_shading_language_100")==GL_FALSE)
    		throw std::exception("GLSL Shaders not supported by the current driver");
     
    	glCreateProgramObjectARB  = (PFNGLCREATEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glCreateProgramObjectARB");
    	glDeleteObjectARB         = (PFNGLDELETEOBJECTARBPROC)glfwGetProcAddress("glDeleteObjectARB");
    	glUseProgramObjectARB     = (PFNGLUSEPROGRAMOBJECTARBPROC)glfwGetProcAddress("glUseProgramObjectARB");
    	glCreateShaderObjectARB   = (PFNGLCREATESHADEROBJECTARBPROC)glfwGetProcAddress("glCreateShaderObjectARB");
    	glShaderSourceARB         = (PFNGLSHADERSOURCEARBPROC)glfwGetProcAddress("glShaderSourceARB");
    	glCompileShaderARB        = (PFNGLCOMPILESHADERARBPROC)glfwGetProcAddress("glCompileShaderARB");
    	glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glfwGetProcAddress("glGetObjectParameterivARB");
    	glAttachObjectARB         = (PFNGLATTACHOBJECTARBPROC)glfwGetProcAddress("glAttachObjectARB");
    	glGetInfoLogARB           = (PFNGLGETINFOLOGARBPROC)glfwGetProcAddress("glGetInfoLogARB");
    	glLinkProgramARB          = (PFNGLLINKPROGRAMARBPROC)glfwGetProcAddress("glLinkProgramARB");
     
    	// Define the positions for each of the three points of the triangle
    	float verts[] = {
    						//X      Y     Z
    						0.0f,  1.0f, 0.0f,		// Top Middle
    						1.0f, -1.0f, 0.0f,		// Bottom Left
    						1.0f, -1.0f, 0.0f		// Bottom Right
    					};
     
    	// Define the colors for each of the three points of the triangle
    	float colors[] = {
    						//R     G	 B
    						1.0f, 0.0f, 0.0f,		// Top Middle - Red
    						0.0f, 1.0f, 0.0f,		// Bottom Left - Green
    						0.0f, 0.0f, 1.0f		// Bottom Right - Blue
    					};
     
    	glGenBuffersARB(1, &amp;vertBuffer);
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertBuffer);									// Set the newly created buffer as the current one
    	glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_STATIC_DRAW_ARB);	// Send the vetex position data to the current buffer
     
    	glGenBuffersARB(1, &amp;colorBuffer);													// Create a handle for the vertex color buffer
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorBuffer);								// Set the newly created buffer as the current one
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(colors), colors, GL_STATIC_DRAW_ARB);	// Send the vertex color data to the current buffer
     
    	//glEnable(GL_VERTEX_PROGRAM_ARB);
    	//glEnable(GL_FRAGMENT_PROGRAM_ARB);
    	GLhandleARB vertShader, fragShader;
    	ShaderFromFile("Vertex.glsl", GL_VERTEX_SHADER_ARB, vertShader);		// Load "Vertex.glsl" as our Vertex Shader
    	ShaderFromFile("Fragment.glsl", GL_FRAGMENT_SHADER_ARB, fragShader);    // Load "Fragment.glsl" as our Fragment Shader
    	LinkShaders(vertShader, fragShader, shaderProgram);					// Link the vertex and fragment shaders into the shader program
     
    	// Now that the shader program has been linked, we no longer need these two intermediate objects and should delete them
    	glDeleteObjectARB(vertShader);
    	glDeleteObjectARB(fragShader);
     
    	// init openGL settings
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);	// Clear the Screen to Black
    	glClearDepth(1.0f);						// Clear the Depth Buffer completely
    	glDepthFunc(GL_LEQUAL);					// The method used to determine if one pixel is behind another
    	glEnable(GL_DEPTH_TEST);				// Enable Z-Buffering (Depth Testing)
    	glShadeModel(GL_SMOOTH);				// When shading, interpolate values between vertices
    }
     
    void Renderer::resize(int width, int height)
    {
    	if(height==0) height = 1;			// Must have a height of at least 1 to prevent divide by 0 errors
     
    	glViewport (0, 0, width, height);	// Tell OpenGL the size of our window 	
    	glMatrixMode(GL_PROJECTION);		// Notify OpenGL that we are modifying the Projection Matrix																
    	glLoadIdentity();					// Set the Projection matrix to the Identiy matrix	
    	gluPerspective(45.0f, width/height , 0.1f, 255.0f);	//Set Perspective projection
    	glMatrixMode(GL_MODELVIEW);			// Switch the matrix back to ModelView mode 																	
    	glLoadIdentity();					// Set the ModelView matrix to the Identity matrix
    }
     
    void Renderer::renderScene(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    	glLoadIdentity();										// Set the ModelView matrix to the Identity matrix to remove any rotation/translation that's already occured											
    	glTranslatef(0.0f, 0.0f, -2.0f);						// Move the "camera" back two units, so we can see the triangle
     
    	// Shader Program
    	glUseProgramObjectARB(shaderProgram);					// Set the shader program to use for this draw call
     
    	// Vertex Buffer
    	glEnableClientState(GL_VERTEX_ARRAY);					// Tell OpenGL that our rendered geometry will contain position information
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertBuffer);		// Set the vertex position buffer as the current buffer 
    	glVertexPointer(3, GL_FLOAT, 0, (char*)NULL);			// Set the current buffer as the source of position information
     
    	// Color Buffer
    	glEnableClientState(GL_COLOR_ARRAY);					// Tell OpenGL that our rendered geometry will contain color information
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorBuffer);		// Set the vertex color buffer as the current buffer 
    	glColorPointer(3, GL_FLOAT, 0, (char*)NULL);			// Set the current buffer as the source of color information
     
    	// Draw
    	glDrawArrays(GL_TRIANGLES, 0, 3);						// Render three points with the current sources
     
    	glDisableClientState(GL_VERTEX_ARRAY);					// Tell OpenGL that we are done using position data
    	glDisableClientState(GL_COLOR_ARRAY);					// Tell OpenGL that we are done using color data
     
    	// Draw "old" stuff
    	glTranslatef(0.0f, 0.0f, -4.0f);
     
    	glBegin(GL_QUADS);
    		glColor4f(0.0f,0.0f,1.0f,1.0f);
    		glVertex3f(-1.0f,-1.0f,-1.0f);
    		glVertex3f(1.0f,-1.0f,-1.0f);
    		glColor4f(0.0f,1.0f,1.0f,1.0f);
    		glVertex3f(1.0f,1.0f,-1.0f);
    		glVertex3f(-1.0f,1.0f,-1.0f);
    	glEnd();
     
    	glFlush();	
    }
     
    void Renderer::terminate(void)
    {
    	if(glDeleteBuffersARB != NULL)
    	{ 
    		// A note about these two calls: If the buffers were not created properly in the first place
    		// OpenGL will silently ignore these calls, so they are safe to make without further error checking
    		glDeleteBuffersARB(1, &amp;vertBuffer);		// Delete the vertex position buffer and free it's data from video memory
    		glDeleteBuffersARB(1, &amp;colorBuffer);		// Delete the vertex color buffer and free it's data from video memory
    	}
     
    	// Do the same for shader resources
    	if(glDeleteObjectARB != NULL)
    		glDeleteObjectARB(shaderProgram);			// Delete the shader program and free it's data from video memory
    }
     
    void Renderer::ShaderFromFile(const char* shaderPath, GLenum shaderType, GLhandleARB&amp; handle)
    {
    	char* shaderSrc = NULL;
    	int len = 0;
    	int errorFlag = -1;
     
    	if(!FileToString(shaderPath, shaderSrc, len))
    	{
    		std::string err = "Could not read shader:\n\n" + std::string(shaderPath);
    		std::cout << err << std::endl;
    		return;
    	}
     
    	handle = glCreateShaderObjectARB(shaderType);
     
    	glShaderSourceARB(handle, 1, (const char**)&amp;shaderSrc, &amp;len);
    	glCompileShaderARB(handle); 
    	delete[] shaderSrc;
     
    	glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &amp;errorFlag);
     
    	if(!errorFlag)
    	{
    		std::string err = "Shader Compile Error:\n\n" + std::string(shaderPath) + "\n\n" + GetShaderInfoLog(handle);
    		std::cout << err << std::endl;
    		return;
    	}
    }
     
    // Helper function used to create (link) a shader program from a vertex and fragment shader object
    void Renderer::LinkShaders(GLhandleARB&amp; vertex, GLhandleARB&amp; fragment, GLhandleARB&amp; handle)
    {
    	int errorFlag = -1;
     
    	handle = glCreateProgramObjectARB();
    	glAttachObjectARB(handle, vertex);
    	glAttachObjectARB(handle, fragment);
    	glLinkProgramARB(handle);
     
    	glGetObjectParameterivARB(handle, GL_OBJECT_LINK_STATUS_ARB, &amp;errorFlag);
    	if(!errorFlag)
    	{
    		std::string err = "Shader Program Link Error:\n\n" + GetShaderInfoLog(handle);
    		std::cout << err << std::endl;
    		return;
    	}
    }
     
    // Helper function used to get log info (such as errors) about a shader object or shader program
    std::string Renderer::GetShaderInfoLog(GLhandleARB&amp; obj)
    {
    	int logLength = 0;
    	int charsWritten  = 0;
    	char *tmpLog;
    	std::string log;
     
    	glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &amp;logLength);
     
    	if (logLength > 0)
    	{
    		tmpLog = new char[logLength];
    		glGetInfoLogARB(obj, logLength, &amp;charsWritten, tmpLog);
    		log = tmpLog;
    		delete[] tmpLog;
    	}
     
    	return log;
    }
     
    // Helper function used to read the contents of a file into a char array
    bool Renderer::FileToString(const char* path, char*&amp; out, int&amp; len)
    {
    	std::ifstream file(path, std::ios::ate | std::ios::binary);
     
    	if(!file.is_open()) return false;
     
    	len = file.tellg();
    	out = new char[ len+1 ];
    	file.seekg (0, std::ios::beg);
    	file.read(out, len);
    	//std::cout << "Shader Code: \n " << out << std::endl;
    	file.close();
    	out[len] = 0;
     
    	return true;
    }

    And the main class:

    Code :
    #include "stdafx.h"
    #include "Renderer.h"
     
    Renderer renderer;
     
    ///ENTRY:mainCRTStartup 
     
    void GLFWCALL windowResize(int width, int height)
    {
    	renderer.resize(width, height);
    }
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int running = GL_TRUE;
     
    	// Initialize GLFW
    	glfwInit();	
    	glfwOpenWindowHint(GLFW_AUX_BUFFERS, 6);
     
    	// Open an OpenGL window
    	if(!glfwOpenWindow( 740,500, 8,8,8,8,24,8, GLFW_WINDOW))
    	{
    		glfwTerminate();
    		return 0;
    	}
     
    	renderer.init();
    	glfwSetWindowTitle("RAVE prototype");
    	glfwSetWindowSizeCallback(windowResize);
     
     
     
    	while(running)
    	{
    		renderer.renderScene();
    		glfwSwapBuffers();
     
    		// Check if ESC key was pressed or window was closed
    		running = !glfwGetKey(GLFW_KEY_ESC) &amp;&amp; glfwGetWindowParam(GLFW_OPENED);
    	}
     
    	// Close window and terminate GLFW
    	renderer.terminate();
    	glfwTerminate();
     
    	// Exit program
    	return 0;
    }

  2. #2
    Member Regular Contributor Rosario Leonardi's Avatar
    Join Date
    Aug 2008
    Location
    Italy
    Posts
    354

    Re: GLFW+VBO+Shader = black screen?

    First bug, width and height are int, probably you are getting one as result of the division.
    Code :
    gluPerspective(45.0f, width/height , 0.1f, 255.0f);
    Second bug
    Code :
    float verts[] = {
      0.0f,  1.0f, 0.0f,
      1.0f, -1.0f, 0.0f,
      1.0f, -1.0f, 0.0f
    };
    Two point are the same, openGL don't draw zero area triangles.

    Can you see the quad? Maybe is a shader error.
    ~ ~ I tell you, realtime 3D is made of blood, sweat and screams! ~ ~

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •