I have an issue where my program renders a black screen on other computers. I narrowed it down to when a different graphics card is being used. When I run the program using Integrated Graphics (default) it works just fine. However, when I run the program using High-Performance NVIDIA Processor it just shows a black screen.
I am using non-static Glew32 that I made using CMAKE specifically for Visual Studio 11 2012 Win32. Glew experiment is set to true.
Shader errors output to log file. (There are none right now)
Main Question: Is there a specific way of setting up and rendering OpenGL for NVIDIA Graphics so that it renders properly, and not a black screen? Alternatively, is there a way to setup and use OpenGL so it works on every graphics card?
Edit: nvcompatlog.txt: Trying to draw without a program bound.
(Is this a big clue as to what is wrong? I can not find anything about how to solve this in any specific google search.)
I'm assuming this means my shader program is not being bound before I am rendering. So there must be something there that NVIDIA does not like.
I have another shader that just renders with Ortho view fonts/UIelements, and those render just fine ontop of the black screen.
I stripped my shader down to pretty much nothing. Got rid of all glGetUniform calls to uniforms that do not exist, all variables that aren't used are gone. Still black screen.
OS: Windows 8.1, 64-bit
GPU: GeForce GTX 970M
Source Code:
Generating VBO, VAO, etc.
glGenVertexArrays( 1, &mesh->GL_VBO_ID );
glBindVertexArray( mesh->GL_VBO_ID );
CheckGLError();
glEnableVertexAttribArray ( 0 );
glEnableVertexAttribArray ( 1 );
glEnableVertexAttribArray ( 2 );
CheckGLError();
glGenBuffers ( 1, &mesh->GL_VertexBuffer_ID );
glGenBuffers ( 1, &mesh->GL_IndexBuffer_ID );
CheckGLError();
glBindBuffer ( GL_ARRAY_BUFFER, mesh->GL_VertexBuffer_ID );
CheckGLError();
unsigned int totalVertBufferSizeBYTES = numIndicesInIndexArray * sizeof ( sVertex_p4t4n4 ); ;
glBufferData ( GL_ARRAY_BUFFER, totalVertBufferSizeBYTES, pTempVertArray, GL_DYNAMIC_DRAW );
CheckGLError();
unsigned int bytesInOneVertex = sizeof( sVertex_p4t4n4 );
unsigned int byteOffsetToPosition = offsetof( sVertex_p4t4n4, Pos );
unsigned int byteOffsetToNormal = offsetof( sVertex_p4t4n4, Normal );
unsigned int byteOffsetToUVCoords = offsetof( sVertex_p4t4n4, TexUVx2 );
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToPosition );
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToUVCoords );
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, bytesInOneVertex, (GLvoid*)byteOffsetToNormal );
CheckGLError();
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, mesh->GL_IndexBuffer_ID );
CheckGLError();
unsigned int sizeOfIndexArrayInBytes = numIndicesInIndexArray * sizeof( GLuint );
glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeOfIndexArrayInBytes, pIndexArrayLocal, GL_DYNAMIC_DRAW);
CheckGLError();
glBindVertexArray( 0 );
CheckGLError();
Rendering
glBindVertexArray ( pGameObject->GL_VBO_ID );
unsigned int numberOfIndices = pGameObject->numTriangles * 3;
glDrawElements( GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_INT, (GLvoid*)0);
CheckGLError();
Create Window
case WM_CREATE:
{
this->m_hdc = GetDC(hWnd);
setupPixelFormat();
int attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
0};
// Create temporary context to get a pointer to the function
HGLRC tmpContext = wglCreateContext(m_hdc);
// Make it current
wglMakeCurrent(this->m_hdc, tmpContext);
//Get the function pointer
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
// If this is NULL then OpenGL 4.0 is not supported
if ( !wglCreateContextAttribsARB )
{
MessageBox(NULL, "OpenGL 4.0 is not supported, falling back to GL #.#", "An error occurred", MB_ICONERROR | MB_OK);
this->m_hglrc = tmpContext;
}
else
{
//Create an OpenGL 4.0 context using the new function
this->m_hglrc = wglCreateContextAttribsARB(this->m_hdc, 0, attribs);
// Delete the temporary context
wglDeleteContext(tmpContext);
}
// Make the GL context current
wglMakeCurrent(this->m_hdc, this->m_hglrc);
// We are running!
this->m_bIsRunning = true;
}
break;
Vertex Shader
#version 400
layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_UV_x2;
layout(location=2) in vec4 in_Normal;
out vec4 ex_PositionWorld;
out vec4 ex_Normal;
out vec4 ex_UV_x2;
uniform mat4 ModelMatrix;
uniform mat4 RotationMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
void main(void)
{
mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
gl_Position = MVP * in_Position;
ex_PositionWorld = ModelMatrix * in_Position;
ex_Normal = RotationMatrix * normalize(in_Normal);
ex_UV_x2 = in_UV_x2;
return;
}
Fragment Shader
#version 400
// in from vertex shader
in vec4 ex_PositionWorld;
in vec4 ex_Normal;
in vec4 ex_UV_x2;
// Default colour output
out vec4 out_Colour;
// Lights
struct LightDesc
{
vec3 position;
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float attenConst;
float attenLinear;
float attenQuad;
float angle;
};
const int NUMLIGHTS = 10;
uniform LightDesc lights[NUMLIGHTS];
// Material
struct MaterialDesc
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
const int NUMMATERIALS = 1;
uniform MaterialDesc materials[NUMMATERIALS];
int curMat = 0;
// 1 Texture
uniform sampler2D Texture00;
// 1 CubeMap
uniform samplerCube SamplerCube00; // Used mostly for skybox. (Like to reserve for skybox reflections if illum set
// Shader ID
uniform int ShaderId;
// Camera
uniform vec3 eye;
vec3 ADSLightModel( in vec3 Normal,
in vec3 Position,
in int LightIndex );
void main(void)
{
// The SkyBox
if ( ShaderId == 1 )
{
vec4 colour = texture( SamplerCube00, ex_Normal.xyz );
out_Colour = vec4(colour.xyz, 1.0f);
return;
}
vec4 colour = texture( Texture00, ex_UV_x2.xy);
vec3 lightContrib = vec3(0.0f, 0.0f, 0.0f);
for (int lightIdx = 0; lightIdx < 10; lightIdx++)
{
lightContrib += ADSLightModel(ex_Normal.xyz, ex_PositionWorld.xyz, lightIdx);
}
colour *= lightContrib;
colour = clamp(colour, 0.0f, 1.0f);
out_Colour = vec4(colour.xyz, 1.0f);
return;
}
vec3 ADSLightModel( in vec3 Normal,
in vec3 Position,
in int LightIndex )
{
if ( length(lights[LightIndex].direction) != 0.0f )
{
vec3 diff = normalize(Position - lights[LightIndex].position);
if ( dot(diff, lights[LightIndex].direction) < lights[LightIndex].angle )
return vec3(0.0f, 0.0f, 0.0f);
}
// normal, light, view, and light reflection vectors
vec3 norm = normalize( Normal );
vec3 lightv = normalize( lights[LightIndex].position - Position);
vec3 viewv = normalize( eye - Position );
vec3 refl = -( reflect( lightv, norm ) );
// ambient light computation
vec3 ambient = materials[curMat].ambient * lights[LightIndex].ambient;
// diffuse light computation
vec3 diffuse = max(0.0f, dot(lightv, norm))
* materials[curMat].diffuse
* lights[LightIndex].diffuse;// myLightDiffuse;
// Calculate Attenuation
float dist = distance( Position, lights[LightIndex].position );
float atten = 1.0f /( lights[LightIndex].attenConst +
lights[LightIndex].attenLinear * dist +
lights[LightIndex].attenQuad * dist * dist );
diffuse *= atten;
// specular light computation
vec3 specular = vec3( 0.0f, 0.0f, 0.0f );
if( dot(lightv, norm) > 0.0f )
{
specular = pow( max(0.0f, dot(viewv,refl)), materials[curMat].shininess)
* materials[curMat].specular
* lights[LightIndex].specular;// // myLightSpecular;
specular *= atten;
}
return clamp( ambient + diffuse + specular, 0.0f, 1.0f );
}
ErrorLog: (There were no errors in log at one point, and black screen was still a result) The only error previously was when glDrawElements was called. Don't focus directly on these errors to answer my question. This is just here for extra information.
[cGameWindow.cpp:191] INVALID_ENUM // (Right after GlewInit() *not false*)
4.00 NVIDIA via Cg compiler
[cShaderManager.cpp:112] INVALID_OPERATION (glUseProgram)
[cRenderManager.cpp:312] INVALID_OPERATION (glGetUniformLocation)
[cRenderManager.cpp:232] INVALID_OPERATION (glClearColor)
[cRenderManager.cpp:357] INVALID_OPERATION (glUniform...)
[cRenderManager.cpp:662] INVALID_OPERATION (glUniform...)
[cRenderManager.cpp:685] INVALID_OPERATION
[cRenderManager.cpp:401] INVALID_OPERATION
[cRenderManager.cpp:410] INVALID_OPERATION
[cRenderManager.cpp:662] INVALID_OPERATION
[cRenderManager.cpp:591] INVALID_OPERATION
[cRenderManager.cpp:509] INVALID_OPERATION
[cRenderManager.cpp:662] INVALID_OPERATION
[cRenderManager.cpp:509] INVALID_OPERATION
[cRenderManager.cpp:662] INVALID_OPERATION
...
...
ErrorLog With stripped fragment shader (Minimal stuff)
[cGameWindow.cpp:191] INVALID_ENUM
4.00 NVIDIA via Cg compiler