what i am trying to do is;- creating custom window and enable `OpenGL` to draw on it using `glew`, I draw the triangle fine , rotate , scale , etc fine , but when it comes to use `Shaders`, the screen start to flicker and I got wrong colors on the triangle
ScreenManager Class:
void GraphicManager::CreateScreen(std::string screenName, int width, int hight, int posX, int posY)
{
WNDCLASSEX winex;
ZeroMemory(&winex, sizeof(WNDCLASSEX));
m_hInstance = m_hInstance;
m_screenName = screenName;
winex.cbSize = sizeof(WNDCLASSEX);
winex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
winex.lpfnWndProc = MsgProc;
winex.cbClsExtra = 0;
winex.cbWndExtra = 0;
winex.hInstance = m_hInstance;
winex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winex.hCursor = LoadCursor(NULL, IDC_ARROW);
winex.hbrBackground = NULL;
winex.lpszMenuName = NULL;
winex.lpszClassName = m_screenName.c_str();
winex.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
if (!RegisterClassEx(&winex))
{
MessageBox(NULL, std::string("Faild to register " + m_screenName + " class!").c_str(), NULL, NULL);
return ;
}
m_hwnd = CreateWindowEx(NULL, m_screenName.c_str(), m_screenName.c_str(), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, posX, posY, width, hight, NULL, NULL, m_hInstance, NULL);
if (!m_hwnd)
{
MessageBox(NULL, std::string("Faild to create " + m_screenName + " window!").c_str(), NULL, NULL);
}
EnableOGL();
}
void GraphicManager::EnableOGL()
{
m_hdc = GetDC(m_hwnd);
if (m_hdc == NULL)
MessageBox(NULL, "Faild to get Device Context!", "Error", NULL);
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
32, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, //Number of bits for the depthbuffer
8, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int PixelFormat;
PixelFormat = ChoosePixelFormat(m_hdc, &pfd);
SetPixelFormat(m_hdc, PixelFormat, &pfd);
m_hglrc = wglCreateContext(m_hdc);
if (m_hglrc == NULL)
MessageBox(NULL, "Faild to get OpenGL Context!", "Error", NULL);
if (!wglMakeCurrent(m_hdc, m_hglrc))
{
MessageBox(NULL, "Faild to Create OpenGL Context!", "Error", NULL);
}
if (glewInit() != GLEW_OK)
MessageBox(NULL, "Faild to Init GLEW!", "Error", NULL);
ShowWindow(m_hwnd, SW_SHOW);
UpdateWindow(m_hwnd);
}
void GraphicManager::RunScreenMainLoop()
{
m_game->Init();
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
m_game->Update();
m_game->Render();
SwapBuffers(m_hdc);
}
}
}
ShaderManager Class:
void ShaderManager::Load(const std::string& file, GLenum shaderType)
{
if (!isProgramCreated)
{
program = glCreateProgram();
isProgramCreated = true;
}
std::ifstream fil(std::string(path + file).c_str());
if (fil.is_open())
{
std::string output;
char buf[256];
while (!fil.eof())
{
fil.getline((buf), 256, '\n');
output.append(std::string(buf) + '\n');
}
GLuint shader = glCreateShader(shaderType);
if (shader == 0)
{
//std::exception("craete shader faild");
return;
}
const GLchar* shaderSourceStrings[1];
GLint shaderSourceStringLengths[1];
shaderSourceStrings[0] = output.c_str();
shaderSourceStringLengths[0] = output.length();
glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLengths);
glCompileShader(shader);
GLint shader_ok;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
if (!shader_ok)
{
fprintf(stderr, "Failed to compile %s:\n", file.data());
show_info_log(shader, glGetShaderiv, glGetShaderInfoLog);
glDeleteShader(shader);
return;
}
glAttachShader(program, shader);
//glBindAttribLocation(program, 0, "position");
glLinkProgram(program);
GLint program_ok;
glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
if (!program_ok)
{
fprintf(stderr, "Failed to link shader program:\n");
show_info_log(program, glGetProgramiv, glGetProgramInfoLog);
glDeleteProgram(program);
return;
}
glValidateProgram(program);//check valdiet
shaders[Utilities::SplitString(file, '.')[0]] = shader;
fil.close();
}
else
{
//std::exception(std::string("Faild to load" + file).c_str());
}
}
void ShaderManager::BindShaders()
{
glUseProgram(program);
}
and the Game Class:
void Game::Init()
{
glClearColor(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50, 640.0 / 480.0, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
engine->getShaderManager()->setPath("..\\Debug\\Engine\\Shaders\\");
engine->getShaderManager()->Load("VertexShader.vs", GL_VERTEX_SHADER);
engine->getShaderManager()->Load("FragmentShader.vs", GL_FRAGMENT_SHADER);
engine->getShaderManager()->BindShaders();
}
void Game::Update()
{
}
void Game::Render()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3f(0, 1, -4);
glVertex3f(-1, -1, -4);
glVertex3f(1, -1, -4);
glEnd();
}
VertixShader :
void main()
{
gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex;
}
FragmentShader :
void main()
{
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
the final result should be a red triangle , but what am getting is mixed color triangle with flickering on the screen!
am not sure what am missing here!