/*========================================================================= Program: Visualization Toolkit Module: TestFBOImplementation.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // This code test to make sure vtkOpenGLExtensionManager can properly get // extension functions that can be used. To do this, we convolve an image // with a kernel for a Laplacian filter. This requires the use of functions // defined in OpenGL 1.2, which should be available pretty much everywhere // but still has functions that can be loaded as extensions. #include "vtkConeSource.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkCamera.h" #include "vtkCallbackCommand.h" #include "vtkUnsignedCharArray.h" #include "vtkRegressionTestImage.h" #include "vtkOpenGLExtensionManager.h" #include "vtkgl.h" #include static bool ARB_texture_rectangle_supported=false; static bool depth_texture_supported=false; // OpenGL 1.4 or GL_ARB_depth_texture static bool srgb_texture_supported=false; // OpenGL 2.1 or GL_EXT_texture_sRGB static bool float_texture_supported=false; // GL_ARB_texture_float static bool integer_texture_supported=false; // GL_EXT_texture_integer (GeForce 8) // ---------------------------------------------------------------------------- // Description: // Return a string matching the OpenGL errorCode. // \post result_exists: result!=0 const char *OpenGLErrorMessage2(GLenum errorCode) { const char *result; switch(errorCode) { case GL_NO_ERROR: result="No error"; break; case GL_INVALID_ENUM: result="Invalid enum"; break; case GL_INVALID_VALUE: result="Invalid value"; break; case GL_INVALID_OPERATION: result="Invalid operation"; break; case GL_STACK_OVERFLOW: result="stack overflow"; break; case GL_STACK_UNDERFLOW: result="stack underflow"; break; case GL_OUT_OF_MEMORY: result="out of memory"; break; case vtkgl::INVALID_FRAMEBUFFER_OPERATION_EXT: // GL_EXT_framebuffer_object, 310 result="invalid framebuffer operation ext"; break; default: result="unknown error"; } assert("post: result_exists" && result!=0); return result; } void CheckOpenGLError(const char *message) { GLenum errorCode=glGetError(); if(errorCode!=GL_NO_ERROR) { cout << "ERROR:" << OpenGLErrorMessage2(errorCode) << message << endl; } } void CheckMinValidValue(GLint value, GLint specMinValue) { if(valuespecMaxValue) { cout<<"This OpenGL implementation is not compliant with the OpenGL"; cout<<"specifications."<(uattachment); GLint params; vtkgl::GetFramebufferAttachmentParameterivEXT( vtkgl::FRAMEBUFFER_EXT,attachment, vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,¶ms); CheckOpenGLError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT"); switch(params) { case GL_NONE: cout<<" this attachment is empty"<=2.1) case vtkgl::COMPRESSED_SRGB_S3TC_DXT1_EXT: result="GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; break; case vtkgl::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: result="GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; break; case vtkgl::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: result="GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; break; case vtkgl::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: result="GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; break; default: result="unknown texture compression format"; break; } return result; } const char *MinMagModToString(int minMagMode) { const char *result; switch(minMagMode) { case GL_NEAREST: result="GL_NEAREST"; break; case GL_LINEAR: result="GL_LINEAR"; break; case GL_NEAREST_MIPMAP_NEAREST: result="GL_NEAREST_MIPMAP_NEAREST"; break; case GL_NEAREST_MIPMAP_LINEAR: result="GL_NEAREST_MIPMAP_LINEAR"; break; case GL_LINEAR_MIPMAP_NEAREST: result="GL_LINEAR_MIPMAP_NEAREST"; break; case GL_LINEAR_MIPMAP_LINEAR: result="GL_LINEAR_MIPMAP_LINEAR"; break; default: result=0; // assert("check: impossible case." && 0); break; } return result; } const char *InternalTextureFormatToString(int internalFormat) { const char *result; switch(internalFormat) { case 1: result="backwards compatible GL_LUMINANCE"; break; case 2: result="backwards compatible GL_LUMINANCE_ALPHA"; break; case 3: result="backwards compatible GL_RGB"; break; case 4: result="backwards compatible GL_RGBA"; break; case GL_ALPHA: result="GL_ALPHA"; break; case GL_DEPTH_COMPONENT: result="GL_DEPTH_COMPONENT"; break; case GL_LUMINANCE: result="GL_LUMINANCE"; break; case GL_LUMINANCE_ALPHA: result="GL_LUMINANCE_ALPHA"; break; case GL_INTENSITY: result="GL_INTENSITY"; break; case GL_RGB: result="GL_RGB"; break; case GL_RGBA: result="GL_RGBA"; break; // sized internal format case GL_ALPHA4: result="GL_ALPHA4"; break; case GL_ALPHA8: result="GL_ALPHA8"; break; case GL_ALPHA12: result="GL_ALPHA12"; break; case GL_ALPHA16: result="GL_ALPHA16"; break; case vtkgl::DEPTH_COMPONENT16: result="GL_DEPTH_COMPONENT16"; break; case vtkgl::DEPTH_COMPONENT24: result="GL_DEPTH_COMPONENT24"; break; case vtkgl::DEPTH_COMPONENT32: result="GL_DEPTH_COMPONENT32"; break; case GL_LUMINANCE4: result="GL_LUMINANCE4"; break; case GL_LUMINANCE8: result="GL_LUMINANCE8"; break; case GL_LUMINANCE12: result="GL_LUMINANCE12"; break; case GL_LUMINANCE16: result="GL_LUMINANCE16"; break; case GL_LUMINANCE4_ALPHA4: result="GL_LUMINANCE4_ALPHA4"; break; case GL_LUMINANCE6_ALPHA2: result="GL_LUMINANCE6_ALPHA2"; break; case GL_LUMINANCE8_ALPHA8: result="GL_LUMINANCE8_ALPHA8"; break; case GL_LUMINANCE12_ALPHA4: result="GL_LUMINANCE12_ALPHA4"; break; case GL_LUMINANCE12_ALPHA12: result="GL_LUMINANCE12_ALPHA12"; break; case GL_LUMINANCE16_ALPHA16: result="GL_LUMINANCE16_ALPHA16"; break; case GL_INTENSITY4: result="GL_INTENSITY4"; break; case GL_INTENSITY8: result="GL_INTENSITY8"; break; case GL_INTENSITY12: result="GL_INTENSITY12"; break; case GL_INTENSITY16: result="GL_INTENSITY16"; break; case GL_R3_G3_B2: result="GL_R3_G3_B2"; break; case GL_RGB4: result="GL_RGB4"; break; case GL_RGB5: result="GL_RGB5"; break; case GL_RGB8: result="GL_RGB8"; break; case GL_RGB10: result="GL_RGB10"; break; case GL_RGB12: result="GL_RGB12"; break; case GL_RGB16: result="GL_RGB16"; break; case GL_RGBA2: result="GL_RGBA2"; break; case GL_RGBA4: result="GL_RGBA4"; break; case GL_RGB5_A1: result="GL_RGB5_A1"; break; case GL_RGBA8: result="GL_RGBA8"; break; case GL_RGB10_A2: result="GL_RGB10_A2"; break; case GL_RGBA12: result="GL_RGBA12"; break; case GL_RGBA16: result="GL_RGBA16"; break; // OpenGL 2.1 (GL_EXT_texture_sRGB) case vtkgl::SRGB8: result="GL_SRGB8"; break; case vtkgl::SRGB8_ALPHA8: result="GL_SRGB8_ALPHA8"; break; case vtkgl::SLUMINANCE8: result="GL_SLUMINANCE8"; break; case vtkgl::SLUMINANCE8_ALPHA8: result="GL_SLUMINANCE8_ALPHA8"; break; // Provided by GL_ARB_texture_float case vtkgl::RGBA32F_ARB: result="GL_RGBA32F_ARB"; break; case vtkgl::RGB32F_ARB: result="GL_RGB32F_ARB"; break; case vtkgl::ALPHA32F_ARB: result="GL_ALPHA32F_ARB"; break; case vtkgl::INTENSITY32F_ARB: result="GL_INTENSITY32F_ARB"; break; case vtkgl::LUMINANCE32F_ARB: result="GL_LUMINANCE32F_ARB"; break; case vtkgl::LUMINANCE_ALPHA32F_ARB: result="GL_LUMINANCE_ALPHA32F_ARB"; break; case vtkgl::RGBA16F_ARB: result="GL_RGBA16F_ARB"; break; case vtkgl::RGB16F_ARB: result="GL_RGB16F_ARB"; break; case vtkgl::ALPHA16F_ARB: result="GL_ALPHA16F_ARB"; break; case vtkgl::INTENSITY16F_ARB: result="GL_INTENSITY16F_ARB"; break; case vtkgl::LUMINANCE16F_ARB: result="GL_LUMINANCE16F_ARB"; break; case vtkgl::LUMINANCE_ALPHA16F_ARB: result="GL_LUMINANCE_ALPHA16F_ARB"; break; // Provided by GL_EXT_texture_integer (from GeForce 8) case vtkgl::RGBA32UI_EXT: result="GL_RGBA32UI_EXT"; break; case vtkgl::RGB32UI_EXT: result="GL_RGB32UI_EXT"; break; case vtkgl::ALPHA32UI_EXT: result="GL_ALPHA32UI_EXT"; break; case vtkgl::INTENSITY32UI_EXT: result="GL_INTENSITY32UI_EXT"; break; case vtkgl::LUMINANCE32UI_EXT: result="GL_LUMINANCE32UI_EXT"; break; case vtkgl::LUMINANCE_ALPHA32UI_EXT: result="GL_LUMINANCE_ALPHA32UI_EXT"; break; case vtkgl::RGBA16UI_EXT: result="GL_RGBA16UI_EXT"; break; case vtkgl::RGB16UI_EXT: result="GL_RGB16UI_EXT"; break; case vtkgl::ALPHA16UI_EXT: result="GL_ALPHA16UI_EXT"; break; case vtkgl::INTENSITY16UI_EXT: result="GL_INTENSITY16UI_EXT"; break; case vtkgl::LUMINANCE16UI_EXT: result="GL_LUMINANCE16UI_EXT"; break; case vtkgl::LUMINANCE_ALPHA16UI_EXT : result="GL_LUMINANCE_ALPHA16UI_EXT "; break; case vtkgl::RGBA8UI_EXT: result="GL_RGBA8UI_EXT"; break; case vtkgl::RGB8UI_EXT: result="GL_RGB8UI_EXT"; break; case vtkgl::ALPHA8UI_EXT: result="GL_ALPHA8UI_EXT"; break; case vtkgl::INTENSITY8UI_EXT: result="GL_INTENSITY8UI_EXT"; break; case vtkgl::LUMINANCE8UI_EXT: result="GL_LUMINANCE8UI_EXT"; break; case vtkgl::LUMINANCE_ALPHA8UI_EXT: result="GL_LUMINANCE_ALPHA8UI_EXT"; break; case vtkgl::RGBA32I_EXT: result="GL_RGBA32I_EXT"; break; case vtkgl::RGB32I_EXT: result="GL_RGB32I_EXT"; break; case vtkgl::ALPHA32I_EXT: result="GL_ALPHA32I_EXT"; break; case vtkgl::INTENSITY32I_EXT: result="GL_INTENSITY32I_EXT"; break; case vtkgl::LUMINANCE32I_EXT: result="GL_LUMINANCE32I_EXT"; break; case vtkgl::LUMINANCE_ALPHA32I_EXT: result="GL_LUMINANCE_ALPHA32I_EXT"; break; case vtkgl::RGBA16I_EXT: result="GL_RGBA16I_EXT"; break; case vtkgl::RGB16I_EXT: result="GL_RGB16I_EXT"; break; case vtkgl::ALPHA16I_EXT: result="GL_ALPHA16I_EXT"; break; case vtkgl::INTENSITY16I_EXT: result="GL_INTENSITY16I_EXT"; break; case vtkgl::LUMINANCE16I_EXT: result="GL_LUMINANCE16I_EXT"; break; case vtkgl::LUMINANCE_ALPHA16I_EXT: result="GL_LUMINANCE_ALPHA16I_EXT"; break; case vtkgl::RGBA8I_EXT: result="GL_RGBA8I_EXT"; break; case vtkgl::RGB8I_EXT: result="GL_RGB8I_EXT"; break; case vtkgl::ALPHA8I_EXT: result="GL_ALPHA8I_EXT"; break; case vtkgl::INTENSITY8I_EXT: result="GL_INTENSITY8I_EXT"; break; case vtkgl::LUMINANCE8I_EXT: result="GL_LUMINANCE8I_EXT"; break; case vtkgl::LUMINANCE_ALPHA8I_EXT: result="GL_LUMINANCE_ALPHA8I_EXT"; break; default: result=0; // assert("check: impossible case." && 0); // cout<<"unknown"<<"(0x"<< hex << ivalue[0] << dec << ")"; break; } return result; } const char *WrapModeToString(GLenum wrapMode) { const char *result; switch(wrapMode) { case GL_CLAMP: result="GL_CLAMP"; break; case GL_REPEAT: result="GL_REPEAT"; break; case vtkgl::CLAMP_TO_EDGE:// OpenGL>=1.2 or Gl_SGIS_texture_edge_clamp result="vtkgl::CLAMP_TO_EDGE"; break; case vtkgl::CLAMP_TO_BORDER:// OpenGL>=1.3 or GL_ARB_texture_border_clamp result="vtkgl::CLAMP_TO_BORDER"; break; case vtkgl::MIRRORED_REPEAT:// OpenGL>=1.4 or GL_ARB_texture_mirrored_repeat result="vtkgl::MIRRORED_REPEAT"; break; default: result=""; assert("check: impossible case." && 0); break; } return result; } const char *TextureComponentTypeToString(GLint ivalue) { const char *result; switch(ivalue) { case GL_NONE: // missing component result="missing"; break; case vtkgl::UNSIGNED_NORMALIZED_ARB: // default type for OpenGL 1.1, fixed-point component result=""; break; case GL_FLOAT: result="f"; // floating-point component, with GL_ARB_texture_float break; case GL_INT: result="i"; // signed unnormalized integer component, with GL_EXT_texture_integer (GeForce8) break; case GL_UNSIGNED_INT: result="ui"; // unsigned unnormalized integer component, with GL_EXT_texture_integer (GeForce8) break; default: result="error: unknown type"; break; } return result; } void QueryTextureObject(GLenum target) { assert("pre: valid_target" && (target==GL_TEXTURE_1D || target==GL_PROXY_TEXTURE_1D || target==GL_TEXTURE_2D || target==GL_PROXY_TEXTURE_2D || target==vtkgl::TEXTURE_CUBE_MAP_POSITIVE_X || target==vtkgl::TEXTURE_CUBE_MAP_NEGATIVE_X || target==vtkgl::TEXTURE_CUBE_MAP_POSITIVE_Y || target==vtkgl::TEXTURE_CUBE_MAP_NEGATIVE_Y || target==vtkgl::TEXTURE_CUBE_MAP_POSITIVE_Z || target==vtkgl::TEXTURE_CUBE_MAP_NEGATIVE_Z || target==vtkgl::PROXY_TEXTURE_CUBE_MAP || target==vtkgl::TEXTURE_3D || target==vtkgl::PROXY_TEXTURE_3D || target==vtkgl::TEXTURE_RECTANGLE_ARB || target==vtkgl::PROXY_TEXTURE_RECTANGLE_ARB )); GLint ivalue[4]; GLfloat fvalue[4]; glGetTexParameterfv(target,GL_TEXTURE_BORDER_COLOR,fvalue); CheckOpenGLError(""); cout<<"border color="<0) { cout<<"R"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_RED_TYPE_ARB,ivalue); cout<0) { cout<<"G"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_GREEN_TYPE_ARB,ivalue); cout<0) { cout<<"B"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_BLUE_TYPE_ARB,ivalue); cout<0) { cout<<"L"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_LUMINANCE_TYPE_ARB,ivalue); cout<0) { cout<<"A"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_ALPHA_TYPE_ARB,ivalue); cout<0) { cout<<"I"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_INTENSITY_TYPE_ARB,ivalue); cout<0) { cout<<"D"; iv=ivalue[0]; if(float_texture_supported) { glGetTexLevelParameteriv(target,0,vtkgl::TEXTURE_DEPTH_TYPE_ARB,ivalue); cout<(vtkgl::MIRRORED_REPEAT)) && errorCode==GL_INVALID_ENUM && target==vtkgl::TEXTURE_RECTANGLE_ARB) { // expected error. see extension spec. } else { if(errorCode!=GL_NO_ERROR) { cout << "ERROR:" << OpenGLErrorMessage2(errorCode) << "after GL_TEXTURE_WRAP_S" <(vtkgl::MIRRORED_REPEAT)) && errorCode==GL_INVALID_ENUM && target==vtkgl::TEXTURE_RECTANGLE_ARB) { // expected error. see extension spec. } else { if(errorCode!=GL_NO_ERROR) { cout << "ERROR:" << OpenGLErrorMessage2(errorCode) << "after GL_TEXTURE_WRAP_T" <SetMultiSamples(8); } else { renwin->SetMultiSamples(0); } renwin->SetAlphaBitPlanes(alphaBitPlanes); renwin->SetSize(width,height); // vtkRenderer *renderer = vtkRenderer::New(); // renwin->AddRenderer(renderer); // vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); // renwin->SetInteractor(iren); vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New(); extensions->SetRenderWindow(renwin); renwin->Render(); cout<<"OpenGL 1.1 Implementation dependent values : "<LoadSupportedExtension("GL_VERSION_1_2")) { cout<LoadSupportedExtension("GL_ARB_imaging")) { cout<<"imaging subset is supported."<LoadSupportedExtension("GL_VERSION_1_3")) { cout<0) { GLint *ivalues=new GLint[count]; glGetIntegerv(vtkgl::COMPRESSED_TEXTURE_FORMATS,ivalues); cout<<"GL_COMPRESSED_TEXTURE_FORMATS (Enumerated compressed texture formats)="; int i=0; while(iLoadSupportedExtension("GL_VERSION_1_4")) { cout<ExtensionSupported("GL_VERSION_1_4") || extensions->ExtensionSupported("GL_ARB_depth_texture"); if(extensions->LoadSupportedExtension("GL_VERSION_1_5")) { cout<LoadSupportedExtension("GL_VERSION_2_0")) { cout<ExtensionSupported("GL_VERSION_2_1") || extensions->ExtensionSupported("GL_EXT_texture_sRGB"); float_texture_supported=extensions->LoadSupportedExtension("GL_ARB_texture_float")==1; integer_texture_supported=extensions->ExtensionSupported("GL_EXT_texture_integer")==1; ARB_texture_rectangle_supported=extensions->LoadSupportedExtension("GL_ARB_texture_rectangle")==1; if(ARB_texture_rectangle_supported) { cout<LoadSupportedExtension("GL_EXT_framebuffer_object")) { cout<Delete(); renwin->Delete(); } const int windowSize[2]={512,511}; int main(int vtkNotUsed(argc), char *vtkNotUsed(argv)[]) { cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl; int multisample=0; while(multisample<2) { int alpha=0; while(alpha<2) { int index=0; while(index<2) { TestVisual(multisample,alpha,windowSize[index],windowSize[index]); ++index; } ++alpha; } ++multisample; } vtkRenderWindow *renwin = vtkRenderWindow::New(); renwin->SetAlphaBitPlanes(1); renwin->SetSize(250, 250); vtkRenderer *renderer = vtkRenderer::New(); renwin->AddRenderer(renderer); // Force a Render here so that we can call glGetString reliably: // renwin->Render(); if(vtkgl::TexImage3D!=0) { QueryTexture3D(); } QueryTexture2D(); QueryTexture1D(); if(ARB_texture_rectangle_supported) { QueryTexture2DRectangle(); } // Check if non-power-of-two texture is supported based on glError not // on the OpenGL version returned by the driver or on the list of // extensions returned by the driver. // clean glError glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,64,64,0, GL_RGBA, GL_FLOAT, NULL ); GLenum errorCode=glGetError(); if(errorCode!=GL_NO_ERROR) { cout << "Loading a power-of-two texture failed with the following error:" << OpenGLErrorMessage2(errorCode) <Delete(); renwin->Delete(); return 0; // 0==passed, always pass. }