If I have turned off MSAA, then textures are displayed correctly. When I turn on MSAA, textures (bmp and dds) are black, but objects without bound textures have correct colors.
So shortly:
- MSAA off -> everything is displayed correctly
- MSAA on -> not textured objects are displayed correctly, textured objects are black.
How to fix this problem?
Codes:
Window and antialiasing initiation:
bool TCore::SetDCPixelFormat(HDC hDC_1) //ustawienie formatu pikseli
{
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
int PixelFormat = ChoosePixelFormat(hDC_1, &pfd);
if(PixelFormat == 0)
{
ERROR_H.Error_Log("ChoosePixelFormat failed!", false);
return false;
}
if(SetPixelFormat(APP.hDC, OGL_WNDW.MSAAPixelFormat == 0 ? PixelFormat : OGL_WNDW.MSAAPixelFormat, &pfd) == false)
{
ERROR_H.Error_Log("SetPixelFormat failed!", false);
return false;
}
return true;
}
//--------------------------------------------------------------------
bool TCore::InitGlew(void) //inicjacja rozszerzeń glew
{
if(glewInit() != GLEW_OK)
{
ERROR_H.Error_Log("glewInit failed!", false);
return false;
}
if (!glewIsSupported(
"GL_VERSION_3_3 "
"GL_ARB_vertex_program "
"GL_ARB_fragment_program "
)) {
ERROR_H.Error_Log("Unable to load extensions
Exiting...
", false);
return false;
}
return true;
};
//---------------------------------------------------------------------
bool TCore::InitwGlew(void) //inicjacja rozszerzeń wglew
{
if (!wglewIsSupported(
"WGLEW_ARB_pixel_format "
"WGLEW_EXT_swap_control "
"WGLEW_ARB_create_context "
)) {
//ERROR_H.Error_Log("Unable to load wglew extensions
Exiting...
", false);
//return false;
}
return true;
};
//---------------------------------------------------------------------
bool TCore::Make_Antialiasing(void)
{
if (OGL_WNDW.MSAA_On == true) { //MSAA - od 2x do 24x
if(OGL_WNDW.MSAAPixelFormat == 0 && OGL_WNDW.MSAA_Samples > 0)
{
if(WGLEW_ARB_pixel_format && GLEW_ARB_multisample)
{
while(OGL_WNDW.MSAA_Samples > 0)
{
UINT NumFormats = 0;
int PFAttribs[] =
{
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 24,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_SAMPLE_BUFFERS_ARB, 1, //GL_TRUE,
WGL_SAMPLES_ARB, OGL_WNDW.MSAA_Samples,
0
};
bool result = wglChoosePixelFormatARB(APP.hDC, PFAttribs, NULL, 1, &OGL_WNDW.MSAAPixelFormat, &NumFormats);
if(result == true && NumFormats > 0) {
break;
}
OGL_WNDW.MSAA_Samples--;
}
wglDeleteContext(OGL_WNDW.hGLRC);
DestroyWindow(APP.hWnd);
UnregisterClass(//here forum doesn't let post code);
return InitApplication();
}
else
{
OGL_WNDW.MSAA_Samples = 0;
ERROR_H.Error_Log("Unable to load extensions: WGLEW_ARB_pixel_format or GLEW_ARB_multisample", false);
}
}
else {
//ERROR_H.Error_Log("OGL_WNDW.MSAAPixelFormat (=" + FloatToStr(OGL_WNDW.MSAAPixelFormat) + ") or OGL_WNDW.MSAA_Samples (=" + FloatToStr(OGL_WNDW.MSAA_Samples) + ") is incorrect", false);
}
}
return true;
};
//---------------------------------------------------------------------
bool TCore::Create_OpenGL(void)
{
APP.hDC = GetDC(APP.hWnd);
if(APP.hDC == NULL){
ERROR_H.Error_Log("GetDC failed!", false);
return false;
}
if (SetDCPixelFormat(APP.hDC) == false) {
return false;
}
OGL_WNDW.hGLRC = wglCreateContext(APP.hDC);
if(OGL_WNDW.hGLRC == NULL)
{
ERROR_H.Error_Log("wglCreateContext failed!", false);
return false;
}
if(wglMakeCurrent(APP.hDC, OGL_WNDW.hGLRC) == false)
{
ERROR_H.Error_Log("wglMakeCurrent (1) failed!", false);
return false;
}
if (!InitGlew()) {
return false;
}
if (!InitwGlew()) {
return false;
}
return true;
}
//-----------------------------------------------------------------------
bool TCore::Check_Folder(UnicodeString Folder)
{
if (!DirectoryExists(Folder)) {
ERROR_H.Error_Log("Brak folderu " + Folder, false);
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool TCore::InitApplication(void)
{
SetDoubleClickTime(DblClickTime); //ustawia czas pomiędzy dwoma kliknięciami w podwójnym kliku
Load_Cursors();
if (!Check_Folder(APP.MeshesPath) || !Check_Folder(APP.TexturesPath) || !Check_Folder(APP.GUITexturesPath) || !Check_Folder(APP.SoundsPath) || !Check_Folder(APP.ShadersPath)) {
return false;
}
if (Create_Window(APP.hInstance, APP.Title, APP.Width, APP.Height) == false) {
return false;
}
if (Create_OpenGL() == false) {
return false;
}
if (!Make_Antialiasing()) {
return false;
}
//tworzenie contextu w wersji OpenGL 3.3
if(WGLEW_ARB_create_context)
{
wglMakeCurrent(NULL,NULL); //???
wglDeleteContext(OGL_WNDW.hGLRC);
int GL33RCAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
};
OGL_WNDW.hGLRC = wglCreateContextAttribsARB(APP.hDC, 0, GL33RCAttribs);
if(OGL_WNDW.hGLRC == NULL)
{
ERROR_H.Error_Log("wglCreateContextAttribsARB failed!", false);
return false;
}
if(wglMakeCurrent(APP.hDC, OGL_WNDW.hGLRC) == false)
{
ERROR_H.Error_Log("wglMakeCurrent (2) failed!", false);
return false;
}
}
else
{
ERROR_H.Error_Log("WGL_ARB_create_context not supported!", false);
return false;
}
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &TEX_SET.Max_Texture_Size);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &TEX_SET.Max_Texture_Units);
if(GLEW_EXT_texture_filter_anisotropic)
{
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &TEX_SET.Max_Anisotropy);
if (TEX_SET.Anisotropy_Filter_Samples > TEX_SET.Max_Anisotropy) {
TEX_SET.Anisotropy_Filter_Samples = TEX_SET.Max_Anisotropy;
}
}
//ustawianie VSync
if (!OGL_WNDW.VSync_On) {
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(0);
}
else {
ERROR_H.Error_Log("WGLEW_EXT_swap_control not supported!", false);
}
}
else {
if(WGLEW_EXT_swap_control)
{
wglSwapIntervalEXT(1);
}
else {
ERROR_H.Error_Log("WGLEW_EXT_swap_control not supported!", false);
}
}
if (!GAME.Load_Game()) {
return false;
}
return true;
}
//------------------------------------------------------------------------------
void TCore::Show_Window(bool Maximized)
{
RECT dRect, wRect, cRect;
GetWindowRect(GetDesktopWindow(), &dRect);
GetWindowRect(APP.hWnd, &wRect);
GetClientRect(APP.hWnd, &cRect);
wRect.right += APP.Width - cRect.right;
wRect.bottom += APP.Height - cRect.bottom;
wRect.right -= wRect.left;
wRect.bottom -= wRect.top;
wRect.left = dRect.right / 2 - wRect.right / 2;
wRect.top = dRect.bottom / 2 - wRect.bottom / 2;
MoveWindow(APP.hWnd, wRect.left, wRect.top, wRect.right, wRect.bottom, FALSE);
ShowWindow(APP.hWnd, Maximized ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
UpdateWindow(APP.hWnd);
}
//-----------------------------------------------------------------------
Textures generating:
Generate_Texture_DDS(DDS_IMAGE_DATA *pDDSImageData1, bool Make_mipmaps, GLint Texture_Min_Filter, GLint Texture_Mag_Filter)
{
if(pDDSImageData1 != NULL ) {
int nHeight = pDDSImageData1->height;
int nWidth = pDDSImageData1->width;
int nNumMipMaps = pDDSImageData1->numMipMaps;
int nBlockSize;
if(pDDSImageData1->format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
nBlockSize = 8;
else
nBlockSize = 16;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //?
glGenTextures(1, &TEXTURE_MANAGER.Texture_s.Texture_ID);
glBindTexture(GL_TEXTURE_2D, TEXTURE_MANAGER.Texture_s.Texture_ID);
//parametry tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Texture_Min_Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Texture_Mag_Filter); // Filtrowanie liniowe
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, CORE.TEX_SET.Anisotropy_Filter_Samples);
int nSize;
int nOffset = 0;
// Load the mip-map levels
if (Make_mipmaps == false) {
nNumMipMaps = 1;
}
for(int i = 0; i < nNumMipMaps; ++i) {
if(nWidth == 0) nWidth = 1;
if(nHeight == 0) nHeight = 1;
nSize = ((nWidth+3)/4) * ((nHeight+3)/4) * nBlockSize;
glCompressedTexImage2DARB(GL_TEXTURE_2D,
i,
pDDSImageData1->format,
nWidth,
nHeight,
0,
nSize,
pDDSImageData1->pixels + nOffset);
nOffset += nSize;
// Half the image size for the next mip-map level...
nWidth = (nWidth / 2);
nHeight = (nHeight / 2);
}
}
}
//-----------------------------------------------------------------------
void TTextureManager::Generate_Texture_BMP(unsigned char *TextureData, bool Make_mipmaps, GLint Texture_Min_Filter, GLint Texture_Mag_Filter)
{
glGenTextures(1, &Texture_s.Texture_ID); // Utworzenie tekstury
glBindTexture(GL_TEXTURE_2D, Texture_s.Texture_ID); // ustawia teksturę jako bieżącą i w 2D
//parametry tekstury
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Texture_Min_Filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Texture_Mag_Filter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, CORE.TEX_SET.Anisotropy_Filter_Samples);
if (BMP_has_alpha == true) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, BMP_Width, BMP_Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, TextureData);
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BMP_Width, BMP_Height, 0, GL_BGR, GL_UNSIGNED_BYTE, TextureData);
}
if (Make_mipmaps == true) {
//The parameters to control the total number of mipmaps levels are given by:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
glGenerateMipmap(GL_TEXTURE_2D);
}
}
//-----------------------------------------------------------------------
Shaders:
vertex:
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec4 vertexColor;
layout(location = 2) in vec2 vertexUV;
// Output data ; will be interpolated for each fragment.
out vec4 fragmentColor;
out vec2 UV;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;
void main(){
// Output position of the vertex, in clip space : MVP * position
gl_Position = MVP * vec4(vertexPosition_modelspace,1.0);
// The color of each vertex will be interpolated
// to produce the color of each fragment
fragmentColor = vertexColor;
// UV of the vertex. No special space for this one.
UV = vertexUV;
}
fragment:
#version 330 core
// Interpolated values from the vertex shaders
in vec4 fragmentColor;
in vec2 UV;
// Ouput data
out vec4 color;
// Values that stay constant for the whole mesh.
uniform int UseBaseColor;
uniform int UseTexture;
uniform int UseDiffuseMap;
uniform int UseNormalMap;
uniform int UseSpecularMap;
uniform int UseGlowMap;
uniform int UseLightMap;
uniform sampler2D DiffuseMap;
uniform sampler2D NormalMap;
uniform sampler2D SpecularMap;
uniform sampler2D GlowMap;
uniform sampler2D LightMap;
void main()
{
if (UseTexture == 1 && UseDiffuseMap == 1) {
// Output color = color of the texture at the specified UV
color = texture(DiffuseMap, UV);
if (UseBaseColor == 1) {
color = (color + fragmentColor) / 2.0;
}
if (UseNormalMap == 1) {
//color = color;
}
if (UseSpecularMap == 1) {
//color = color;
}
if (UseGlowMap == 1) {
color = color + texture(GlowMap, UV);
if (color.r > 1.0) {
color.r = 1.0;
}
if (color.g > 1.0) {
color.g = 1.0;
}
if (color.b > 1.0) {
color.b = 1.0;
}
if (color.a > 1.0) {
color.a = 1.0;
}
}
if (UseLightMap == 1) {
//color = color;
}
}
else {
// Output color = color specified in the vertex shader,
// interpolated between all 3 surrounding vertices
color = fragmentColor;
}
}
Please help.