📄 teximage.c
字号:
"glTexSubImage%D(xoffset or yoffset)", dimensions); return GL_TRUE; } /* size must be multiple of 4 or equal to whole texture size */ if ((width & 3) && (GLuint) width != texImage->Width) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; } if ((height & 3) && (GLuint) height != texImage->Height) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; } } return GL_FALSE;}/** * Test glCopyTexImage[12]D() parameters for errors. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param target texture target given by the user. * \param level image level given by the user. * \param internalFormat internal format given by the user. * \param width image width given by the user. * \param height image height given by the user. * \param depth image depth given by the user. * \param border texture border. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. * * Verifies each of the parameters against the constants specified in * __GLcontextRec::Const and the supported extensions, and according to the * OpenGL specification. */static GLbooleancopytexture_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border ){ GLenum type; GLboolean sizeOK; GLint format; /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glCopyTexImage%dD(invalid readbuffer)", dimensions); return GL_TRUE; } } _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage%dD(level=%d)", dimensions, level); return GL_TRUE; } /* Check border */ if (border < 0 || border > 1 || ((target == GL_TEXTURE_RECTANGLE_NV || target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { return GL_TRUE; } format = _mesa_base_tex_format(ctx, internalFormat); if (format < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage%dD(internalFormat)", dimensions); return GL_TRUE; } /* NOTE: the format and type aren't really significant for * TestProxyTexImage(). Only the internalformat really matters. if (!_mesa_source_buffer_exists(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%dD(missing readbuffer)", dimensions); return GL_TRUE; } */ type = GL_FLOAT; /* Check target and call ctx->Driver.TestProxyTexImage() to check the * level, width, height and depth. */ if (dimensions == 1) { if (target == GL_TEXTURE_1D) { sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D, level, internalFormat, format, type, width, 1, 1, border); } else { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); return GL_TRUE; } } else if (dimensions == 2) { if (target == GL_TEXTURE_2D) { sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D, level, internalFormat, format, type, width, height, 1, border); } else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); return GL_TRUE; } sizeOK = (width == height) && ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB, level, internalFormat, format, type, width, height, 1, border); } else if (target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); return GL_TRUE; } sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_RECTANGLE_NV, level, internalFormat, format, type, width, height, 1, border); } else { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); return GL_TRUE; } } else { _mesa_problem(ctx, "invalid dimensions in copytexture_error_check"); return GL_TRUE; } if (!sizeOK) { if (dimensions == 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width=%d)", width); } else { ASSERT(dimensions == 2); _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width=%d, height=%d)", width, height); } return GL_TRUE; } if (is_compressed_format(ctx, internalFormat)) { if (target != GL_TEXTURE_2D) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%d(target)", dimensions); return GL_TRUE; } if (border != 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%D(border!=0)", dimensions); return GL_TRUE; } } else if (is_depth_format(internalFormat)) { /* make sure we have depth/stencil buffers */ if (!ctx->ReadBuffer->_DepthBuffer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%D(no depth)", dimensions); return GL_TRUE; } } else if (is_depthstencil_format(internalFormat)) { /* make sure we have depth/stencil buffers */ if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%D(no depth/stencil buffer)", dimensions); return GL_TRUE; } } /* if we get here, the parameters are OK */ return GL_FALSE;}/** * Test glCopyTexSubImage[12]D() parameters for errors. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param target texture target given by the user. * \param level image level given by the user. * \param xoffset sub-image x offset given by the user. * \param yoffset sub-image y offset given by the user. * \param zoffset sub-image z offset given by the user. * \param width image width given by the user. * \param height image height given by the user. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. * * Verifies each of the parameters against the constants specified in * __GLcontextRec::Const and the supported extensions, and according to the * OpenGL specification. */static GLbooleancopytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height ){ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_image *teximage; /* Check target */ /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glCopyTexImage%dD(invalid readbuffer)", dimensions); return GL_TRUE; } } if (dimensions == 1) { if (target != GL_TEXTURE_1D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); return GL_TRUE; } } else if (dimensions == 2) { if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); return GL_TRUE; } } else if (target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); return GL_TRUE; } } else if (target != GL_TEXTURE_2D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); return GL_TRUE; } } else if (dimensions == 3) { if (target != GL_TEXTURE_3D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); return GL_TRUE; } } /* Check level */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(level=%d)", dimensions, level); return GL_TRUE; } /* Check size */ if (width < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(width=%d)", dimensions, width); return GL_TRUE; } if (dimensions > 1 && height < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(height=%d)", dimensions, height); return GL_TRUE; } teximage = _mesa_select_tex_image(ctx, texUnit, target, level); if (!teximage) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(undefined texture level: %d)", dimensions, level); return GL_TRUE; } if (xoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); return GL_TRUE; } if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(xoffset+width)", dimensions); return GL_TRUE; } if (dimensions > 1) { if (yoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); return GL_TRUE; } /* NOTE: we're adding the border here, not subtracting! */ if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(yoffset+height)", dimensions); return GL_TRUE; } } if (dimensions > 2) { if (zoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(zoffset)", dimensions); return GL_TRUE; } if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(zoffset+depth)", dimensions); return GL_TRUE; } } if (teximage->IsCompressed) { if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(missing readbuffer)", dimensions); return GL_TRUE; } if (target != GL_TEXTURE_2D) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%d(target)", dimensions); return GL_TRUE; } /* offset must be multiple of 4 */ if ((xoffset & 3) || (yoffset & 3)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%D(xoffset or yoffset)", dimensions); return GL_TRUE; } /* size must be multiple of 4 */ if ((width & 3) != 0 && (GLuint) width != teximage->Width) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%D(width)", dimensions); return GL_TRUE; } if ((height & 3) != 0 && (GLuint) height != teximage->Height) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%D(height)", dimensions); return GL_TRUE; } } if (teximage->InternalFormat == GL_YCBCR_MESA) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); return GL_TRUE; } if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) { if (!ctx->ReadBuffer->_DepthBuffer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%D(no depth buffer)", dimensions); return GL_TRUE; } } else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%D(no depth/stencil buffer)", dimensions); return GL_TRUE; } } /* if we get here, the parameters are OK */ return GL_FALSE;}/** * Get texture image. Called by glGetTexImage. * * \param target texture target. * \param level image level. * \param format pixel data format for returned image. * \param type pixel data type for returned image. * \param pixels returned pixel data. */void GLAPIENTRY_mesa_GetTexImage( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ){ const struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLint maxLevels = 0; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); texObj = _mesa_select_tex_object(ctx, texUnit, target); if (!texObj || _mesa_is_proxy_texture(target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); return; } maxLevels = _mesa_max_texture_levels(ctx, target);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -