static bool getTexImage(bool doPBO, GLenum target, GLubyte data[][IMAGE_SIZE], GLenum internalformat, int tolerance) { int i; int num_layers=1, num_faces=1, layer_size; GLubyte data2[18][IMAGE_SIZE]; GLubyte *dataGet; GLuint tex, packPBO; bool pass = true; glGenTextures(1, &tex); glBindTexture(target, tex); switch (target) { case GL_TEXTURE_1D: glTexImage1D(GL_TEXTURE_1D, 0, internalformat, IMAGE_WIDTH, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); layer_size = IMAGE_WIDTH * 4; break; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE: glTexImage2D(target, 0, internalformat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); layer_size = IMAGE_SIZE; break; case GL_TEXTURE_3D: num_layers = 16; glTexImage3D(GL_TEXTURE_3D, 0, internalformat, IMAGE_WIDTH, IMAGE_HEIGHT, num_layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); layer_size = IMAGE_SIZE; break; case GL_TEXTURE_CUBE_MAP: num_faces = 6; for (i = 0; i < num_faces; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalformat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[i]); } target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; layer_size = IMAGE_SIZE; break; case GL_TEXTURE_1D_ARRAY: num_layers = 7; glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, internalformat, IMAGE_WIDTH, num_layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // test as a single layer 2D image layer_size = IMAGE_WIDTH * 4 * num_layers; num_layers = 1; break; case GL_TEXTURE_2D_ARRAY: num_layers = 7; glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, IMAGE_WIDTH, IMAGE_HEIGHT, num_layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); layer_size = IMAGE_SIZE; break; case GL_TEXTURE_CUBE_MAP_ARRAY: num_layers = 6 * 3; glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalformat, IMAGE_WIDTH, IMAGE_HEIGHT, num_layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); layer_size = IMAGE_SIZE; break; default: puts("Invalid texture target."); return false; } /* Setup the PBO or data array to read into from glGetTexImage */ if (doPBO) { glGenBuffers(1, &packPBO); glBindBuffer(GL_PIXEL_PACK_BUFFER, packPBO); glBufferData(GL_PIXEL_PACK_BUFFER, layer_size * MAX2(num_faces,num_layers), NULL, GL_STREAM_READ); } else { glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); memset(data2, 123, sizeof(data2)); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; assert(num_layers * num_faces * layer_size <= sizeof(data2)); for (i = 0; i < num_faces; i++) { if (doPBO) { glGetTexImage(target + i, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) (long) (i * layer_size)); } else { glGetTexImage(target + i, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2[i]); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; } if (doPBO) dataGet = (GLubyte *) glMapBufferRange( GL_PIXEL_PACK_BUFFER, 0, layer_size * MAX2(num_faces,num_layers), GL_MAP_READ_BIT); else dataGet = data2[0]; for (i = 0; i < MAX2(num_faces,num_layers); i++) { pass = compare_layer(i, layer_size, tolerance, dataGet, data[i]) && pass; dataGet += layer_size; } if (doPBO) { glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glDeleteBuffers(1, &packPBO); } glDeleteTextures(1, &tex); return pass; }
void FOpenGLES31::ProcessExtensions( const FString& ExtensionsString ) { // Version setup first, need to check string for 3 or higher, then can use integer queries if (SupportsAdvancedFeatures()) { glGetIntegerv(GL_MAJOR_VERSION, &MajorVersion); glGetIntegerv(GL_MINOR_VERSION, &MinorVersion); bES2Fallback = false; UE_LOG(LogRHI, Log, TEXT("bES2Fallback = false")); } else { MajorVersion = 2; MinorVersion = 0; bES2Fallback = true; UE_LOG(LogRHI, Log, TEXT("bES2Fallback = true")); } bSupportsSeparateAlphaBlend = ExtensionsString.Contains(TEXT("GL_EXT_draw_buffers_indexed")); static auto CVarAllowHighQualityLightMaps = IConsoleManager::Get().FindConsoleVariable(TEXT("r.HighQualityLightMaps")); if (!bES2Fallback) { // only supported if we are at a minimum bar bSupportsTessellation = ExtensionsString.Contains(TEXT("GL_EXT_tessellation_shader")); bSupportsTextureView = ExtensionsString.Contains(TEXT("GL_EXT_texture_view")); CVarAllowHighQualityLightMaps->Set(1); } else { CVarAllowHighQualityLightMaps->Set(0); } ProcessQueryGLInt(); FOpenGLBase::ProcessExtensions(ExtensionsString); bSupportsMapBuffer = ExtensionsString.Contains(TEXT("GL_OES_mapbuffer")); bSupportsDepthTexture = ExtensionsString.Contains(TEXT("GL_OES_depth_texture")); bSupportsOcclusionQueries = ExtensionsString.Contains(TEXT("GL_ARB_occlusion_query2")) || ExtensionsString.Contains(TEXT("GL_EXT_occlusion_query_boolean")); bSupportsRGBA8 = ExtensionsString.Contains(TEXT("GL_OES_rgb8_rgba8")); bSupportsBGRA8888 = ExtensionsString.Contains(TEXT("GL_APPLE_texture_format_BGRA8888")) || ExtensionsString.Contains(TEXT("GL_IMG_texture_format_BGRA8888")) || ExtensionsString.Contains(TEXT("GL_EXT_texture_format_BGRA8888")); bSupportsVertexHalfFloat = ExtensionsString.Contains(TEXT("GL_OES_vertex_half_float")); bSupportsTextureFloat = ExtensionsString.Contains(TEXT("GL_OES_texture_float")); bSupportsTextureHalfFloat = ExtensionsString.Contains(TEXT("GL_OES_texture_half_float")); bSupportsSGRB = ExtensionsString.Contains(TEXT("GL_EXT_sRGB")); bSupportsColorBufferHalfFloat = ExtensionsString.Contains(TEXT("GL_EXT_color_buffer_half_float")); bSupportsShaderFramebufferFetch = ExtensionsString.Contains(TEXT("GL_EXT_shader_framebuffer_fetch")) || ExtensionsString.Contains(TEXT("GL_NV_shader_framebuffer_fetch")); // @todo es3: SRGB support does not work with our texture format setup (ES2 docs indicate that internalFormat and format must match, but they don't at all with sRGB enabled) // One possible solution us to use GLFormat.InternalFormat[bSRGB] instead of GLFormat.Format bSupportsSGRB = false;//ExtensionsString.Contains(TEXT("GL_EXT_sRGB")); bSupportsDXT = ExtensionsString.Contains(TEXT("GL_NV_texture_compression_s3tc")) || ExtensionsString.Contains(TEXT("GL_EXT_texture_compression_s3tc")); bSupportsPVRTC = ExtensionsString.Contains(TEXT("GL_IMG_texture_compression_pvrtc")) ; bSupportsATITC = ExtensionsString.Contains(TEXT("GL_ATI_texture_compression_atitc")) || ExtensionsString.Contains(TEXT("GL_AMD_compressed_ATC_texture")); bSupportsETC1 = ExtensionsString.Contains(TEXT("GL_OES_compressed_ETC1_RGB8_texture")); bSupportsVertexArrayObjects = ExtensionsString.Contains(TEXT("GL_OES_vertex_array_object")) ; bSupportsDiscardFrameBuffer = ExtensionsString.Contains(TEXT("GL_EXT_discard_framebuffer")); bSupportsNVFrameBufferBlit = ExtensionsString.Contains(TEXT("GL_NV_framebuffer_blit")); bSupportsPackedDepthStencil = ExtensionsString.Contains(TEXT("GL_OES_packed_depth_stencil")); bSupportsShaderTextureLod = ExtensionsString.Contains(TEXT("GL_EXT_shader_texture_lod")); bSupportsTextureStorageEXT = ExtensionsString.Contains(TEXT("GL_EXT_texture_storage")); bSupportsCopyTextureLevels = bSupportsTextureStorageEXT && ExtensionsString.Contains(TEXT("GL_APPLE_copy_texture_levels")); bSupportsDisjointTimeQueries = ExtensionsString.Contains(TEXT("GL_EXT_disjoint_timer_query"));// || ExtensionsString.Contains(TEXT("GL_NV_timer_query")); bTimerQueryCanBeDisjoint = !ExtensionsString.Contains(TEXT("GL_NV_timer_query")); bSupportsNvTimerQuery = ExtensionsString.Contains(TEXT("GL_NV_timer_query")); // Report shader precision int Range[2]; glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_LOW_FLOAT, Range, &ShaderLowPrecision); glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, Range, &ShaderMediumPrecision); glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, Range, &ShaderHighPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader lowp precision: %d"), ShaderLowPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader mediump precision: %d"), ShaderMediumPrecision); UE_LOG(LogRHI, Log, TEXT("Fragment shader highp precision: %d"), ShaderHighPrecision); // Test whether the GPU can support volume-texture rendering. // There is no API to query this - you just have to test whether a 3D texture is framebuffer-complete. if (!bES2Fallback) { GLuint FrameBuffer; glGenFramebuffers(1, &FrameBuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FrameBuffer); GLuint VolumeTexture; glGenTextures(1, &VolumeTexture); glBindTexture(GL_TEXTURE_3D, VolumeTexture); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 256, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTextureEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, VolumeTexture, 0); bSupportsVolumeTextureRendering = (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); glDeleteTextures(1, &VolumeTexture); glDeleteFramebuffers(1, &FrameBuffer); } bSupportsCopyImage = ExtensionsString.Contains(TEXT("GL_EXT_copy_image")); }
void MyView:: windowViewWillStart(std::shared_ptr<tygra::Window> window) { assert(scene_ != nullptr); glEnable(GL_TEXTURE_2D); //shadow maps glGenTextures(1, &shadowMap_tex_); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMap_tex_); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT16, 1024, 1024, 5, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); //the 256 is number of layers, change this to number of shadow casting lights glGenFramebuffers(1, &shadowMap_fbo_); glBindFramebuffer(GL_FRAMEBUFFER, shadowMap_fbo_); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMap_tex_, 0); glDrawBuffer(GL_NONE); // No color buffer is drawn to. check_fbo(); shadowMap_program_ = glCreateProgram(); GLuint fs = getFragmentShader("shadowMap_fs.glsl"); GLuint vs = getVertexShader("shadowMap_vs.glsl"); glAttachShader(shadowMap_program_, vs); glDeleteShader(vs); glAttachShader(shadowMap_program_, fs); glDeleteShader(fs); glLinkProgram(shadowMap_program_); //test program GLint link_status = 0; glGetProgramiv(shadowMap_program_, GL_LINK_STATUS, &link_status); if (link_status != GL_TRUE) { const int string_length = 1024; GLchar log[string_length] = ""; glGetProgramInfoLog(shadowMap_program_, string_length, NULL, log); std::cerr << log << std::endl; } //ssma textures glGenTextures(1, &albedo_tex); glBindTexture(GL_TEXTURE_2D, albedo_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0); glGenTextures(1, &edge_tex); glBindTexture(GL_TEXTURE_2D, edge_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0); glGenTextures(1, &blend_tex); glBindTexture(GL_TEXTURE_2D, blend_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0); unsigned char* buffer = 0; FILE* f = 0; buffer = new unsigned char[1024 * 1024]; f = fopen((app_path + "smaa_area.raw").c_str(), "rb"); //rb stands for "read binary file" if (!f) { std::cerr << "Couldn't open smaa_area.raw.\n"; exit(1); } fread(buffer, AREATEX_WIDTH * AREATEX_HEIGHT * 2, 1, f); fclose(f); f = 0; glGenTextures(1, &area_tex); glBindTexture(GL_TEXTURE_2D, area_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, (GLsizei)AREATEX_WIDTH, (GLsizei)AREATEX_HEIGHT, 0, GL_RG, GL_UNSIGNED_BYTE, buffer); f = fopen((app_path + "smaa_search.raw").c_str(), "rb"); if (!f) { std::cerr << "Couldn't open smaa_search.raw.\n"; exit(1); } fread(buffer, SEARCHTEX_WIDTH * SEARCHTEX_HEIGHT, 1, f); fclose(f); f = 0; glGenTextures(1, &search_tex); glBindTexture(GL_TEXTURE_2D, search_tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, (GLsizei)SEARCHTEX_WIDTH, (GLsizei)SEARCHTEX_HEIGHT, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); delete[] buffer; get_opengl_error(); /* * Initialize FBOs */ GLenum modes[] = { GL_COLOR_ATTACHMENT0 }; glGenFramebuffers(1, &albedo_fbo); glBindFramebuffer(GL_FRAMEBUFFER, albedo_fbo); glDrawBuffers(1, modes); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, albedo_tex, 0); check_fbo(); glGenFramebuffers(1, &edge_fbo); glBindFramebuffer(GL_FRAMEBUFFER, edge_fbo); glDrawBuffers(1, modes); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, edge_tex, 0); check_fbo(); glGenFramebuffers(1, &blend_fbo); glBindFramebuffer(GL_FRAMEBUFFER, blend_fbo); glDrawBuffers(1, modes); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blend_tex, 0); check_fbo(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); get_opengl_error(); /* * Set up shaders */ /* * EDGE SHADER */ create_shader(&edge_vs, &edge_ps, &edge_shader); //SET UNIFORMS glUseProgram(edge_shader); glUniform1i(glGetUniformLocation(edge_shader, "albedo_tex"), 0); glUseProgram(0); //VALIDATE validate_program(edge_shader); get_opengl_error(); /* * BLEND SHADER */ create_shader(&blend_vs, &blend_ps, &blend_shader); //SET UNIFORMS glUseProgram(blend_shader); glUniform1i(glGetUniformLocation(blend_shader, "edge_tex"), 0); glUniform1i(glGetUniformLocation(blend_shader, "area_tex"), 1); glUniform1i(glGetUniformLocation(blend_shader, "search_tex"), 2); glUseProgram(0); //VALIDATE validate_program(blend_shader); get_opengl_error(); /* * NEIGHBORHOOD SHADER */ create_shader(&neighborhood_vs, &neighborhood_ps, &neighborhood_shader); //SET UNIFORMS glUseProgram(neighborhood_shader); glUniform1i(glGetUniformLocation(neighborhood_shader, "albedo_tex"), 0); glUniform1i(glGetUniformLocation(neighborhood_shader, "blend_tex"), 1); glUseProgram(0); //VALIDATE validate_program(neighborhood_shader); get_opengl_error(); //anything that is done once on load goes here materialCount_ = scene_->getAllMaterials().size(); spotLightCount_ = scene_->getAllSpotLights().size(); pointLightCount_ = scene_->getAllPointLights().size(); directionalLightCount_ = scene_->getAllDirectionalLights().size(); loadShaders(); loadMeshes(); loadUniformBuffers(); glEnable(GL_CULL_FACE); glClearColor(0.f, 0.f, 0.25f, 0.f); //GBUFER TEXTURES glGenTextures(1, &gbuffer_position_tex_); glGenTextures(1, &gbuffer_normal_tex_); glGenTextures(1, &gbuffer_matColour_tex_); glGenFramebuffers(1, &lbuffer_fbo_); glGenRenderbuffers(1, &lbuffer_colour_rbo_); glGenFramebuffers(1, &gbuffer_fbo_); glGenRenderbuffers(1, &gbuffer_depth_rbo_); //only need to set this once glUseProgram(shaderPrograms_[AMBIENT_LIGHT]); GLuint ambient = glGetUniformLocation(shaderPrograms_[AMBIENT_LIGHT], "ambientLight"); glUniform3fv(ambient, 1, glm::value_ptr(scene_->getAmbientLightIntensity())); }
void GL::Texture::setup(const void* data, GLenum type, int samples) { assert(_dimensions >= 1 && _dimensions <= 3); GLenum targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D}; GLenum wrap_enums[] = {GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_R}; _target = targets[_dimensions-1]; if (samples > 0) { // Multisample textures don't support mipmapping. assert(_min_filter != GL_NEAREST_MIPMAP_NEAREST); assert(_min_filter != GL_LINEAR_MIPMAP_NEAREST); assert(_min_filter != GL_NEAREST_MIPMAP_LINEAR); assert(_min_filter != GL_LINEAR_MIPMAP_LINEAR); assert(_dimensions == 2); if (_dimensions == 2) { _target = GL_TEXTURE_2D_MULTISAMPLE; } } bind(); if (samples == 0) { if (FLEXT_EXT_texture_filter_anisotropic) { glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_config.max_anisotropy()); } glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, _mag_filter); glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, _min_filter); for (int i = 0; i < _dimensions; ++i) { glTexParameteri(_target, wrap_enums[i], _wrap_method); } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); switch (_dimensions) { case 1: glTexImage1D(GL_TEXTURE_1D, // target 0, // level _internal_format, // internalFormat _width, // size 0, // border _format, // format type, // type data); // pixels break; case 2: if (samples < 1) { glTexImage2D(GL_TEXTURE_2D, // target 0, // level _internal_format, // internalFormat _width,_height, // size 0, // border _format, // format type, // type data); // pixels } else { glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, // target samples, // samples _internal_format, // internalFormat _width,_height, // size GL_FALSE); // fixedsamplelocations } break; case 3: glTexImage3D(GL_TEXTURE_3D, // target 0, // level _internal_format, // internalFormat _width,_height,_depth, // size 0, // border _format, // format type, // type data); // pixels break; default: assert(0); // To keep the compiler quiet.. } generate_mipmaps(); unbind(); }
Scene::Scene(std::istream& ins) :projection(NULL), view(NULL), numLights(0), shadowMapSize(windWidth*2), texUnitBase(0) { srand(0);//TODO SEED WITH TIME parseScene(ins); //create shadow map texture glGenTextures(1, &shadowMapTexture); glGenFramebuffersEXT(1, &FBOID); glGenFramebuffersEXT(1, &recordFBOID); glGenTextures(2, recordTexBase); glGenFramebuffersEXT(1, &directFBOID); glGenTextures(2, directTex); glBindTexture(GL_TEXTURE_2D, directTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windWidth, windHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, directTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windWidth, windHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, directFBOID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, directTex[0], 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, directTex[1], 0); glGenFramebuffersEXT(1, &splatBufFBOID); glGenTextures(1, &splatTex); glActiveTexture(texUnitEnums[0]); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapTexture); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); std::cout << "numlights: " << numLights << std::endl; glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, numLights, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOID); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); //set up splat buffer glBindTexture(GL_TEXTURE_2D, splatTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, windWidth, windHeight, 0, GL_RGBA, GL_FLOAT, NULL); //it doesn't need a depth attachment //set up "color" attachment, alpha channel with be depth glBindTexture(GL_TEXTURE_2D, recordTexBase[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, recordWidth, recordHeight, 0, GL_RGBA, GL_FLOAT, NULL); //set up depth attachment glBindTexture(GL_TEXTURE_2D, recordTexBase[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, recordWidth, recordHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);//window buffer loadShadowShader(); loadSplatShader(); loadFinalShader(); readCoordNormals(); // std::cout << "constructor completed" << std::endl; IMap = new float[4*recordWidth*recordHeight]; splatBuffer = new float[4*windWidth*windHeight]; timer.start(); std::cout << "before warmup" <<timer.split() << std::endl; warmupCache(1000);//generate starting records std::cout << "after warmup" << timer.split() << std::endl; }
void glInit() { initFont(); // create openGL functions for (int i=0; i<NUM_GL_NAMES; i++) glFP[i] = (GenFP)wglGetProcAddress(glnames[i]); // Create and link shader and stuff: // I will have to separate these to be able to use more than one shader... // TODO: I should make some sort of compiling and linking loop... // create noise Texture #ifdef FLOAT_TEXTURE for (int i = 0; i < NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * 4; i++) { noiseData[i] = frand() - 0.5f; } #else for (int i = 0; i < NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * 4; i++) { noiseData[i] = (unsigned char)rand(); } #endif // init objects: GLuint vMainObject = glCreateShader(GL_VERTEX_SHADER); GLuint fMainBackground = glCreateShader(GL_FRAGMENT_SHADER); GLuint fOffscreenCopy = glCreateShader(GL_FRAGMENT_SHADER); shaderPrograms[0] = glCreateProgram(); shaderPrograms[1] = glCreateProgram(); // compile sources: glShaderSource(vMainObject, 1, &vertexMainObject, NULL); glCompileShader(vMainObject); glShaderSource(fMainBackground, 1, &fragmentMainBackground, NULL); glCompileShader(fMainBackground); glShaderSource(fOffscreenCopy, 1, &fragmentOffscreenCopy, NULL); glCompileShader(fOffscreenCopy); // Check programs int tmp, tmp2; glGetShaderiv(vMainObject, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(vMainObject, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "vMainObject shader error", MB_OK); return; } glGetShaderiv(fMainBackground, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(fMainBackground, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "fMainBackground shader error", MB_OK); return; } glGetShaderiv(fOffscreenCopy, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(fOffscreenCopy, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "fOffscreeCopy shader error", MB_OK); return; } // link shaders: glAttachShader(shaderPrograms[0], vMainObject); glAttachShader(shaderPrograms[0], fMainBackground); glLinkProgram(shaderPrograms[0]); glAttachShader(shaderPrograms[1], vMainObject); glAttachShader(shaderPrograms[1], fOffscreenCopy); glLinkProgram(shaderPrograms[1]); // Create a rendertarget texture glGenTextures(1, &offscreenTexture); glBindTexture(GL_TEXTURE_2D, offscreenTexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); #if 1 // RLE uncompress int pos = 0; for (int k = 0; k < numValues; k++) { for (int i = 0; i < fontLength[k]; i++) { fontCompressed[0][0][pos+fontLength[k]-i-1] = fontValues[k]; } pos += fontLength[k]; } // uncompress font for (int color = 0; color < 4; color++) { for (int y = 0; y < fontHeight; y++) { for (int x = 0; x < fontWidth; x++) { font[y][x][color] = fontCompressed[color][y][x]; } } } // Set texture. glEnable(GL_TEXTURE_3D); // automatic? glGenTextures(1, &noiseTexture); glBindTexture(GL_TEXTURE_3D, noiseTexture); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); #ifdef FLOAT_TEXTURE glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, 0, GL_RGBA, GL_FLOAT, noiseData); #else glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, noiseData); #endif // Load font texture glGenTextures(1, &fontTexture); glBindTexture(GL_TEXTURE_2D, fontTexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // TODO: Mip Mapping!!!! glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering glEnable(GL_TEXTURE_2D); // Enable Texture Mapping gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, fontWidth, fontHeight, GL_BGRA, GL_UNSIGNED_BYTE, font); glDisable(GL_TEXTURE_2D); // Enable Texture Mapping #endif }
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels) { GPUTexture *tex; GLenum type, format, internalformat; void *pixels = NULL; float vfBorderColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; if (!GLEW_VERSION_1_2) return NULL; tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); tex->w = w; tex->h = h; tex->depth = depth; tex->number = -1; tex->refcount = 1; tex->target = GL_TEXTURE_3D; glGenTextures(1, &tex->bindcode); if (!tex->bindcode) { fprintf(stderr, "GPUTexture: texture create failed: %d\n", (int)glGetError()); GPU_texture_free(tex); return NULL; } if (!GPU_non_power_of_two_support()) { tex->w = power_of_2_max_i(tex->w); tex->h = power_of_2_max_i(tex->h); tex->depth = power_of_2_max_i(tex->depth); } tex->number = 0; glBindTexture(tex->target, tex->bindcode); GPU_print_error("3D glBindTexture"); type = GL_FLOAT; if (channels == 4) { format = GL_RGBA; internalformat = GL_RGBA; } else { format = GL_RED; internalformat = GL_INTENSITY; } //if (fpixels) // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL); GPU_print_error("3D glTexImage3D"); if (fpixels) { if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) { /* clear first to avoid unitialized pixels */ float *zero= MEM_callocN(sizeof(float)*tex->w*tex->h*tex->depth, "zero"); glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->depth, format, type, zero); MEM_freeN(zero); } glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels); GPU_print_error("3D glTexSubImage3D"); } glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor); GPU_print_error("3D GL_TEXTURE_BORDER_COLOR"); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GPU_print_error("3D GL_LINEAR"); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GPU_print_error("3D GL_CLAMP_TO_BORDER"); if (pixels) MEM_freeN(pixels); GPU_texture_unbind(tex); return tex; }
double Object::InitializeGPUArrays(bool _log) { if (m_bInitializedGPU) { Logw("Object::SetupGPUArrays(): ERROR: GPU arrays already initialized\n"); return (1.0); } __int64 t0 = StartCounter(); // Create and bind vertex array glGenVertexArrays(1, &m_vaoObject); glError("Object::SetupGPUArrays()", "glGenVertexArrays() m_vaoObject"); glBindVertexArray(m_vaoObject); glError("Object::SetupGPUArrays()", "glBindVertexArray() m_vaoObject"); // Create and bind vertex and index buffers (init with NULL) // vertex buffer glGenBuffers(1, &m_vboObjectVertices); glError("Object::SetupGPUArrays()", "glGenBuffers() m_vboObjectVertices"); glBindBuffer(GL_ARRAY_BUFFER, m_vboObjectVertices); glError("Object::SetupGPUArrays()", "glBindBuffer() m_vboObjectVertices"); glBufferData(GL_ARRAY_BUFFER, sizeof(GLvertex) * m_nVertices, NULL, GL_STATIC_DRAW); glError("Object::SetupGPUArrays()", "glBufferData() GL_ARRAY_BUFFER"); // index buffer glGenBuffers(1, &m_iboObject); glError("Object::SetupGPUArrays()", "glGenBuffers() m_iboObject"); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_iboObject); glError("Object::SetupGPUArrays()", "glBindBuffer() m_iboObject"); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_nIndices, NULL, GL_STATIC_DRAW); glError("Object::SetupGPUArrays()", "glBufferData() GL_ELEMENT_ARRAY_BUFFER"); // set vertex attributes according to shader flags // positions (default) if (m_vertexFlags & VERTEX_POSITION) { GLint aPos = m_pShaderProgram->GetAttribute("attributePosition"); glEnableVertexAttribArray(aPos); glVertexAttribPointer(aPos, 3, GL_FLOAT, GL_FALSE, sizeof(GLvertex), (GLvoid *)0); glError("Object::InitializeGPUArrays()", "glVertexAttribPointer(): VERTEX_POSITION"); } // normals if (m_vertexFlags & VERTEX_NORMAL) { GLint aNorm = m_pShaderProgram->GetAttribute("attributeNormal"); glEnableVertexAttribArray(aNorm); glVertexAttribPointer(aNorm, 3, GL_FLOAT, GL_FALSE, sizeof(GLvertex), (GLvoid *)offsetof(GLvertex, normal)); glError("Object::InitializeGPUArrays()", "glVertexAttribPointer(): VERTEX_TEXCOORD"); } // texture coordinates if (m_vertexFlags & VERTEX_TEXCOORD) { GLint aTexCoord = m_pShaderProgram->GetAttribute("attributeTexCoord"); glEnableVertexAttribArray(aTexCoord); glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(GLvertex), (GLvoid *)offsetof(GLvertex, texCoord)); glError("Object::InitializeGPUArrays()", "glVertexAttribPointer(): VERTEX_TEXCOORD"); // is there a texture associated with this Object? if (m_texture.m_pTexture) { // setup basic texture parameters GLuint id; glGenTextures(1, &id); glError("Object::InitializeGPUArrays()", "glGenTextures() id"); glBindTexture(m_texture.m_eTextureType, id); glError("Object::InitializeGPUArrays()", "glBindTexture() id"); // update id in the texture (now set from Object instead of from Texture) m_texture.m_pTexture->SetTextureID(id); // trivial pixel format search GLtextureFormat format = m_texture.m_pTexture->TextureFormat(); //Logw("\nFormat = internal: %d (%s)\tserver: %d (%s)\n\n", format.texInternalFormat, (format.texInternalFormat == GL_RGB ? "GL_RGB" : "dunno"), format.texServerFormat, (format.texServerFormat == GL_RGB ? "GL_RGB" : "dunno")); // create an empty texture server-side of correct dimensions switch (m_texture.m_eTextureType) { case GL_TEXTURE_1D: glTexImage1D(m_texture.m_eTextureType, 0, format.texInternalFormat, m_texture.m_pTexture->TexWidth(), 0, format.texServerFormat, GL_UNSIGNED_BYTE, 0); glError("Object::SetupGPUArrays()", "glTexImage1D()"); break; case GL_TEXTURE_2D: glTexImage2D(m_texture.m_eTextureType, 0, format.texInternalFormat, m_texture.m_pTexture->TexWidth(), m_texture.m_pTexture->TexHeight(), 0, format.texServerFormat, GL_UNSIGNED_BYTE, 0); glError("Object::SetupGPUArrays()", "glTexImage2D()"); break; case GL_TEXTURE_3D: glTexImage3D(m_texture.m_eTextureType, 0, format.texInternalFormat, m_texture.m_pTexture->TexWidth(), m_texture.m_pTexture->TexHeight(), m_texture.m_pTexture->TexDepth(), 0, format.texServerFormat, GL_UNSIGNED_BYTE, 0); glError("Object::SetupGPUArrays()", "glTexImage3D()"); break; } // Set texture parameters GLtextureParameters param = m_texture.m_pTexture->TextureParameters(); glGenerateMipmap(m_texture.m_eTextureType); glError("Object::SetupGPUArrays()", "glGenerateMipmap()"); glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_WRAP_S, param.texParameterWrapS); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterWrapS"); if (m_texture.m_eTextureType == GL_TEXTURE_2D) { glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_WRAP_T, param.texParameterWrapT); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterWrapS"); } if (m_texture.m_eTextureType == GL_TEXTURE_3D) { glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_WRAP_T, param.texParameterWrapT); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterWrapT"); glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_WRAP_R, param.texParameterWrapR); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterWrapR"); } glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_MIN_FILTER, param.texParameterMinFilter); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterMinFilter"); glTexParameteri(m_texture.m_eTextureType, GL_TEXTURE_MAG_FILTER, param.texParameterMagFilter); glError("Object::SetupGPUArrays()", "glTexParameteri() param.texParameterMagFilter"); // unbind texture glBindTexture(m_texture.m_eTextureType, 0); } } // set flag m_bInitializedGPU = true; // update render function m_pRenderFunc = &Object::RenderVertices; if (_log) Logw("Object::SetupGPUArrays(): Frame %llu: GPU arrays and vertex attributes setup for object '%s' in %.4f ms\n", g_lFrame, m_objectName.c_str(), GetElapsed(t0)); // return execution time return (GetElapsed(t0)); } // end Object::SetupGPUArrays()
void DarwinGlTexture::iUpdateTextureSurface( const GlTextureUpdateType& utype ) { if ( utype == GlTextureUpdateType::PixelBuffer ) { SoftwarePixelBuffer softpixu = getPixelBuffer(); if ( softpixu.isInvalid() ) { return; } SoftwarePixelBufferHolder softpix = softpixu.lock(); if ( iGlTexture ) { bind(); // Here we assume the Texture has already been created and the Surface is correct. // We just call glTexSubImage depending on the TextureType. GLenum target = GlTextureTargetFromTextureType(getType()); GLint level = 0; GLint xoffset = 0; // Unsupported GLint yoffset = 0; // Unsupported GLint zoffset = 0; // Unsupported GLsizei width = getSurface().width; GLsizei height = getSurface().height; GLsizei depth = 0; // Unsupported GLenum format = GlTextureComponents(softpix->getPixelFormat()); GLenum type = GlTextureFormat(softpix->getPixelFormat()); const GLvoid* pixels = (const GLvoid*) softpix->getData(); TextureType textype = getType(); if ( textype == TextureType::OneDimension ) { glTexSubImage1D(target, level, xoffset, width, format, type, pixels); } if ( textype == TextureType::TwoDimension ) { glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } if ( textype == TextureType::ThreeDimension ) { glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } if ( textype == TextureType::CubeMap ) { // Here we have 6 different textures. But we will not do it for now. // UNSUPPORTED } } else { // If 'iGlTexture' is invalid , we must create the Texture object. // We must also check for TextureType , and Surface . if ( getType() == TextureType::Null ) return; Surface surf = getSurface(); if ( surf.width <= 0 || surf.height <= 0 ) return; glGenTextures(1, &iGlTexture); bind(); GLenum target = GlTextureTargetFromTextureType(getType()); GLint level = 0; GLsizei width = getSurface().width; GLsizei height = getSurface().height; GLsizei depth = 0; // Unsupported GLenum format = GlTextureComponents(softpix->getPixelFormat()); GLenum type = GlTextureFormat(softpix->getPixelFormat()); const GLvoid* pixels = (const GLvoid*) softpix->getData(); TextureType textype = getType(); if ( textype == TextureType::OneDimension ) { glTexImage1D(target, level, GL_RGBA, width, 0, format, type, pixels); } if ( textype == TextureType::TwoDimension ) { glTexImage2D(target, level, GL_RGBA, width, height, 0, format, type, pixels); } if ( textype == TextureType::ThreeDimension ) { glTexImage3D(target, level, GL_RGBA, width, height, depth, 0, format, type, pixels); } if ( textype == TextureType::CubeMap ) { // Here we have 6 different textures. But we will not do it for now. // UNSUPPORTED } } } if ( utype == GlTextureUpdateType::Surface ) { // If we are updating the Surface , but the GlTexture is valid , we should destroy it and // make a new one. Normally , you should not use Texture::setSurface if data is already set. if ( iGlTexture ) { // Destroy the Texture , and launch the Update with SoftwarePixelBuffer . glDeleteTextures(1, &iGlTexture); iGlTexture = 0; } SoftwarePixelBuffer pixbufu = getPixelBuffer(); if ( pixbufu.isInvalid() ) { // Create a new empty pixel buffer . SoftwarePixelBufferHolder pixbuf = SoftwarePixelBufferHolder ( new SoftwarePixelBufferPrivate(getName()+"/0softbuf") ); pixbuf->setPixelFormat(HardwarePixelFormat::RGBAFloat); pixbuf->setData(nullptr, getSurface().width * getSurface().height * sizeof(float)); setPixelBuffer(pixbuf); } else { iUpdateTextureSurface(GlTextureUpdateType::PixelBuffer); } } if ( utype == GlTextureUpdateType::Type ) { // If TextureType has changed , we should reload the Texture. if ( iGlTexture ) { glDeleteTextures(1, &iGlTexture); iGlTexture = 0; } iUpdateTextureSurface(GlTextureUpdateType::PixelBuffer); } }
void intro_init( void ) { // create openGL functions for (int i=0; i<NUM_GL_NAMES; i++) glFP[i] = (GenFP)wglGetProcAddress(glnames[i]); // create noise Texture #ifdef FLOAT_TEXTURE for (int i = 0; i < NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * 4; i++) { noiseData[i] = frand() - 0.5f; } #else for (int i = 0; i < NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * NOISE_TEXTURE_SIZE * 4; i++) { noiseData[i] = (unsigned char)rand(); } #endif // Create and link shader and stuff: // I will have to separate these to be able to use more than one shader... // TODO: I should make some sort of compiling and linking loop... // init objects: GLuint vMainObject = glCreateShader(GL_VERTEX_SHADER); GLuint fMainBackground = glCreateShader(GL_FRAGMENT_SHADER); GLuint fOffscreenCopy = glCreateShader(GL_FRAGMENT_SHADER); shaderPrograms[0] = glCreateProgram(); shaderPrograms[1] = glCreateProgram(); // compile sources: glShaderSource(vMainObject, 1, &vertexMainObject, NULL); glCompileShader(vMainObject); glShaderSource(fMainBackground, 1, &fragmentMainBackground, NULL); glCompileShader(fMainBackground); glShaderSource(fOffscreenCopy, 1, &fragmentOffscreenCopy, NULL); glCompileShader(fOffscreenCopy); #ifdef SHADER_DEBUG // Check programs int tmp, tmp2; glGetShaderiv(vMainObject, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(vMainObject, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "vMainObject shader error", MB_OK); return; } glGetShaderiv(fMainBackground, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(fMainBackground, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "fMainBackground shader error", MB_OK); return; } glGetShaderiv(fOffscreenCopy, GL_COMPILE_STATUS, &tmp); if (!tmp) { glGetShaderInfoLog(fOffscreenCopy, 4096, &tmp2, err); err[tmp2]=0; MessageBox(hWnd, err, "fOffscreeCopy shader error", MB_OK); return; } #endif // link shaders: glAttachShader(shaderPrograms[0], vMainObject); glAttachShader(shaderPrograms[0], fMainBackground); glLinkProgram(shaderPrograms[0]); glAttachShader(shaderPrograms[1], vMainObject); glAttachShader(shaderPrograms[1], fOffscreenCopy); glLinkProgram(shaderPrograms[1]); // Set texture. glEnable(GL_TEXTURE_3D); // automatic? glGenTextures(1, &noiseTexture); glBindTexture(GL_TEXTURE_3D, noiseTexture); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); #ifdef FLOAT_TEXTURE glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, 0, GL_RGBA, GL_FLOAT, noiseData); #else glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, NOISE_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, noiseData); #endif // Create a rendertarget texture glGenTextures(1, &offscreenTexture); glBindTexture(GL_TEXTURE_2D, offscreenTexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); //glBindTexture(GL_TEXTURE_2D, 0); }
bool upload_image_levels(const struct image_info img, unsigned num_levels, unsigned level, unsigned unit, const uint32_t *pixels) { const unsigned m = image_num_components(img.format); int i, l; if (get_texture(unit)) { glDeleteTextures(1, &textures[unit]); textures[unit] = 0; } if (get_buffer(unit)) { glDeleteBuffers(1, &buffers[unit]); buffers[unit] = 0; } glGenTextures(1, &textures[unit]); glBindTexture(img.target->target, textures[unit]); switch (img.target->target) { case GL_TEXTURE_1D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage1D(GL_TEXTURE_1D, l, img.format->format, size.x, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage2D(GL_TEXTURE_2D, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_3D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_3D, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_RECTANGLE: assert(num_levels == 1); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, img.format->format, img.size.x, img.size.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); break; case GL_TEXTURE_CUBE_MAP: for (l = 0; l < num_levels; ++l) { const unsigned offset = m * image_level_offset(img, l); const struct image_extent size = image_level_size(img, l); const unsigned face_sz = m * product(size) / 6; for (i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[offset + face_sz * i]); } break; case GL_TEXTURE_BUFFER: { /* * glTexImage*() isn't supposed to work with buffer * textures. We copy the unpacked pixels to a texture * with the desired internal format to let the GL pack * them for us. */ const struct image_extent grid = image_optimal_extent(img.size); GLuint packed_tex; assert(num_levels == 1); glGenBuffers(1, &buffers[unit]); glBindBuffer(GL_PIXEL_PACK_BUFFER, buffers[unit]); glBufferData(GL_PIXEL_PACK_BUFFER, img.size.x * image_pixel_size(img.format) / 8, NULL, GL_STATIC_DRAW); glGenTextures(1, &packed_tex); glBindTexture(GL_TEXTURE_2D, packed_tex); glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.x, grid.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); glGetTexImage(GL_TEXTURE_2D, 0, img.format->pixel_format, img.format->pixel_type, NULL); glDeleteTextures(1, &packed_tex); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glTexBuffer(GL_TEXTURE_BUFFER, image_compat_format(img.format), buffers[unit]); break; } case GL_TEXTURE_1D_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage2D(GL_TEXTURE_1D_ARRAY, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_2D_ARRAY, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_CUBE_MAP_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { /* * GL doesn't seem to provide any direct way to * initialize a multisample texture, so we use * imageStore() to render to it from the fragment * shader copying the contents of a larger * single-sample 2D texture. */ const struct grid_info grid = { get_image_stage(GL_FRAGMENT_SHADER)->bit, img.format, image_optimal_extent(img.size) }; GLuint prog = generate_program( grid, GL_FRAGMENT_SHADER, concat(image_hunk(image_info_for_grid(grid), "SRC_"), image_hunk(img, "DST_"), hunk("readonly SRC_IMAGE_UNIFORM_T src_img;\n" "writeonly DST_IMAGE_UNIFORM_T dst_img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " imageStore(dst_img, DST_IMAGE_ADDR(idx),\n" " imageLoad(src_img, SRC_IMAGE_ADDR(idx)));\n" " return x;\n" "}\n"), NULL)); bool ret = prog && generate_fb(grid, 1); GLuint tmp_tex; assert(num_levels == 1); glGenTextures(1, &tmp_tex); glBindTexture(GL_TEXTURE_2D, tmp_tex); if (img.target->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, img.size.x, img.format->format, img.size.y, img.size.z, img.size.w, GL_FALSE); } else { glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, img.size.x, img.format->format, img.size.y, img.size.z, GL_FALSE); } glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.size.x, grid.size.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); glBindImageTexture(unit, textures[unit], 0, GL_TRUE, 0, GL_WRITE_ONLY, img.format->format); glBindImageTexture(6, tmp_tex, 0, GL_TRUE, 0, GL_READ_ONLY, img.format->format); ret &= set_uniform_int(prog, "src_img", 6) && set_uniform_int(prog, "dst_img", unit) && draw_grid(grid, prog); glDeleteProgram(prog); glDeleteTextures(1, &tmp_tex); glBindFramebuffer(GL_FRAMEBUFFER, fb[0]); glViewportIndexedfv(0, vp[0]); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); if (!ret) return false; break; } default: abort(); } glBindImageTexture(unit, textures[unit], level, GL_TRUE, 0, GL_READ_WRITE, img.format->format); return piglit_check_gl_error(GL_NO_ERROR); }
static void test_non_proxy_texture_size(GLenum target, GLenum internalformat) { GLuint tex; int maxSide, k; GLfloat *pixels = NULL; enum piglit_result result = PIGLIT_PASS; glGenTextures(1, &tex); glBindTexture(target, tex); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Query the largest supported texture size */ glGetIntegerv(getMaxTarget(target), &maxSide); printf("%s, Internal Format = %s, Largest Texture Size = %d\n", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(internalformat), maxSide); /* Allocate and initialize texture data array */ pixels = initTexData(target, maxSide/2); if (pixels == NULL) { printf("Error allocating texture data array for target %s, size %d\n", piglit_get_gl_enum_name(target), maxSide); result = PIGLIT_SKIP; goto out; } switch (target) { case GL_TEXTURE_1D: glTexImage1D(target, 0, internalformat, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); STOP_ON_ERRORS; glTexSubImage1D(target, 0, 0, maxSide/2, GL_RGBA, GL_FLOAT, pixels); break; case GL_TEXTURE_2D: glTexImage2D(target, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); STOP_ON_ERRORS; glTexSubImage2D(target, 0, 0, 0, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); break; case GL_TEXTURE_RECTANGLE: glTexImage2D(target, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); STOP_ON_ERRORS; break; case GL_TEXTURE_3D: glTexImage3D(target, 0, internalformat, maxSide, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); STOP_ON_ERRORS; glTexSubImage3D(target, 0, 0, 0, 0, maxSide/2, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); break; case GL_TEXTURE_CUBE_MAP_ARB: for (k = 0; k < 6; k++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + k, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); STOP_ON_ERRORS; } for (k = 0; k < 6; k++) { glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + k, 0, 0, 0, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); STOP_ON_ERRORS; } break; } STOP_ON_ERRORS; out: glDeleteTextures(1, &tex); free(pixels); piglit_report_subtest_result(result, "%s-%s", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(internalformat)); }
static void test_proxy_texture_size(GLenum target, GLenum internalformat) { int maxSide; enum piglit_result result; GLenum err = GL_NO_ERROR; /* Query the largest supported texture size */ glGetIntegerv(getMaxTarget(target), &maxSide); /* Compute largest supported texture size using proxy textures */ while (isValidTexSize(target, internalformat, maxSide)) maxSide *= 2; /* First unsupported size */ while (!isValidTexSize(target, internalformat, maxSide)) maxSide /= 2; while (isValidTexSize(target, internalformat, maxSide)) maxSide += 1; /* Last supported texture size */ maxSide -= 1; printf("%s, Internal Format = %s, Largest Texture Size = %d\n", piglit_get_gl_enum_name(getProxyTarget(target)), piglit_get_gl_enum_name(internalformat), maxSide); switch (target) { case GL_TEXTURE_1D: glTexImage1D(GL_PROXY_TEXTURE_1D, 0, internalformat, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); break; case GL_TEXTURE_2D: glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); break; case GL_TEXTURE_RECTANGLE: glTexImage2D(target, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); break; case GL_TEXTURE_3D: glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, maxSide, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); break; case GL_TEXTURE_CUBE_MAP: glTexImage2D(GL_PROXY_TEXTURE_CUBE_MAP, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); break; } err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); result = PIGLIT_FAIL; } else { result = PIGLIT_PASS; } piglit_report_subtest_result(result, "%s-%s", piglit_get_gl_enum_name(getProxyTarget(target)), piglit_get_gl_enum_name(internalformat)); }
bool Framebuffer::init(bool gen) { //~ printf("init framebuffer with gen %u\n", gen); fflush(stdout); if (gen) { glGenFramebuffers(1, &id_); } if (params_.numMrts == 0) { printf("num mrts is zero, failed!\n"); fflush(stdout); return false; } if (params_.depth > GL_MAX_COLOR_ATTACHMENTS) { // same for mrt printf("num mrts is too many, failed\n"); fflush(stdout); return false; } bind(); // NSIGHT doesn't support this, seems to work without it anyways (since we aren't using empty framebuffers) //glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, params_.width); //glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, params_.height); if (params_.colorEnable) { if (gen) { color_ = new GLuint[params_.numMrts]; } if (params_.type == GL_TEXTURE_2D) { //~ printf("making non-msaa 2d framebuffer\n"); fflush(stdout); if (gen) { glGenTextures(params_.numMrts, &color_[0]); } for (unsigned int i = 0; i < params_.numMrts; i++) { //printf("making non msaa color target for id %u\n", color_[i]); fflush(stdout); glBindTexture(GL_TEXTURE_2D, color_[i]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, params_.filter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, params_.filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, params_.format, params_.width, params_.height, 0, GL_RGBA, GL_FLOAT, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, color_[i], 0); } } else if (params_.type == GL_TEXTURE_2D_MULTISAMPLE) { GLint maxSamples = 0; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); params_.numSamples = min(params_.numSamples, static_cast<GLuint>(maxSamples)); if (gen) { glGenTextures(params_.numMrts, &color_[0]); } for (int i = 0; i < params_.numMrts; i++) { //~ printf("making msaa color target for id %u\n", color_[i]); fflush(stdout); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color_[i]); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, params_.numSamples, params_.format , params_.width, params_.height, false); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D_MULTISAMPLE, color_[i], 0); } } else if (params_.type == GL_TEXTURE_3D) { //~ printf("making non-msaa 3d framebuffer\n"); fflush(stdout); if (gen) { glGenTextures(params_.numMrts, &color_[0]); } for (int i = 0; i < params_.numMrts; i++) { glBindTexture(GL_TEXTURE_3D, color_[i]); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // must be linear or nearest glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage3D(GL_TEXTURE_3D, 0, params_.format, params_.width, params_.height, params_.depth, 0, GL_RGBA, GL_FLOAT, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, color_[i], 0); } /* binding each layer to a color attachment (old way) for (int i = 0; i < params_.depth; i++) { glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, color_[0], 0, i); } */ } GLenum *bufs = new GLenum[params_.numMrts]; for (unsigned int i = 0; i < params_.numMrts; i++) { bufs[i] = GL_COLOR_ATTACHMENT0 + i; } glDrawBuffers(params_.numMrts, bufs); delete[] bufs; glBindTexture(params_.type, 0); } if(params_.depthEnable) { if (gen) { glGenTextures(1, &depth_); } if (params_.type == GL_TEXTURE_2D_MULTISAMPLE) { //~ printf("making msaa z target id for %u\n", depth_); fflush(stdout); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, depth_); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // this was throwing GL debug errors, so maybe take care of it in a sampler, or when we are doing shadow mapping? //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); //~ glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, params_.numSamples, params_.depthFormat, params_.width, params_.height, false); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depth_, 0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); } else if (params_.type == GL_TEXTURE_3D) { glBindTexture(GL_TEXTURE_3D, depth_); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexImage3D(GL_TEXTURE_3D, 0, params_.depthFormat, params_.width, params_.height, params_.depth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_, 0); glBindTexture(GL_TEXTURE_3D, 0); } else { //printf("making normal z target for id %u\n", depth_); fflush(stdout); glBindTexture(GL_TEXTURE_2D, depth_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); // should be default glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // comparison functions for shadow mapping glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexImage2D(GL_TEXTURE_2D, 0, params_.depthFormat, params_.width, params_.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_, 0); glBindTexture(GL_TEXTURE_2D, 0); } } bool check = checkStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, 0); return check; }
// Creation / loading methods void GL3PlusTexture::createInternalResourcesImpl(void) { // set HardwareBuffer::Usage for TU_RENDERTARGET if nothing else specified if((mUsage & TU_RENDERTARGET) && (mUsage & ~TU_RENDERTARGET) == 0) mUsage |= HardwareBuffer::HBU_DYNAMIC; // Adjust format if required. mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps. uint32 maxMips = getMaxMipmaps(); if (PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) mNumRequestedMipmaps = 0; mNumMipmaps = mNumRequestedMipmaps; if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; // Create a texture object and identify its GL type. OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID)); GLenum texTarget = getGL3PlusTextureTarget(); // Calculate size for all mip levels of the texture. uint32 width, height, depth; if ((mWidth * PixelUtil::getNumElemBytes(mFormat)) & 3) { // Standard alignment of 4 is not right for some formats. OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); } // Bind texture object to its type, making it the active texture object // for that type. mRenderSystem->_getStateCacheManager()->bindGLTexture( texTarget, mTextureID ); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, mNumMipmaps); // Set some misc default parameters, these can of course be changed later. mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set up texture swizzling. mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); if (PixelUtil::isLuminance(mFormat) && (mRenderSystem->hasMinGLVersion(3, 3) || mRenderSystem->checkExtension("GL_ARB_texture_swizzle"))) { if (PixelUtil::getComponentCount(mFormat) == 2) { mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN); } else { mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ONE); } } GLenum format = GL3PlusPixelUtil::getGLInternalFormat(mFormat, mHwGamma); GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat); width = mWidth; height = mHeight; depth = mDepth; // Allocate texture storage so that glTexSubImageXD can be // used to upload the texture. if (PixelUtil::isCompressed(mFormat)) { // Compressed formats GLsizei size; for (uint32 mip = 0; mip <= mNumMipmaps; mip++) { size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat)); // std::stringstream str; // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID) // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat)) // << " Mip: " + StringConverter::toString(mip) // << " Width: " << StringConverter::toString(width) // << " Height: " << StringConverter::toString(height) // << " Format " << PixelUtil::getFormatName(mFormat) // << " Internal Format: 0x" << std::hex << format // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat) // << " Data type: 0x" << std::hex << datatype; // LogManager::getSingleton().logMessage(LML_NORMAL, str.str()); switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, size, NULL)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, size, NULL)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, size, NULL)); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format, width, height, depth, 0, size, NULL)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, NULL)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) { depth = depth / 2; } } } else { if (mRenderSystem->hasMinGLVersion(4, 2) || mRenderSystem->checkExtension("GL_ARB_texture_storage")) { switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexStorage1D(GL_TEXTURE_1D, GLsizei(mNumMipmaps+1), format, GLsizei(width))); break; case TEX_TYPE_2D: case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); break; case TEX_TYPE_CUBE_MAP: OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_CUBE_MAP, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); break; case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_2D_ARRAY, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth))); break; case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_3D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth))); break; } } else { GLenum originFormat = GL3PlusPixelUtil::getGLOriginFormat(mFormat); // Run through this process to pregenerate mipmap pyramid for(uint32 mip = 0; mip <= mNumMipmaps; mip++) { // std::stringstream str; // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID) // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(width, height, depth, mFormat)) // << " Mip: " + StringConverter::toString(mip) // << " Width: " << StringConverter::toString(width) // << " Height: " << StringConverter::toString(height) // << " Format " << PixelUtil::getFormatName(mFormat) // << " Internal Format: 0x" << std::hex << format // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat) // << " Data type: 0x" << std::hex << datatype; // LogManager::getSingleton().logMessage(LML_NORMAL, str.str()); // Normal formats switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_3D: case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format, width, height, depth, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, originFormat, datatype, NULL)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) { depth = depth / 2; } } } } // Reset unpack alignment to defaults OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); _createSurfaceList(); // Generate mipmaps after all texture levels have been loaded // This is required for compressed formats such as DXT if (PixelUtil::isCompressed(mFormat) && mUsage & TU_AUTOMIPMAP) { OGRE_CHECK_GL_ERROR(glGenerateMipmap(getGL3PlusTextureTarget())); } // Get final internal format. mFormat = getBuffer(0,0)->getFormat(); }
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { PROFILE(SetTextureData); if (!object_ || !graphics_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } graphics_->SetTextureForUpdate(this); bool wholeLevel = x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth; unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; #ifndef GL_ES_VERSION_2_0 if (!IsCompressed()) { if (wholeLevel) glTexImage3D(target_, level, format, width, height, depth, 0, GetExternalFormat(format_), GetDataType(format_), data); else glTexSubImage3D(target_, level, x, y, z, width, height, depth, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage3D(target_, level, format, width, height, depth, 0, GetDataSize(width, height, depth), data); else glCompressedTexSubImage3D(target_, level, x, y, z, width, height, depth, format, GetDataSize(width, height, depth), data); } #endif graphics_->SetTexture(0, 0); return true; }
/* ======================== idImage::AllocImage Every image will pass through this function. Allocates all the necessary MipMap levels for the Image, but doesn't put anything in them. This should not be done during normal game-play, if you can avoid it. ======================== */ void idImage::AllocImage() { GL_CheckErrors(); PurgeImage(); switch( opts.format ) { case FMT_RGBA8: internalFormat = GL_RGBA8; dataFormat = GL_RGBA; dataType = GL_UNSIGNED_BYTE; break; case FMT_XRGB8: internalFormat = GL_RGB; dataFormat = GL_RGBA; dataType = GL_UNSIGNED_BYTE; break; case FMT_RGB565: internalFormat = GL_RGB; dataFormat = GL_RGB; dataType = GL_UNSIGNED_SHORT_5_6_5; break; case FMT_ALPHA: #if defined( USE_CORE_PROFILE ) internalFormat = GL_R8; dataFormat = GL_RED; #else internalFormat = GL_ALPHA8; dataFormat = GL_ALPHA; #endif dataType = GL_UNSIGNED_BYTE; break; case FMT_L8A8: #if defined( USE_CORE_PROFILE ) internalFormat = GL_RG8; dataFormat = GL_RG; #else internalFormat = GL_LUMINANCE8_ALPHA8; dataFormat = GL_LUMINANCE_ALPHA; #endif dataType = GL_UNSIGNED_BYTE; break; case FMT_LUM8: #if defined( USE_CORE_PROFILE ) internalFormat = GL_R8; dataFormat = GL_RED; #else internalFormat = GL_LUMINANCE8; dataFormat = GL_LUMINANCE; #endif dataType = GL_UNSIGNED_BYTE; break; case FMT_INT8: #if defined( USE_CORE_PROFILE ) internalFormat = GL_R8; dataFormat = GL_RED; #else internalFormat = GL_INTENSITY8; dataFormat = GL_LUMINANCE; #endif dataType = GL_UNSIGNED_BYTE; break; case FMT_DXT1: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; dataFormat = GL_RGBA; dataType = GL_UNSIGNED_BYTE; break; case FMT_DXT5: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; dataFormat = GL_RGBA; dataType = GL_UNSIGNED_BYTE; break; case FMT_DEPTH: internalFormat = GL_DEPTH_COMPONENT; dataFormat = GL_DEPTH_COMPONENT; dataType = GL_UNSIGNED_BYTE; break; case FMT_SHADOW_ARRAY: internalFormat = GL_DEPTH_COMPONENT; dataFormat = GL_DEPTH_COMPONENT; dataType = GL_UNSIGNED_BYTE; break; case FMT_X16: internalFormat = GL_INTENSITY16; dataFormat = GL_LUMINANCE; dataType = GL_UNSIGNED_SHORT; break; case FMT_Y16_X16: internalFormat = GL_LUMINANCE16_ALPHA16; dataFormat = GL_LUMINANCE_ALPHA; dataType = GL_UNSIGNED_SHORT; break; default: idLib::Error( "Unhandled image format %d in %s\n", opts.format, GetName() ); } // if we don't have a rendering context, just return after we // have filled in the parms. We must have the values set, or // an image match from a shader before OpenGL starts would miss // the generated texture if( !R_IsInitialized() ) { return; } // generate the texture number glGenTextures( 1, ( GLuint* )&texnum ); assert( texnum != TEXTURE_NOT_LOADED ); //---------------------------------------------------- // allocate all the mip levels with NULL data //---------------------------------------------------- int numSides; int target; int uploadTarget; if( opts.textureType == TT_2D ) { target = uploadTarget = GL_TEXTURE_2D; numSides = 1; } else if( opts.textureType == TT_CUBIC ) { target = GL_TEXTURE_CUBE_MAP; uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; numSides = 6; } // RB begin else if( opts.textureType == TT_2D_ARRAY ) { target = GL_TEXTURE_2D_ARRAY; uploadTarget = GL_TEXTURE_2D_ARRAY; numSides = 6; } // RB end else { assert( !"opts.textureType" ); target = uploadTarget = GL_TEXTURE_2D; numSides = 1; } glBindTexture( target, texnum ); if( opts.textureType == TT_2D_ARRAY ) { glTexImage3D( uploadTarget, 0, internalFormat, opts.width, opts.height, numSides, 0, dataFormat, GL_UNSIGNED_BYTE, NULL ); } else { for( int side = 0; side < numSides; side++ ) { int w = opts.width; int h = opts.height; if( opts.textureType == TT_CUBIC ) { h = w; } for( int level = 0; level < opts.numLevels; level++ ) { // clear out any previous error GL_CheckErrors(); if( IsCompressed() ) { int compressedSize = ( ( ( w + 3 ) / 4 ) * ( ( h + 3 ) / 4 ) * int64( 16 ) * BitsForFormat( opts.format ) ) / 8; // Even though the OpenGL specification allows the 'data' pointer to be NULL, for some // drivers we actually need to upload data to get it to allocate the texture. // However, on 32-bit systems we may fail to allocate a large block of memory for large // textures. We handle this case by using HeapAlloc directly and allowing the allocation // to fail in which case we simply pass down NULL to glCompressedTexImage2D and hope for the best. // As of 2011-10-6 using NVIDIA hardware and drivers we have to allocate the memory with HeapAlloc // with the exact size otherwise large image allocation (for instance for physical page textures) // may fail on Vista 32-bit. // RB begin #if defined(_WIN32) void* data = HeapAlloc( GetProcessHeap(), 0, compressedSize ); glCompressedTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data ); if( data != NULL ) { HeapFree( GetProcessHeap(), 0, data ); } #else byte* data = ( byte* )Mem_Alloc( compressedSize, TAG_TEMP ); glCompressedTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data ); if( data != NULL ) { Mem_Free( data ); } #endif // RB end } else { glTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, dataFormat, dataType, NULL ); } GL_CheckErrors(); w = Max( 1, w >> 1 ); h = Max( 1, h >> 1 ); } } glTexParameteri( target, GL_TEXTURE_MAX_LEVEL, opts.numLevels - 1 ); } // see if we messed anything up GL_CheckErrors(); SetTexParameters(); GL_CheckErrors(); }
void Texture3D::TexImage3D(GLenum _format, GLenum _type, const GLvoid * _data, int _level) /* _level = 0 */ { ValidateNow(); GL_CHECK(glBindTexture(GL_TEXTURE_3D, m_texture)); GL_CHECK(glTexImage3D(GL_TEXTURE_3D, _level, m_format, m_width, m_height, m_depth, 0, _format, _type, _data)); }
void ShadowManager::createShadowMaps(const Light *const light) { //frame buffer object unsigned int fboID; glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_FRAMEBUFFER, fboID); shadowDatas[light]->setFboID(fboID); //textures for shadow map: depth texture && shadow map texture (variance shadow map) GLenum fboAttachments[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, fboAttachments); glReadBuffer(GL_NONE); unsigned int textureIDs[2]; glGenTextures(2, &textureIDs[0]); glBindTexture(GL_TEXTURE_2D_ARRAY, textureIDs[0]); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, depthComponent, shadowMapResolution, shadowMapResolution, nbShadowMaps, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureIDs[0], 0); glBindTexture(GL_TEXTURE_2D_ARRAY, textureIDs[1]); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RG32F, shadowMapResolution, shadowMapResolution, nbShadowMaps, 0, GL_RG, GL_FLOAT, 0); glFramebufferTexture(GL_FRAMEBUFFER, fboAttachments[0], textureIDs[1], 0); shadowDatas[light]->setDepthTextureID(textureIDs[0]); shadowDatas[light]->setShadowMapTextureID(textureIDs[1]); //blur shadow map if(blurShadow!=BlurShadow::NO_BLUR) { std::shared_ptr<TextureFilter> verticalBlurFilter = std::make_shared<TextureFilterBuilder>() ->filterType(TextureFilterBuilder::GAUSSIAN_BLUR_V) ->textureSize(shadowMapResolution, shadowMapResolution) ->textureType(GL_TEXTURE_2D_ARRAY) ->textureNumberLayer(nbShadowMaps) ->textureInternalFormat(GL_RG32F) ->textureFormat(GL_RG) ->blurSize(static_cast<int>(blurShadow)) ->build(); shadowDatas[light]->setVerticalBlurFilter(verticalBlurFilter); std::shared_ptr<TextureFilter> horizontalBlurFilter = std::make_shared<TextureFilterBuilder>() ->filterType(TextureFilterBuilder::GAUSSIAN_BLUR_H) ->textureSize(shadowMapResolution, shadowMapResolution) ->textureType(GL_TEXTURE_2D_ARRAY) ->textureNumberLayer(nbShadowMaps) ->textureInternalFormat(GL_RG32F) ->textureFormat(GL_RG) ->blurSize(static_cast<int>(blurShadow)) ->build(); shadowDatas[light]->setHorizontalBlurFilter(horizontalBlurFilter); } }
bool TF::Texture::SetTexels(void* texels, u32 miplevel, TextureFace face) { if ( miplevel >= mipLevels ) return false; bool success = true; u32 div = 1 << miplevel; // 2 ^ miplevel GLsizei w = width / div; if ( w == 0 ) w = 1; GLsizei h = height / div; if ( h == 0 ) h = 1; GLsizei d = depth / div; if ( d == 0 ) d = 1; // defined in Renderer.cpp void GetOpenGLParametersFromTextureFormat(TextureFormat format, GLint& glInternalFormat, GLenum& glFormat, GLenum& glType, bool& isCompressed); GLint glInternalFormat = 0; GLenum glFormat = 0; GLenum glType = 0; bool isCompressed; GetOpenGLParametersFromTextureFormat(format, glInternalFormat, glFormat, glType, isCompressed); // flip texture vertically since OpenGL starts at lower left corner... if ( type == TT_TEXTURE2D || type == TT_TEXTURECUBE ) { flipImage(texels, w, h, format); } // upload texture to pbo u32 nbBytes = ComputeTextureMemorySize(type, format, w, h, d); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, specific.pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER, nbBytes, 0, GL_STREAM_DRAW); glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, nbBytes, texels); if ( glGetError() ) { LOGWARNING("Failed to upload to PBO."); success = false; goto fail; } // send to video memory switch ( type ) { case TT_TEXTURE1D: { TF_ASSERT(format < TFMT_BC1); glBindTexture(GL_TEXTURE_1D, specific.texture); glTexImage1D(GL_TEXTURE_1D, miplevel, glInternalFormat, w, 0, glFormat, glType, 0); break; } case TT_SHADOW: case TT_TEXTURE2D: case TT_TEXTURECUBE: { GLenum target = type == TT_TEXTURECUBE ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : GL_TEXTURE_2D; glBindTexture(target, specific.texture); if ( isCompressed ) { u32 nbBytes = ComputeTextureMemorySize(type, format, w, h); glCompressedTexImage2D(target, miplevel, glInternalFormat, w, h, 0, nbBytes, 0); } else { glTexImage2D(target, miplevel, glInternalFormat, w, h, 0, glFormat, glType, 0); } break; } case TT_TEXTURE3D: { TF_ASSERT(format < TFMT_BC1); glBindTexture(GL_TEXTURE_3D, specific.texture); glTexImage3D(GL_TEXTURE_3D, miplevel, glInternalFormat, w, h, d, 0, glFormat, glType, 0); break; } } if ( glGetError() ) { LOGWARNING("Failed to upload texels."); success = false; goto fail; } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); fail: // restore texture if ( type == TT_TEXTURE2D || type == TT_TEXTURECUBE ) { flipImage(texels, w, h, format); } return success; }
virtual void updateTexture() { if (mMTime == mTexture->GetMTime()) { return; } mMTime = mTexture->GetMTime(); //vtkgl::ActiveTexture(getGLTextureForVolume(textureUnitIndex)); //TODO is this OK? GLenum size,internalType; boost::uint32_t dimx = mTexture ->GetDimensions( )[0]; boost::uint32_t dimy = mTexture ->GetDimensions( )[1]; boost::uint32_t dimz = mTexture ->GetDimensions( )[2]; mMemorySize = dimx * dimy * dimz; glEnable( GL_TEXTURE_3D ); glBindTexture(GL_TEXTURE_3D, textureId); report_gl_error(); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); switch (mTexture->GetScalarType()) { case VTK_UNSIGNED_CHAR: { size = GL_UNSIGNED_BYTE; internalType = GL_LUMINANCE; } break; //8UI_EXT; break; case VTK_UNSIGNED_SHORT: { size = GL_UNSIGNED_SHORT; internalType = GL_LUMINANCE16; mMemorySize *= 2; } break; //16UI_EXT; break; default: size = 0; internalType = 0; std::cout << "Bit size not supported!" << std::endl; QString dataType(mTexture->GetScalarTypeAsString()); CX_LOG_ERROR() << QString("Attempt to update 3D GL texture from type %1 failed. Only unsigned types supported").arg(dataType); break; } if (mTexture->GetNumberOfScalarComponents()==1) { void* data = mTexture->GetPointData()->GetScalars()->GetVoidPointer(0); glTexImage3D(GL_TEXTURE_3D, 0, internalType, dimx, dimy, dimz, 0, GL_LUMINANCE, size, data); } else if (mTexture->GetNumberOfScalarComponents()==3) { internalType = GL_RGB; void* data = mTexture->GetPointData()->GetScalars()->GetVoidPointer(0); glTexImage3D(GL_TEXTURE_3D, 0, internalType, dimx, dimy, dimz, 0, GL_RGB, size, data); mMemorySize *= 3; } else { std::cout << "unsupported number of image components" << std::endl; } glDisable(GL_TEXTURE_3D); report_gl_error(); }
// Creation / loading methods void GL3PlusTexture::createInternalResourcesImpl(void) { // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps size_t maxMips = GL3PlusPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) mNumRequestedMipmaps = 0; mNumMipmaps = mNumRequestedMipmaps; if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; // Generate texture name OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID)); GLenum texTarget = getGL3PlusTextureTarget(); // Set texture type OGRE_CHECK_GL_ERROR(glBindTexture(texTarget, mTextureID)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, (mMipmapsHardwareGenerated && (mUsage & TU_AUTOMIPMAP)) ? maxMips : mNumMipmaps )); // Set some misc default parameters, these can of course be changed later OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // Set up texture swizzling if(mGLSupport.checkExtension("GL_ARB_texture_swizzle") || gl3wIsSupported(3, 3)) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA)); if(mFormat == PF_BYTE_LA) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN)); } else if(mFormat == PF_L8 || mFormat == PF_L16) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_RED)); } } // If we can do automip generation and the user desires this, do so mMipmapsHardwareGenerated = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); // Allocate internal buffer so that glTexSubImageXD can be used // Internal format GLenum format = GL3PlusPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat); size_t width = mWidth; size_t height = mHeight; size_t depth = mDepth; if (PixelUtil::isCompressed(mFormat)) { // Compressed formats size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not // accept a 0 pointer like normal glTexImageXD // Run through this process for every mipmap to pregenerate mipmap pyramid uint8* tmpdata = new uint8[size]; memset(tmpdata, 0, size); for (size_t mip = 0; mip <= mNumMipmaps; mip++) { size = PixelUtil::getMemorySize(width, height, depth, mFormat); switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, size, tmpdata)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, size, tmpdata)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, size, tmpdata)); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format, width, height, depth, 0, size, tmpdata)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, tmpdata)); } break; default: break; }; // LogManager::getSingleton().logMessage("GL3PlusTexture::create - " + StringConverter::toString(mTextureID) + // " Mip: " + StringConverter::toString(mip) + // " Width: " + StringConverter::toString(width) + // " Height: " + StringConverter::toString(height) + // " Internal Format: " + StringConverter::toString(format) // ); if(width > 1) { width = width / 2; } if(height > 1) { height = height / 2; } if(depth > 1) { depth = depth / 2; } } delete [] tmpdata; } else { if((mGLSupport.checkExtension("GL_ARB_texture_storage") || gl3wIsSupported(4, 2)) && mTextureType == TEX_TYPE_2D) { OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLint(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); } else { // Run through this process to pregenerate mipmap pyramid for(size_t mip = 0; mip <= mNumMipmaps; mip++) { // Normal formats switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, GL_RGBA, datatype, 0)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); break; case TEX_TYPE_3D: case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format, width, height, depth, 0, GL_RGBA, datatype, 0)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1) { depth = depth / 2; } } } } _createSurfaceList(); // Get final internal format mFormat = getBuffer(0,0)->getFormat(); }
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples) { m_xfbFramebuffer = 0; m_efbColor = 0; m_efbDepth = 0; m_efbColorSwap = 0; m_resolvedColorTexture = 0; m_resolvedDepthTexture = 0; m_targetWidth = targetWidth; m_targetHeight = targetHeight; m_msaaSamples = msaaSamples; // The EFB can be set to different pixel formats by the game through the // BPMEM_ZCOMPARE register (which should probably have a different name). // They are: // - 24-bit RGB (8-bit components) with 24-bit Z // - 24-bit RGBA (6-bit components) with 24-bit Z // - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z // We only use one EFB format here: 32-bit ARGB with 24-bit Z. // Multisampling depends on user settings. // The distinction becomes important for certain operations, i.e. the // alpha channel should be ignored if the EFB does not have one. glActiveTexture(GL_TEXTURE9); GLuint glObj[3]; glGenTextures(3, glObj); m_efbColor = glObj[0]; m_efbDepth = glObj[1]; m_efbColorSwap = glObj[2]; m_EFBLayers = (g_ActiveConfig.iStereoMode > 0) ? 2 : 1; m_efbFramebuffer = new GLuint[m_EFBLayers](); m_resolvedFramebuffer = new GLuint[m_EFBLayers](); // OpenGL MSAA textures are a different kind of texture type and must be allocated // with a different function, so we create them separately. if (m_msaaSamples <= 1) { m_textureType = GL_TEXTURE_2D_ARRAY; glBindTexture(m_textureType, m_efbColor); glTexParameteri(m_textureType, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(m_textureType, 0, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glBindTexture(m_textureType, m_efbDepth); glTexParameteri(m_textureType, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(m_textureType, 0, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, m_EFBLayers, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); glBindTexture(m_textureType, m_efbColorSwap); glTexParameteri(m_textureType, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(m_textureType, 0, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } else { GLenum resolvedType = GL_TEXTURE_2D_ARRAY; // Only use a layered multisample texture if needed. Some drivers // slow down significantly with single-layered multisample textures. if (m_EFBLayers > 1) { m_textureType = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; glBindTexture(m_textureType, m_efbColor); glTexImage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, false); glBindTexture(m_textureType, m_efbDepth); glTexImage3DMultisample(m_textureType, m_msaaSamples, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, m_EFBLayers, false); glBindTexture(m_textureType, m_efbColorSwap); glTexImage3DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, false); glBindTexture(m_textureType, 0); } else { m_textureType = GL_TEXTURE_2D_MULTISAMPLE; glBindTexture(m_textureType, m_efbColor); glTexImage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, false); glBindTexture(m_textureType, m_efbDepth); glTexImage2DMultisample(m_textureType, m_msaaSamples, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, false); glBindTexture(m_textureType, m_efbColorSwap); glTexImage2DMultisample(m_textureType, m_msaaSamples, GL_RGBA, m_targetWidth, m_targetHeight, false); glBindTexture(m_textureType, 0); } // Although we are able to access the multisampled texture directly, we don't do it everywhere. // The old way is to "resolve" this multisampled texture by copying it into a non-sampled texture. // This would lead to an unneeded copy of the EFB, so we are going to avoid it. // But as this job isn't done right now, we do need that texture for resolving: glGenTextures(2, glObj); m_resolvedColorTexture = glObj[0]; m_resolvedDepthTexture = glObj[1]; glBindTexture(resolvedType, m_resolvedColorTexture); glTexParameteri(resolvedType, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(resolvedType, 0, GL_RGBA, m_targetWidth, m_targetHeight, m_EFBLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glBindTexture(resolvedType, m_resolvedDepthTexture); glTexParameteri(resolvedType, GL_TEXTURE_MAX_LEVEL, 0); glTexImage3D(resolvedType, 0, GL_DEPTH_COMPONENT32F, m_targetWidth, m_targetHeight, m_EFBLayers, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); // Bind resolved textures to resolved framebuffer. glGenFramebuffers(m_EFBLayers, m_resolvedFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_resolvedFramebuffer[0]); FramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, resolvedType, m_resolvedColorTexture, 0); FramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, resolvedType, m_resolvedDepthTexture, 0); // Bind all the other layers as separate FBOs for blitting. for (unsigned int i = 1; i < m_EFBLayers; i++) { glBindFramebuffer(GL_FRAMEBUFFER, m_resolvedFramebuffer[i]); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_resolvedColorTexture, 0, i); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_resolvedDepthTexture, 0, i); } } // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffers(1, &m_xfbFramebuffer); // Bind target textures to EFB framebuffer. glGenFramebuffers(m_EFBLayers, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer[0]); FramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_textureType, m_efbColor, 0); FramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_textureType, m_efbDepth, 0); // Bind all the other layers as separate FBOs for blitting. for (unsigned int i = 1; i < m_EFBLayers; i++) { glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer[i]); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_efbColor, 0, i); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_efbDepth, 0, i); } // EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f glViewport(0, 0, m_targetWidth, m_targetHeight); glScissor(0, 0, m_targetWidth, m_targetHeight); glClearColor(0.f, 0.f, 0.f, 1.f); glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // reinterpret pixel format const char* vs = m_EFBLayers > 1 ? "void main(void) {\n" " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n" " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n" "}\n" : "flat out int layer;\n" "void main(void) {\n" " layer = 0;\n" " vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n" " gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n" "}\n"; // The way to sample the EFB is based on the on the current configuration. // As we use the same sampling way for both interpreting shaders, the sampling // shader are generated first: std::string sampler; if (m_msaaSamples <= 1) { // non-msaa, so just fetch the pixel sampler = "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n" "vec4 sampleEFB(ivec3 pos) {\n" " return texelFetch(samp9, pos, 0);\n" "}\n"; } else if (g_ogl_config.bSupportSampleShading) { // msaa + sample shading available, so just fetch the sample // This will lead to sample shading, but it's the only way to not loose // the values of each sample. if (m_EFBLayers > 1) { sampler = "SAMPLER_BINDING(9) uniform sampler2DMSArray samp9;\n" "vec4 sampleEFB(ivec3 pos) {\n" " return texelFetch(samp9, pos, gl_SampleID);\n" "}\n"; } else { sampler = "SAMPLER_BINDING(9) uniform sampler2DMS samp9;\n" "vec4 sampleEFB(ivec3 pos) {\n" " return texelFetch(samp9, pos.xy, gl_SampleID);\n" "}\n"; } } else { // msaa without sample shading: calculate the mean value of the pixel std::stringstream samples; samples << m_msaaSamples; if (m_EFBLayers > 1) { sampler = "SAMPLER_BINDING(9) uniform sampler2DMSArray samp9;\n" "vec4 sampleEFB(ivec3 pos) {\n" " vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n" " for(int i=0; i<" + samples.str() + "; i++)\n" " color += texelFetch(samp9, pos, 0), i);\n" " return color / " + samples.str() + ";\n" "}\n"; } else { sampler = "SAMPLER_BINDING(9) uniform sampler2DMS samp9;\n" "vec4 sampleEFB(ivec3 pos) {\n" " vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n" " for(int i=0; i<" + samples.str() + "; i++)\n" " color += texelFetch(samp9, pos.xy, i);\n" " return color / " + samples.str() + ";\n" "}\n"; } } std::string ps_rgba6_to_rgb8 = sampler + "flat in int layer;\n" "out vec4 ocol0;\n" "void main()\n" "{\n" " ivec4 src6 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xy, layer)) * 63.f));\n" " ivec4 dst8;\n" " dst8.r = (src6.r << 2) | (src6.g >> 4);\n" " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n" " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n" " dst8.a = 255;\n" " ocol0 = float4(dst8) / 255.f;\n" "}"; std::string ps_rgb8_to_rgba6 = sampler + "flat in int layer;\n" "out vec4 ocol0;\n" "void main()\n" "{\n" " ivec4 src8 = ivec4(round(sampleEFB(ivec3(gl_FragCoord.xy, layer)) * 255.f));\n" " ivec4 dst6;\n" " dst6.r = src8.r >> 2;\n" " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n" " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n" " dst6.a = src8.b & 0x3F;\n" " ocol0 = float4(dst6) / 63.f;\n" "}"; std::stringstream vertices, layers; vertices << m_EFBLayers * 3; layers << m_EFBLayers; std::string gs = "layout(triangles) in;\n" "layout(triangle_strip, max_vertices = " + vertices.str() + ") out;\n" "flat out int layer;\n" "void main()\n" "{\n" " for (int j = 0; j < " + layers.str() + "; ++j) {\n" " for (int i = 0; i < 3; ++i) {\n" " layer = j;\n" " gl_Layer = j;\n" " gl_Position = gl_in[i].gl_Position;\n" " EmitVertex();\n" " }\n" " EndPrimitive();\n" " }\n" "}\n"; ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr); ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8.c_str(), (m_EFBLayers > 1) ? gs.c_str() : nullptr); ProgramShaderCache::CompileShader(m_EfbPokes, StringFromFormat( "in vec2 rawpos;\n" "in vec4 color0;\n" // color "in int color1;\n" // depth "out vec4 v_c;\n" "out float v_z;\n" "void main(void) {\n" " gl_Position = vec4(((rawpos + 0.5) / vec2(640.0, 528.0) * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);\n" " gl_PointSize = %d.0 / 640.0;\n" " v_c = color0.bgra;\n" " v_z = float(color1 & 0xFFFFFF) / 16777216.0;\n" "}\n", m_targetWidth).c_str(), StringFromFormat( "in vec4 %s_c;\n" "in float %s_z;\n" "out vec4 ocol0;\n" "void main(void) {\n" " ocol0 = %s_c;\n" " gl_FragDepth = %s_z;\n" "}\n", m_EFBLayers > 1 ? "g" : "v", m_EFBLayers > 1 ? "g" : "v", m_EFBLayers > 1 ? "g" : "v", m_EFBLayers > 1 ? "g" : "v").c_str(), m_EFBLayers > 1 ? StringFromFormat( "layout(points) in;\n" "layout(points, max_vertices = %d) out;\n" "in vec4 v_c[1];\n" "in float v_z[1];\n" "out vec4 g_c;\n" "out float g_z;\n" "void main()\n" "{\n" " for (int j = 0; j < %d; ++j) {\n" " gl_Layer = j;\n" " gl_Position = gl_in[0].gl_Position;\n" " gl_PointSize = %d.0 / 640.0;\n" " g_c = v_c[0];\n" " g_z = v_z[0];\n" " EmitVertex();\n" " EndPrimitive();\n" " }\n" "}\n", m_EFBLayers, m_EFBLayers, m_targetWidth).c_str() : nullptr); glGenBuffers(1, &m_EfbPokes_VBO); glGenVertexArrays(1, &m_EfbPokes_VAO); glBindBuffer(GL_ARRAY_BUFFER, m_EfbPokes_VBO); glBindVertexArray(m_EfbPokes_VAO ); glEnableVertexAttribArray(SHADER_POSITION_ATTRIB); glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_UNSIGNED_SHORT, 0, sizeof(EfbPokeData), (void*)offsetof(EfbPokeData, x)); glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB); glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 4, GL_UNSIGNED_BYTE, 1, sizeof(EfbPokeData), (void*)offsetof(EfbPokeData, data)); glEnableVertexAttribArray(SHADER_COLOR1_ATTRIB); glVertexAttribIPointer(SHADER_COLOR1_ATTRIB, 1, GL_INT, sizeof(EfbPokeData), (void*)offsetof(EfbPokeData, data)); if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) glEnable(GL_PROGRAM_POINT_SIZE); }
void Surface::init(unsigned w, unsigned h, unsigned d, GLenum ext_fmt, GLenum ext_type, GLvoid **ext_data) { if (gl_id > 0) { throw std::runtime_error("Already initialized"); } switch (desc.surface_type) { case SURF_NONE: throw std::invalid_argument("SURF_NONE"); case SURF_COLOUR: if (!desc.is_texture) return throw std::invalid_argument("Colour buffers must be textures"); break; case SURF_DEPTH: case SURF_STENCIL: case SURF_DEPTH_STENCIL: if (desc.is_texture) return throw std::invalid_argument("Stencil and depth buffers must not be textures"); break; } if (desc.is_texture) { if (desc.gl_tgt != GL_TEXTURE_RECTANGLE_ARB) { P2(w); P2(h); P2(d); } glGenTextures(1, &gl_id); glBindTexture(desc.gl_tgt, gl_id); glGetError(); if (ext_fmt == 0) ext_fmt = externalFormatForInternal(desc.gl_fmt); switch (desc.gl_tgt) { case GL_TEXTURE_1D: glTexImage1D(desc.gl_tgt, 0, desc.gl_fmt, w, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_ARB: glTexImage2D(desc.gl_tgt, 0, desc.gl_fmt, w, h, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; case GL_TEXTURE_CUBE_MAP: for (int i = 0; i < 6; ++i) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, desc.gl_fmt, w, h, 0, ext_fmt, ext_type, ext_data ? ext_data[i] : NULL); } break; case GL_TEXTURE_3D: glTexImage3D(desc.gl_tgt, 0, desc.gl_fmt, w, h, d, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; } GLuint err = glGetError(); if (err) { glDeleteTextures(1, &gl_id); gl_id = 0; throw std::runtime_error("failed to initialize texture"); } if (desc.is_mipmapped) glGenerateMipmapEXT(desc.gl_tgt); desc.param.apply(desc.gl_tgt); glBindTexture(desc.gl_tgt, 0); } else { glGenRenderbuffersEXT(1, &gl_id); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, gl_id); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, desc.gl_fmt, w, h); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } width = w; height = h; depth = d; }
OsdGLPtexMipmapTexture * OsdGLPtexMipmapTexture::Create(PtexTexture * reader, int maxLevels) { OsdGLPtexMipmapTexture * result = NULL; GLint maxNumPages = 0; glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxNumPages); // Read the ptexture data and pack the texels OsdPtexMipmapTextureLoader loader(reader, maxNumPages, maxLevels); // Setup GPU memory int numFaces = loader.GetNumFaces(); GLuint layout = genTextureBuffer(GL_R16I, numFaces * 6 * sizeof(GLshort), loader.GetLayoutBuffer()); GLenum format, type; switch (reader->dataType()) { case Ptex::dt_uint16 : type = GL_UNSIGNED_SHORT; break; case Ptex::dt_float : type = GL_FLOAT; break; case Ptex::dt_half : type = GL_HALF_FLOAT; break; default : type = GL_UNSIGNED_BYTE; break; } switch (reader->numChannels()) { case 1 : format = GL_RED; break; case 2 : format = GL_RG; break; case 3 : format = GL_RGB; break; case 4 : format = GL_RGBA; break; default: format = GL_RED; break; } // actual texels texture array GLuint texels; glGenTextures(1, &texels); glBindTexture(GL_TEXTURE_2D_ARRAY, texels); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, (type == GL_FLOAT) ? GL_RGBA32F : GL_RGBA, loader.GetPageWidth(), loader.GetPageHeight(), loader.GetNumPages(), 0, format, type, loader.GetTexelBuffer()); // loader.ClearBuffers(); // Return the Osd Ptexture object result = new OsdGLPtexMipmapTexture; result->_width = loader.GetPageWidth(); result->_height = loader.GetPageHeight(); result->_depth = loader.GetNumPages(); result->_format = format; result->_layout = layout; result->_texels = texels; return result; }
bool Texture::Create( const Texture::Properties& properties, const void* ptr) { Destroy(); SetProperties(properties); if(IsValid()) return true; GLuint handle = properties.Handle; if(handle < 1) glGenTextures(1, &handle); if(handle < 1) return false; m_Properties.Handle = handle; // glActiveTextureARB(m_Properties.TextureUnit); // Texture::CheckStatus(m_Properties.Name, "Activating texture unit"); glBindTexture(m_Properties.Target, handle); Texture::CheckStatus(m_Properties.Name, "Binding texture"); if(!m_Properties.Internal) m_Properties.Internal = GL_RGBA; if(!m_Properties.Format) m_Properties.Format = m_Properties.Internal; if(!m_Properties.DataType) m_Properties.DataType = GL_UNSIGNED_BYTE; if(m_Properties.Internal == GL_DEPTH_COMPONENT) { int iDepth = 8; glGetIntegerv(GL_DEPTH_BITS, &iDepth); if(iDepth == 16) m_Properties.Internal = GL_DEPTH_COMPONENT16; else if(iDepth == 24) m_Properties.Internal = GL_DEPTH_COMPONENT24; else if(iDepth == 32) m_Properties.Internal = GL_DEPTH_COMPONENT32; } if(m_Properties.Target == GL_TEXTURE_3D) { if(m_Properties.UseMipMaps && ptr) { if(!m_Properties.MinFilterMode) m_Properties.MinFilterMode = GL_LINEAR_MIPMAP_NEAREST; if(!m_Properties.MagFilterMode) m_Properties.MagFilterMode = GL_LINEAR_MIPMAP_LINEAR; gluBuild3DMipmaps(m_Properties.Target, m_Properties.Internal, m_Properties.Width, m_Properties.Height, m_Properties.Depth, m_Properties.Format, m_Properties.DataType, ptr ); } else { if(!m_Properties.MinFilterMode) m_Properties.MinFilterMode = GL_LINEAR; if(!m_Properties.MagFilterMode) m_Properties.MagFilterMode = GL_LINEAR; glTexImage3D(m_Properties.Target, 0, m_Properties.Internal, m_Properties.Width, m_Properties.Height, m_Properties.Depth, 0, m_Properties.Format, m_Properties.DataType, ptr); } } else if(m_Properties.Target == GL_TEXTURE_2D || GL_TEXTURE_RECTANGLE_ARB) { if(m_Properties.UseMipMaps && ptr) { if(!m_Properties.MinFilterMode) m_Properties.MinFilterMode = GL_LINEAR_MIPMAP_NEAREST; if(!m_Properties.MagFilterMode) m_Properties.MagFilterMode = GL_LINEAR_MIPMAP_LINEAR; gluBuild2DMipmaps(m_Properties.Target, m_Properties.Internal, m_Properties.Width, m_Properties.Height, m_Properties.Format, m_Properties.DataType, ptr ); } else { if(!m_Properties.MinFilterMode) m_Properties.MinFilterMode = GL_LINEAR; if(!m_Properties.MagFilterMode) m_Properties.MagFilterMode = GL_LINEAR; glTexImage2D(m_Properties.Target, 0, m_Properties.Internal, m_Properties.Width, m_Properties.Height, 0, m_Properties.Format, m_Properties.DataType, ptr); } } glTexParameteri(m_Properties.Target, GL_TEXTURE_MIN_FILTER, m_Properties.MinFilterMode); glTexParameteri(m_Properties.Target, GL_TEXTURE_MAG_FILTER, m_Properties.MagFilterMode); Texture::CheckStatus(m_Properties.Name, "Allocating texture"); glBindTexture(m_Properties.Target, 0); Texture::CheckStatus(m_Properties.Name, "Unbinding texture"); // glActiveTextureARB(GL_TEXTURE0); // Texture::CheckStatus(m_Properties.Name, "Disabling texture unit"); return true; }
// submit manually // supports the modes valid in GLES 1.0 virtual void submit(void * pixels=NULL, uint32_t align=4) { validate(); glBindTexture(mTarget, id()); // set glPixelStore according to the array layout: //glPixelStorei(GL_UNPACK_ALIGNMENT, align); switch (mTarget) { case GL_TEXTURE_1D: glTexImage1D(mTarget, 0, // GLint level mInternalFormat, width(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; case GL_TEXTURE_2D: glTexImage2D(mTarget, 0, // GLint level mInternalFormat, width(), height(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; case GL_TEXTURE_3D: glTexImage3D(mTarget, 0, // GLint level mInternalFormat, width(), height(), depth(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; default: printf("texture target not supported yet\n"); break; } // set alignment back to default //glPixelStorei(GL_UNPACK_ALIGNMENT, 4); Graphics::error("submitting texture"); // // OpenGL may have changed the internal format to one it supports: // GLint format; // glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); // if (format != mInternalFormat) { // printf("converted from %X to %X format\n", mInternalFormat, format); // mInternalFormat = format; // } //printf("submitted texture data %p\n", pixels); glBindTexture(mTarget, 0); }
/** * Create a texture image with reference values. Draw a textured quad. * Save reference image with glReadPixels(). * Loop: * replace a sub-region of the texture image with same values * draw test textured quad * read test image with glReadPixels * compare reference image to test image * \param target GL_TEXTURE_1D/2D/3D * \param intFormat the internal texture format */ static GLboolean test_format(GLenum target, GLenum intFormat) { const GLenum srcFormat = GL_RGBA; GLuint w = 128, h = 64, d = 8; GLuint tex, i, j, k, n, t; GLubyte *img, *ref, *testImg; GLboolean pass = GL_TRUE; GLuint bw, bh, wMask, hMask, dMask; get_format_block_size(intFormat, &bw, &bh); wMask = ~(bw-1); hMask = ~(bh-1); dMask = ~0; if (target != GL_TEXTURE_3D) d = 1; if (target == GL_TEXTURE_1D) h = 1; img = (GLubyte *) malloc(w * h * d * 4); ref = (GLubyte *) malloc(w * h * d * 4); testImg = (GLubyte *) malloc(w * h * d * 4); /* fill source tex image */ n = 0; for (i = 0; i < d; i++) { for (j = 0; j < h; j++) { for (k = 0; k < w; k++) { img[n++] = j * 4; img[n++] = k * 2; img[n++] = i * 16; img[n++] = 255; } } } glPixelStorei(GL_UNPACK_ROW_LENGTH, w); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h); glGenTextures(1, &tex); glBindTexture(target, tex); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); if (target == GL_TEXTURE_1D) { glTexImage1D(target, 0, intFormat, w, 0, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexImage2D(target, 0, intFormat, w, h, 0, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_3D) { glTexImage3D(target, 0, intFormat, w, h, d, 0, srcFormat, GL_UNSIGNED_BYTE, img); } glEnable(target); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); /* draw reference image */ glClear(GL_COLOR_BUFFER_BIT); piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ref); for (t = 0; t < 10; t++) { /* Choose random region of texture to update. * Use sizes and positions that are multiples of * the compressed block size. */ GLint tw = (rand() % w) & wMask; GLint th = (rand() % h) & hMask; GLint td = (rand() % d) & dMask; GLint tx = (rand() % (w - tw)) & wMask; GLint ty = (rand() % (h - th)) & hMask; GLint tz = (rand() % (d - td)) & dMask; assert(tx + tw <= w); assert(ty + th <= h); assert(tz + td <= d); /* replace texture region (with same data) */ glPixelStorei(GL_UNPACK_SKIP_PIXELS, tx); glPixelStorei(GL_UNPACK_SKIP_ROWS, ty); glPixelStorei(GL_UNPACK_SKIP_IMAGES, tz); if (target == GL_TEXTURE_1D) { glTexSubImage1D(target, 0, tx, tw, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexSubImage2D(target, 0, tx, ty, tw, th, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexSubImage3D(target, 0, tx, ty, tz, tw, th, td, srcFormat, GL_UNSIGNED_BYTE, img); } /* draw test image */ glClear(GL_COLOR_BUFFER_BIT); piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, testImg); piglit_present_results(); if (!equal_images(ref, testImg, w, h)) { printf("texsubimage failed\n"); printf(" target: %s\n", piglit_get_gl_enum_name(target)); printf(" internal format: %s\n", piglit_get_gl_enum_name(intFormat)); printf(" region: %d, %d %d x %d\n", tx, ty, tw, th); pass = GL_FALSE; break; } } glDisable(target); free(img); free(ref); free(testImg); glDeleteTextures(1, &tex); return pass; }
/** Test target params to glTexImage functions */ static GLboolean test_targets(void) { /* all of these should generate GL_INVALID_ENUM */ glTexImage1D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexImage2D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glTexImage3D(GL_TEXTURE_1D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage3D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage1D(GL_TEXTURE_2D, 0, 6, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage1D(GL_PROXY_TEXTURE_1D, 0, 6, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage2D(GL_PROXY_TEXTURE_2D, 0, 6, 6, 10, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage3D(GL_PROXY_TEXTURE_2D, 0, 6, 6, 6, 10, 10, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage3D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage1D(GL_PROXY_TEXTURE_1D, 0, GL_RGBA, 4, 4, 16, 0); if (!verify_error("glCopyTexImage1D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 4, 4, 16, 16, 0); if (!verify_error("glCopyTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage2D(GL_TEXTURE_1D, 0, GL_RGBA, 4, 4, 16, 16, 0); if (!verify_error("glCopyTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage1D(GL_PROXY_TEXTURE_1D, 0, 4, 4, 6, 10); if (!verify_error("glCopyTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage2D(GL_PROXY_TEXTURE_2D, 0, 4, 4, 6, 6, 10, 10); if (!verify_error("glCopyTexSubImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage3D(GL_PROXY_TEXTURE_3D, 0, 4, 4, 4, 6, 6, 10, 10); if (!verify_error("glCopyTexSubImage2D", GL_INVALID_ENUM)) return GL_FALSE; return GL_TRUE; }
GLuint Texture::generateTexture3D(GLenum texTarget, GLuint surfaceWidth, GLuint surfaceHeight, GLuint surfaceDepth, GLint texInternalFormat, GLenum type , GLenum format , void *data , bool buildMipMap , GLint mip_level, GLint border, GLint wrapModeR , GLint wrapModeS , GLint wrapModeT , GLint minFilter , GLint magFilter ) { // Make sure if texture is created before then delete it. deleteTexture(); internalFormat = texInternalFormat; width = surfaceWidth; height = surfaceHeight; depth = surfaceDepth; target = texTarget; miniFilter = minFilter; magniFilter = magFilter; texWrapModeR = wrapModeR; texWrapModeS = wrapModeS; texWrapModeT = wrapModeT; glGenTextures(1, &texID); /* // Check the glError here glErr = glGetError(); if(glErr != GL_NO_ERROR){ return; } */ // Allocate OpenGL texture memory and bind to it. glBindTexture (target, texID); // Set texture's S wrapping mode type glTexParameteri(target, GL_TEXTURE_WRAP_R, texWrapModeR); glTexParameteri(target, GL_TEXTURE_WRAP_S, texWrapModeS); glTexParameteri(target, GL_TEXTURE_WRAP_T, texWrapModeT); // Set texture's interpolation glTexParameteri(target, GL_TEXTURE_MIN_FILTER, miniFilter); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magniFilter); // Set texture's format glTexImage3D (target, mip_level, internalFormat, width, height, depth, border, format, type, data); if(buildMipMap){ glGenerateMipmap(target); } return texID; }