Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: The black screen

  1. #1

    The black screen

    Hi all.

    Having completed my D3D renderers for my engine, I turned my attention to OpenGL. I say that because it is relevant a bit later on when I set up the various matrices.

    So, I've completed all the code that I thought I needed, but I'm getting a black screen, so I must be missing something. I check all my errors, but nothing is coming up. This is for the windows platform, and I'm not using GLEW or GLUT or any of that kind of stuff, just core functionality here.

    I'm taking out all the error checking in this code to keep it as brief as possible. Can someone take a look through it and see if they see any issues?

    I will start after I have set up the context. I think it's working fine up to that point (BTW, I print out the OGL version both after setting up a dummy context and then setting up the real context, and I get 4.0.0 first, then 3.3.0 second (which is correct, I request a 3.3.0 context from wglChoosePixelFormatARB()).

    The test geometry vertex and index data:
    Code :
    	//geometry data
    	GLfloat BoxVerts[] = {(-0.6f,  0.8f, -0.6f), (0.6f,  0.8f, -0.6f), (0.6f,  0.8f,  0.6f), (-0.6f,  0.8f,  0.6f),
    						 (-0.8f, -0.8f, -0.8f), (0.8f, -0.8f, -0.8f), (0.8f, -0.8f,  0.8f), (-0.8f, -0.8f,  0.8f)};
    	GLfloat BoxColors[] = {(1.0f, 1.0f, 1.0f), (0.0f, 1.0f, 1.0f), (1.0f, 0.0f, 1.0f), (1.0f, 1.0f, 0.0f),
    							 (0.0f, 0.0f, 1.0f), (0.0f, 1.0f, 0.0f), (1.0f, 0.0f, 0.0f), (0.0f, 1.0f, 0.0f)};
    	unsigned int BoxIndices[] = {3,1,0, 2,1,3, 0,5,4, 1,5,0, 3,4,7, 0,4,3, 1,6,5, 2,6,1, 2,7,6, 3,7,2, 6,4,5, 7,4,6};

    The shader setup

    Code :
    	//create the shader objects, compile and link them
    	GLuint VertexShader;
    	GLuint FragmentShader;
    	GLuint ShaderProgram;
    	char *Log;
    	GLint Size;
     
    	VertexShader = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(VertexShader, 1, &vString, NULL);
    	glCompileShader(VertexShader);
    	glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &Size);
    	Log = new char[Size];
    	glGetShaderInfoLog(VertexShader, Size, nullptr, Log); 
    	OutputDebugStringA(Log);
    	delete Log;
     
    	FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    	glShaderSource(FragmentShader, 1, &fString, NULL);
    	glCompileShader(FragmentShader);
    	glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &Size);
    	Log = new char[Size];
    	glGetShaderInfoLog(FragmentShader, Size, nullptr, Log); 
    	OutputDebugStringA(Log);
    	delete Log;
     
    	//create the program
    	ShaderProgram = glCreateProgram();
    	glAttachShader(ShaderProgram, VertexShader);
    	glAttachShader(ShaderProgram, FragmentShader);
     
    	//link and use the program
    	glLinkProgram(ShaderProgram);
    	glUseProgram(ShaderProgram);

    Setting up the attribute buffers
    Code :
    	//find the attribute locations
    	GLint PositionLocation;
    	GLint ColorLocation;
    	PositionLocation = glGetAttribLocation(ShaderProgram, "Position");
    	ColorLocation = glGetAttribLocation(ShaderProgram, "Color");
     
    	//create and bind a vertex array object
    	GLuint vao;
    	glGenVertexArrays(1, &vao);
    	glBindVertexArray(vao);
     
    	//create the attribute buffers
    	GLuint AttributeBuffer;
    	glGenBuffers(1, &AttributeBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, AttributeBuffer);
     
    	//fill the buffer
    	glBufferData(GL_ARRAY_BUFFER, sizeof(BoxVerts) + sizeof(BoxColors), nullptr, GL_STATIC_DRAW);
    	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(BoxVerts), BoxVerts);
    	glBufferSubData(GL_ARRAY_BUFFER, sizeof(BoxVerts), sizeof(BoxColors), BoxColors);
     
    	//relate the buffer data to the attributes in the shaders
    	glEnableVertexAttribArray(PositionLocation);
    	glVertexAttribPointer(PositionLocation, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)0);
    	glEnableVertexAttribArray(ColorLocation);
    	glVertexAttribPointer(ColorLocation, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(BoxVerts));
     
    	//create the index buffer
    	GLuint IndexBuffer;
    	glGenBuffers(1, &IndexBuffer);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
     
    	//fill the buffer
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(BoxIndices), BoxIndices, GL_STATIC_DRAW);

    setting the uniforms
    Code :
    	//set the matrices
    	GLuint UniformWorldMatrix;
    	GLuint UniformViewMatrix;
    	GLuint UniformProjectionMatrix;
     
    	float WorldMatrix[] = {0.707f, 0.0f, 0.707f, 0.0f,
    						   0.0f, 1.0f, 0.0f, 0.0f,
    						   -0.707f, 0.0f, 0.707f, 0.0f,
    						   0.0f, 0.0f, 0.0f, 1.0f};
    	float ViewMatrix[] = {1.0f, 0.0f, 0.0f, 0.0f,
    						  0.0f, 1.0f, 0.0f, 0.0f,
    						  0.0f, 0.0f, 1.0f, 10.0f,
    						  0.0f, 0.0f, 0.0f, 1.0f};
    	float ProjectionMatrix[] = {4.0f, 0.0f, 0.0f, 0.0f,
    						        0.0f, 4.0f, 0.0f, 0.0f,
    						        0.0f, 0.0f, 1.0f, -1.0f,
    						        0.0f, 0.0f, 1.0f, 0.0f};
     
    	UniformWorldMatrix = glGetUniformLocation(ShaderProgram, "WorldMatrix");
    	UniformViewMatrix = glGetUniformLocation(ShaderProgram, "ViewMatrix");
    	UniformProjectionMatrix = glGetUniformLocation(ShaderProgram, "ProjectionMatrix");
    	glUniformMatrix4fv(UniformWorldMatrix, 1, GL_FALSE, WorldMatrix);
    	glUniformMatrix4fv(UniformViewMatrix, 1, GL_FALSE, ViewMatrix);
    	glUniformMatrix4fv(UniformProjectionMatrix, 1, GL_FALSE, ProjectionMatrix);

    Windows code
    Code :
        //pop up the window
        ShowWindow(ControlWindowHandle, true);
     
    	while (true)
            {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                if (msg.message == WM_QUIT)
                    {
                    break;
                    }
                TranslateMessage(&msg);
                DispatchMessage(&msg);
                }
            else
                {
                Sleep(1);   //do not max out processor
    	    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));   
                }
            }
     
    	return 0;
    	}

    [EDIT: I broke up the wall of code a bit for easier reading. I also changed the last parameter of glDrawElements to 0 (I've seen conflicting reports on what to put in here, but I think 0 is correct, let me know if that's wrong).]

    Okay, a lot of code, I know, but hopefully it's readable.

    Alright, the hard coded matrices are the same ones I use from my D3D renderer (they are not hard coded there, but the values I use here are what they end up being). It occurs to me that this may not be right (there are handedness differences between OGL and D3D, right? Which would change the perspective matrix?). I can mess with that (although if anyone has a link somewhere that explains the differences and how they affect the matrices, that would be good).

    The values for the box vertices/indeces are the same as from D3D, so I'm not concerned those are wrong.

    The shaders are as such:

    Code :
    	const char *vString = "																\
    		#version 330\n 																	\
    																						\
    		in vec3 Position;																\
    		in vec3 Color;																	\
    		out vec3 FragColor;																\
    		uniform mat4 WorldMatrix;														\
    		uniform mat4 ViewMatrix;														\
    		uniform mat4 ProjectionMatrix;													\
    																						\
    		void main ()																	\
    			{																			\
    			vec4 Vertex = vec4(Position, 1.0);											\
    			gl_Position = (ProjectionMatrix * (WorldMatrix * ViewMatrix)) * Vertex;		\
    			FragColor = Color;															\
    			}";
     
    	const char *fString = "																\
    		#version 330\n 																	\
    																						\
    		in vec3 FragColor;																\
    		out vec4 OutColor;																\
    																						\
    		void main ()																	\
    			{																			\
    			OutColor = vec4(FragColor, 1.0);											\
    			}";

    So, does anyone see what it is that I'm missing or messing up?

  2. #2
    Senior Member Regular Contributor
    Join Date
    Dec 2009
    Posts
    105

    Re: The black screen

    Silly question but are you using SwapBuffers to flip your scene into the screen?

  3. #3

    Re: The black screen

    Believe me, there are no silly questions I'm sure whatever I'm doing wrong, it's something silly like that. I'm a complete newbie when it comes to OGL, I'm going off my references and what I can study on the internet (and unfortunately, just about everything assumes use of GLUT, GLEW etc, which I'm not using, so it's rough going).

    No, I wasn't using SwapBuffer, but that was because I wasn't requesting a double buffered pixel format. Since that seems like a very good idea, I changed that. My pixel format selector now looks like such (this happens before all that code I posted above)

    Code :
    	//get a real pixel format
    	unsigned int PixelCount;
    	int PixAttribs[] = {
    		WGL_SUPPORT_OPENGL_ARB, 1,
    		WGL_DOUBLE_BUFFER_ARB, 1,
    		WGL_DRAW_TO_WINDOW_ARB, 1,
    		0};
    	int ContextAttribs[] = {
    		WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
    		WGL_CONTEXT_MINOR_VERSION_ARB, 3,
    		0};
    	int Format;
     
    	wglChoosePixelFormatARB(DC, PixAttribs, nullptr, 1, &Format, &PixelCount);
     
    	if (Format == -1)
    	OutputDebugString(L"ChoosePixelFormat (OGL): Unable to locate available Pixel Format\r\n");
     
    	//delete the old context
    	wglMakeCurrent(DC, nullptr);	
    	wglDeleteContext(RenderingContext);
     
    	//set up the real context
    	RenderingContext = wglCreateContextAttribsARB(DC, nullptr, ContextAttribs);
    	wglMakeCurrent(DC, RenderingContext);

    And then the draw call (in the message pump) is now

    Code :
            else
                {
                Sleep(1);   //do not max out processor
    	    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));   
    	    OGLPrintError("glDrawElements()");
    	    SwapBuffers(DC);
                }

    Still no luck with getting geometry on the screen though.

    I've also changed my perspective matrix after doing a bit of research. It is slightly different from what is used with D3D. Hopefully this is right, but let me know if you see anything suspicious:

    Code :
    	float ViewportWidth = 0.5f;
    	float ViewportHeight = 0.5f;
    	float ViewportNear = -1.0f;
    	float ViewportFar = -1000.0f;
    	float ProjectionMatrix[] = {1.0f, 0.0f, 0.0f, 0.0f,
    						        0.0f, 1.0f, 0.0f, 0.0f,
    						        0.0f, 0.0f, 1.0f, 0.0f,
    						        0.0f, 0.0f, -1.0f, 0.0f};
    	ProjectionMatrix[0] = (2.0f*ViewportNear)/ViewportWidth;
    	ProjectionMatrix[5] = (2.0f*ViewportNear)/ViewportHeight;
    	ProjectionMatrix[10] = (ViewportNear - ViewportFar)/(ViewportFar - ViewportNear);
    	ProjectionMatrix[11] = (-2.0f*ViewportFar*ViewportNear)/(ViewportFar - ViewportNear);

    Notice I set my near and far parameters to be negative, which I'm doing based on the idea that -z should go into the screen. But it is possible the math already accounts for that and they should be positive (I couldn't really tell to be honest), so I've tried them both ways. But still, no geometry.

  4. #4
    Senior Member Frequent Contributor
    Join Date
    Mar 2009
    Location
    Karachi, Pakistan
    Posts
    810

    Re: The black screen

    Quote Originally Posted by RonHiler
    I've also changed my perspective matrix after doing a bit of research. It is slightly different from what is used with D3D. Hopefully this is right, but let me know if you see anything suspicious:

    Code :
    	float ViewportWidth = 0.5f;
    	float ViewportHeight = 0.5f;
    	float ViewportNear = -1.0f;
    	float ViewportFar = -1000.0f;
    	float ProjectionMatrix[] = {1.0f, 0.0f, 0.0f, 0.0f,
    						        0.0f, 1.0f, 0.0f, 0.0f,
    						        0.0f, 0.0f, 1.0f, 0.0f,
    						        0.0f, 0.0f, -1.0f, 0.0f};
    	ProjectionMatrix[0] = (2.0f*ViewportNear)/ViewportWidth;
    	ProjectionMatrix[5] = (2.0f*ViewportNear)/ViewportHeight;
    	ProjectionMatrix[10] = (ViewportNear - ViewportFar)/(ViewportFar - ViewportNear);
    	ProjectionMatrix[11] = (-2.0f*ViewportFar*ViewportNear)/(ViewportFar - ViewportNear);

    ...
    Hi I think ur projection matrix is incorrect. It should be this
    Code :
    ProjectionMatrix[0] = (2.0f * zMin) / (xMax - xMin);
    ProjectionMatrix[5] = (2.0f * zMin) / (yMax - yMin);
    ProjectionMatrix[8] = (xMax + xMin) / (xMax - xMin);
    ProjectionMatrix[9] = (yMax + yMin) / (yMax - yMin);
    ProjectionMatrix[10] = -((zMax + zMin) / (zMax - zMin));
    ProjectionMatrix[11] = -1.0f;
    ProjectionMatrix[14] = -((2.0f * (zMax*zMin))/(zMax - zMin));
    ProjectionMatrix[15] = 0.0f;
    source: http://www.songho.ca/opengl/gl_projectionmatrix.html
    Regards,
    Mobeen

  5. #5

    Re: The black screen

    Thanks Mobeen. My matrix assumes a symmetric viewing volume, therefore:

    xMax - xMin = 2xMax = ViewportWidth
    yMax - yMin = 2yMax = ViewportHeight
    xMax + xMin = 0
    yMax + yMin = 0

    So I think all my equations simplify to exactly what you have written down, if I did the math right [and actually, if you scroll down one more matrix on the link you gave me, he shows the same equations for a symmetric viewing volume].

    However, I do notice you are specifying your arrays into the matrix in column major order (so that the -1.0 ends up at [11], while I was putting them in in row order (so it ends up at [14]. Should I be specifying them in column major? I'll try that, maybe there is my problem (or I guess I could just let OGL transpose them for me in the glUniformMatrix4fv() call). I'll give it a try and let you know.

    [EDIT: No, that still doesn't give me any geometry. I noticed your [10] array member does not match mine, so I changed to agree with yours (I must have made an error in my calculations).

    I'm at a total loss here. Is there any sort of diagnostic program I can run (similar to PIX for D3D?) or any way to find out what are in the attributes/uniforms as each vertex is processed through the shader, and (even better) what the out values end up being? I just don't even know what to look at here, at this point.

  6. #6
    Senior Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    592

    Re: The black screen

    Ahem, how can you say xMax - xMin = ViewportWidth

    You should have written WindowWidth IMO. You need to derive this width (and height) based on either HFOV or VFOV for symmetric frustums. Here's my code for a 90 degree hfov:

    frustum[1] = std::tan(.5 * M_HALFPI) * GetN(frustum);
    frustum[0] = -frustum[1];
    frustum[3] = aspect_ratio * frustum[1];
    frustum[2] = -frustum[3];

    frustum is the array {l, r, b, t, n, f}.

    Best solution to your problem IMO would be to take an existing demo from the Internet, which works, and then adapt it to your use. Also check for OpenGL errors if you aren't already! Also for shader compile and link errors! I think there's a tool that checks for errors on Windows automatically, but I don't use it, since I'm a Linux user.

    # define GL_DEBUG(x)\
    do {\
    GLenum error(glGetError());\
    if (GL_NO_ERROR != error)\
    {\
    std::cerr << gl_error_string(error) << std::endl;\
    BOOST_VERIFY(0);\
    }\
    } while(0)
    #else
    # define GL_DEBUG(x)
    #endif // NDEBUG

    Please be aware, that people in these forums generally frown upon this macro of mine (but hey, it compiles away in release builds and is portable). I compiled stuff with this macro for FreeBSD, Linux and Windows.

  7. #7

    Re: The black screen

    Quote Originally Posted by ugluk
    Ahem, how can you say xMax - xMin = ViewportWidth
    Okay, I'm going to remove this from the problem set, because whether it is correct or not, I'm about 95% sure it's not the underlying cause of my lack of geometry, heh. But I'll get to that in a while, I'm retooling the code at the moment.

    Best solution to your problem IMO would be to take an existing demo from the Internet, which works, and then adapt it to your use.
    Well, I would, if one existed that was even remotely useful to me. Sadly, 99.9% of the stuff out there on the internets uses Glu and/or glut and/or glew, and is therefore mostly useless to me. And I know you guys don't understand the whys of this, but take it as a given I won't be using any of those libraries.

    Also check for OpenGL errors if you aren't already!
    I do. Every line in my code that calls an OGL function is followed by another that goes something like:
    OGLPrintError("glBindVertexArray()");

    Which just checks for and prints out any errors. I took all those lines out of the code I posted for brevity, but they are there. And they report nothing amiss.

    Also for shader compile and link errors!
    Already done, look at the code.

    I like your macro. When (if EVER) I get this working and start converting to actual it production code, I'll probably adapt it to for my uses rather than make a function call like I'm doing now. Thanks.

    I'm going to repost my code in a minute, a bit simplified to remove the uniforms. I just want to see $%&amp;^&amp;^ triangles on the screen, I can deal with the matrices later once I have everything else working.

  8. #8
    Senior Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    592

    Re: The black screen

    There are folks here who provide modern OpenGL samples/tutorials. There's also a GL3 sample in the GL wiki. I'm sure you can find something. I've seen GL4+ context creation posts in these forums, just google for them.

    About my macro: maybe we like it, because we are both noobs.

    http://www.opengl.org/wiki/Tutorial:...tion_%28GLX%29

    BTW:
    //////////////////////////////////////////////////////////////////////////////
    GLubyte const* gl_error_string(GLenum error)
    {
    return gluErrorString(error);
    }

    Here I use GLU, but the wrapper is there precisely so I don't rely on GLU on platforms where it is not present. You can copy Mesa's implementation of gluErrorString(), if you don't like GLU.

  9. #9

    Re: The black screen

    First, thanks very much to everyone that has offered suggestions. It is much appreciated. I know how frustrating it can be dealing with a newbie, and I appreciate the patience you are showing with me

    I still have no geometry on screen, which is baffling me. I feel like I must be missing a step somewhere. And it's probably something really obvious and stupid that is simply getting missed in the vastness of the rest of the code.

    Okay, I'm going to post nearly the entirety of my test program. This is simplified from what I posted before, it uses no uniforms at all, so there are no matrix calculations to deal with. The code goes in order from top to bottom, though I'm breaking it into chunks here so it's not overwhelming. Also, I DO CHECK ALL OGL ERRORS (that code not shown). None are reported.

    Okay, so the definition of the vertices:
    Code :
    	GLfloat BoxVerts[] = {(20.0f,  50.0f, -20.0f), (40.0f,  50.0f, -20.0f), (40.0f,  50.0f, -40.0f), (20.0f,  50.0f, -40.0f),
    						 (10.0f, 10.0f, -10.0f), (50.0f, 10.0f, -10.0f), (50.0f, 10.0f, -60.0f), (10.0f, 10.0f, -60.0f)};
    	GLfloat BoxColors[] = {(1.0f, 1.0f, 1.0f), (0.0f, 1.0f, 1.0f), (1.0f, 0.0f, 1.0f), (1.0f, 1.0f, 0.0f),
    							 (0.0f, 0.0f, 1.0f), (0.0f, 1.0f, 0.0f), (1.0f, 0.0f, 0.0f), (0.0f, 1.0f, 0.0f)};
    	unsigned int BoxIndices[] = {3,1,0, 2,1,3, 0,5,4, 1,5,0, 3,4,7, 0,4,3, 1,6,5, 2,6,1, 2,7,6, 3,7,2, 6,4,5, 7,4,6};

    Since I'm not using matrices at all, I've defined the locations in window coords.

    Okay, creation of the window and setup of the dummy rendering context:

    Code :
        //fill in the class attributes for the main window
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
        wc.lpfnWndProc = WndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = Instance;
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
        wc.lpszMenuName = nullptr;
        wc.lpszClassName = L"OGL Test";
        wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
     
        //register
        RegisterClassEx(&amp;wc);
     
        //create and center the window on screen
        ControlWindowHandle = CreateWindowEx(NULL, L"OGL Test", L"OGL Test", WS_THICKFRAME | WS_MINIMIZEBOX | WS_SYSMENU, 0, 0, 800, 600, NULL, NULL, Instance, NULL);
     
    	//grab the device context
    	DC = GetDC(ControlWindowHandle);
     
    	//we can't use wglGetProcAddress without a context first, so set up a dummy context
    	PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
    	PixelFormatDesc.cColorBits = 24;
    	PixelFormatDesc.cAlphaBits = 8;
    	PixelFormatDesc.cDepthBits = 24;
    	PixelFormatDesc.cStencilBits = 8;
    	PixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
     
    	SetPixelFormat(DC, 1, &amp;PixelFormatDesc);
    	RenderingContext = wglCreateContext(DC);
    	wglMakeCurrent(DC, RenderingContext);	
     
    	//show the version of OGL that is available
    	OutputDebugStringA((char*)glGetString(GL_VERSION));
    	OutputDebugStringA("\r\n");

    Okay, now I grab pointers to all the functions I am going to use. I'm going to abbreviate this, as it's a lot of lines of essentially the same code, but it goes like such:

    Code :
    	//query for the functions we are going to need
    	bool (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *AttributeIntList, const float *AttributeFloatList, unsigned int MaxFormats, int *PixelFormat, unsigned int *PixelCount);
    	HGLRC (WINAPI *wglCreateContextAttribsARB)(HDC hdc, HGLRC ShareContext, const int *AttributeList);
    ...and so forth...
     
    	*reinterpret_cast<PROC*>(&amp;wglChoosePixelFormatARB) = wglGetProcAddress("wglChoosePixelFormatARB");
    	*reinterpret_cast<PROC*>(&amp;wglCreateContextAttribsARB) = wglGetProcAddress("wglCreateContextAttribsARB");
    ...and so forth...

    Now I delete the dummy context and set up the real context
    Code :
    	//get a real pixel format
    	unsigned int PixelCount;
    	int PixAttribs[] = {
    		WGL_SUPPORT_OPENGL_ARB, 1,
    		WGL_DOUBLE_BUFFER_ARB, 1,
    		WGL_DRAW_TO_WINDOW_ARB, 1,
    		0};
    	int ContextAttribs[] = {
    		WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
    		WGL_CONTEXT_MINOR_VERSION_ARB, 3,
    		0};
    	int Format;
     
    	wglChoosePixelFormatARB(DC, PixAttribs, nullptr, 1, &amp;Format, &amp;PixelCount);
     
    	if (Format == -1)
    	OutputDebugString(L"ChoosePixelFormat (OGL): Unable to locate available Pixel Format\r\n");
     
    	//delete the old context
    	wglMakeCurrent(DC, nullptr);	
    	wglDeleteContext(RenderingContext);
     
    	//set up the real context
    	RenderingContext = wglCreateContextAttribsARB(DC, nullptr, ContextAttribs);
    	wglMakeCurrent(DC, RenderingContext);	
     
    	//show the version of OGL we are using (should be 3.3.0)
    	OutputDebugStringA((char*)glGetString(GL_VERSION));
    	OutputDebugStringA("\r\n");

    Okay, these are the new shader strings

    Code :
    	const char *vString = "																\
    		#version 330\n 																	\
    																						\
    		in vec3 Position;																\
    		in vec3 Color;																	\
    		out vec3 FragColor;																\
    																						\
    		void main ()																	\
    			{																			\
    			gl_Position = vec4(Position, 1.0);											\
    			FragColor = Color;															\
    			}";
     
    	const char *fString = "																\
    		#version 330\n 																	\
    																						\
    		in vec3 FragColor;																\
    		out vec4 OutColor;																\
    																						\
    		void main ()																	\
    			{																			\
    			OutColor = vec4(FragColor, 1.0);											\
    			}";

    Those are used to create, link, and use the shaders, like such:

    Code :
    	GLuint VertexShader;
    	GLuint FragmentShader;
    	GLuint ShaderProgram;
    	char *Log;
    	GLint Size;
     
    	VertexShader = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(VertexShader, 1, &amp;vString, NULL);
    	glCompileShader(VertexShader);
    	glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &amp;Size);
    	Log = new char[Size];
    	glGetShaderInfoLog(VertexShader, Size, nullptr, Log); 
    	OutputDebugStringA(Log);
    	delete Log;
     
    	FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    	glShaderSource(FragmentShader, 1, &amp;fString, NULL);
    	glCompileShader(FragmentShader);
    	glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &amp;Size);
    	Log = new char[Size];
    	glGetShaderInfoLog(FragmentShader, Size, nullptr, Log); 
    	OutputDebugStringA(Log);
    	delete Log;
     
    	//create the program
    	ShaderProgram = glCreateProgram();
    	glAttachShader(ShaderProgram, VertexShader);
    	glAttachShader(ShaderProgram, FragmentShader);
     
    	//link and use the program
    	glLinkProgram(ShaderProgram);
    	glUseProgram(ShaderProgram);

    Grabbing the attribute locations
    Code :
    	//find the attribute locations
    	GLint PositionLocation;
    	GLint ColorLocation;
    	PositionLocation = glGetAttribLocation(ShaderProgram, "Position");
    	ColorLocation = glGetAttribLocation(ShaderProgram, "Color");

    Set up the vertex array object
    Code :
    	//create and bind a vertex array object
    	GLuint vao;
    	glGenVertexArrays(1, &amp;vao);
    	glBindVertexArray(vao);

    Create the attribute buffers, fill them, and link them to the shader attributes
    Code :
    	//create the attribute buffers
    	GLuint AttributeBuffer;
    	glGenBuffers(1, &amp;AttributeBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, AttributeBuffer);
     
    	//fill the buffer
    	glBufferData(GL_ARRAY_BUFFER, sizeof(BoxVerts) + sizeof(BoxColors), nullptr, GL_STATIC_DRAW);
    	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(BoxVerts), BoxVerts);
    	glBufferSubData(GL_ARRAY_BUFFER, sizeof(BoxVerts), sizeof(BoxColors), BoxColors);
     
    	//relate the buffer data to the attributes in the shaders
    	glEnableVertexAttribArray(PositionLocation);
    	glVertexAttribPointer(PositionLocation, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)0);
    	glEnableVertexAttribArray(ColorLocation);
    	glVertexAttribPointer(ColorLocation, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(BoxVerts));

    Create and fill the index buffer
    Code :
    	//create the index buffer
    	GLuint IndexBuffer;
    	glGenBuffers(1, &amp;IndexBuffer);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
     
    	//fill the buffer
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(BoxIndices), BoxIndices, GL_STATIC_DRAW);

    Is this possibly where I am missing a step? Do I need to enable that buffer somehow?

    And then finally the windows message pump
    Code :
        //pop up the window
        ShowWindow(ControlWindowHandle, true);
     
    	while (true)
            {
            if (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE))
                {
                if (msg.message == WM_QUIT)
                    {
                    break;
                    }
                TranslateMessage(&amp;msg);
                DispatchMessage(&amp;msg);
                }
            else
                {
                Sleep(1);   //do not max out processor
    			glClear(GL_COLOR_BUFFER_BIT);
    			glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, BoxIndices);   
    			glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   
    			SwapBuffers(DC);
                }
            }
     
    	return 0;

    Notice I've used glDrawElements() twice. There is some seriously conflicting information out there on what to put in that last parameter. Some people (who claim their code works) put in a nullptr (0, to refer to the starting point of the bound index buffer). Others, who make the same claim, put in the address of their index array. I'm thoroughly confused as to which is right (I suspect the former because the index array is already bound to the pipeline, so I see no reason why we need to pass it into the draw call at all, but I could be wrong).

    Alright, just in case, I'll also post my message handler. There is nothing special here.

    Code :
    //---------------------------------------------------------------------------
    long CALLBACK WndProc(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
        {
    	PAINTSTRUCT ps;
    	HDC hdc;
     
    	switch (Message)
    		{
    		case WM_DESTROY:
    			{
    			PostQuitMessage(0);
    			return 0;
    			}
    		case WM_KEYDOWN:
    			{
    			if (wParam == VK_ESCAPE)
    				{
    				DestroyWindow(Wnd);
    				return 0;
    				}
    			}
    		case WM_PAINT:
    			{
    			hdc = BeginPaint(Wnd, &amp;ps);
    			EndPaint(Wnd, &amp;ps);
    			break;
    			}
    		}
    	return DefWindowProc(Wnd, Message, wParam, lParam);
        }

    Sorry for posting so much code. I hope it becomes evident from what I've posted what I'm missing.

  10. #10

    Re: The black screen

    Success guys!

    See, I TOLD you it was something really stupid.

    glFlush();

    that's all it took. I now have geometry on the screen. Wooh!

    Although the fact that I HAVE to call glFlush to see geometry on the screen suggests to me there might be something amiss with my double buffer, as my understanding was that glFlush shouldn't have to be called at all. I'll have to look into what is going on with that.

    Also I'm not getting the results I expect, it's almost like the buffers are reading interleaved instead of one after the other like I intended.

    But I have something on the screen, so I can work with it and get all this stuff figured out. Which is a huge relief, heh.

    Thanks again everyone. I know I was a PITA. Hopefully I can take it from here.

Page 1 of 2 12 LastLast

Similar Threads

  1. Black screen
    By Tim88348 in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 09-20-2011, 10:15 AM
  2. just get a black screen
    By chewabob in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 05-12-2011, 11:15 AM
  3. Black screen using Print Screen
    By specifikys in forum OpenGL: Windows
    Replies: 1
    Last Post: 11-01-2010, 01:32 PM
  4. Replies: 0
    Last Post: 07-29-2009, 12:54 PM
  5. Replies: 0
    Last Post: 09-30-2003, 08:58 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean