⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texrender.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
字号:
#include "context.h"#include "fbobject.h"#include "texformat.h"#include "texrender.h"#include "renderbuffer.h"/* * Render-to-texture code for GL_EXT_framebuffer_object *//** * Derived from gl_renderbuffer class */struct texture_renderbuffer{   struct gl_renderbuffer Base;   /**< Base class object */   struct gl_texture_image *TexImage;   StoreTexelFunc Store;   GLint Yoffset;                 /**< Layer for 1D array textures. */   GLint Zoffset;                 /**< Layer for 2D array textures, or slice				   * for 3D textures				   */};/** * Get row of values from the renderbuffer that wraps a texture image. */static voidtexture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                GLint x, GLint y, void *values){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   ASSERT(trb->TexImage->Width == rb->Width);   ASSERT(trb->TexImage->Height == rb->Height);   y += trb->Yoffset;   if (rb->DataType == CHAN_TYPE) {      GLchan *rgbaOut = (GLchan *) values;      for (i = 0; i < count; i++) {         trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i);      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      GLuint *zValues = (GLuint *) values;      /*      const GLdouble scale = (GLdouble) 0xffffffff;      */      for (i = 0; i < count; i++) {         GLfloat flt;         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);#if 0         /* this should work, but doesn't (overflow due to low precision) */         zValues[i] = (GLuint) (flt * scale);#else         /* temporary hack */         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;#endif      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      GLuint *zValues = (GLuint *) values;      for (i = 0; i < count; i++) {         GLfloat flt;         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_get_row");   }}static voidtexture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                   const GLint x[], const GLint y[], void *values){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   if (rb->DataType == CHAN_TYPE) {      GLchan *rgbaOut = (GLchan *) values;      for (i = 0; i < count; i++) {         trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i] + trb->Yoffset,				    z, rgbaOut + 4 * i);      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      GLuint *zValues = (GLuint *) values;      for (i = 0; i < count; i++) {         GLfloat flt;         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,				    z, &flt);#if 0         zValues[i] = (GLuint) (flt * 0xffffffff);#else         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;#endif      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      GLuint *zValues = (GLuint *) values;      for (i = 0; i < count; i++) {         GLfloat flt;         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,				    z, &flt);         zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_get_values");   }}/** * Put row of values into a renderbuffer that wraps a texture image. */static voidtexture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                GLint x, GLint y, const void *values, const GLubyte *mask){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   y += trb->Yoffset;   if (rb->DataType == CHAN_TYPE) {      const GLchan *rgba = (const GLchan *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x + i, y, z, rgba);         }         rgba += 4;      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      const GLuint *zValues = (const GLuint *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x + i, y, z, zValues + i);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      const GLuint *zValues = (const GLuint *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff);            trb->Store(trb->TexImage, x + i, y, z, &flt);         }      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_put_row");   }}static voidtexture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                     GLint x, GLint y, const void *value, const GLubyte *mask){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   y += trb->Yoffset;   if (rb->DataType == CHAN_TYPE) {      const GLchan *rgba = (const GLchan *) value;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x + i, y, z, rgba);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      const GLuint zValue = *((const GLuint *) value);      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x + i, y, z, &zValue);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      const GLuint zValue = *((const GLuint *) value);      const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x + i, y, z, &flt);         }      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row");   }}static voidtexture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,                   const GLint x[], const GLint y[], const void *values,                   const GLubyte *mask){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   if (rb->DataType == CHAN_TYPE) {      const GLchan *rgba = (const GLchan *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);         }         rgba += 4;      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      const GLuint *zValues = (const GLuint *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z,		       zValues + i);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      const GLuint *zValues = (const GLuint *) values;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            GLfloat flt = (zValues[i] >> 8) * (1.0 / 0xffffff);            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);         }      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_put_values");   }}static voidtexture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,                        GLuint count, const GLint x[], const GLint y[],                        const void *value, const GLubyte *mask){   const struct texture_renderbuffer *trb      = (const struct texture_renderbuffer *) rb;   const GLint z = trb->Zoffset;   GLuint i;   if (rb->DataType == CHAN_TYPE) {      const GLchan *rgba = (const GLchan *) value;      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT) {      const GLuint zValue = *((const GLuint *) value);      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue);         }      }   }   else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) {      const GLuint zValue = *((const GLuint *) value);      const GLfloat flt = (zValue >> 8) * (1.0 / 0xffffff);      for (i = 0; i < count; i++) {         if (!mask || mask[i]) {            trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt);         }      }   }   else {      _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values");   }}static voiddelete_texture_wrapper(struct gl_renderbuffer *rb){   ASSERT(rb->RefCount == 0);   _mesa_free(rb);}/** * This function creates a renderbuffer object which wraps a texture image. * The new renderbuffer is plugged into the given attachment point. * This allows rendering into the texture as if it were a renderbuffer. */static voidwrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att){   struct texture_renderbuffer *trb;   const GLuint name = 0;   ASSERT(att->Type == GL_TEXTURE);   ASSERT(att->Renderbuffer == NULL);   trb = CALLOC_STRUCT(texture_renderbuffer);   if (!trb) {      _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");      return;   }   /* init base gl_renderbuffer fields */   _mesa_init_renderbuffer(&trb->Base, name);   /* plug in our texture_renderbuffer-specific functions */   trb->Base.Delete = delete_texture_wrapper;   trb->Base.AllocStorage = NULL; /* illegal! */   trb->Base.GetRow = texture_get_row;   trb->Base.GetValues = texture_get_values;   trb->Base.PutRow = texture_put_row;   trb->Base.PutMonoRow = texture_put_mono_row;   trb->Base.PutValues = texture_put_values;   trb->Base.PutMonoValues = texture_put_mono_values;   /* update attachment point */   _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));}/** * Update the renderbuffer wrapper for rendering to a texture. * For example, update the width, height of the RB based on the texture size, * update the internal format info, etc. */static voidupdate_wrapper(GLcontext *ctx, const struct gl_renderbuffer_attachment *att){   struct texture_renderbuffer *trb      = (struct texture_renderbuffer *) att->Renderbuffer;   (void) ctx;   ASSERT(trb);   trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];   ASSERT(trb->TexImage);   trb->Store = trb->TexImage->TexFormat->StoreTexel;   ASSERT(trb->Store);   if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {      trb->Yoffset = att->Zoffset;      trb->Zoffset = 0;   }   else {      trb->Yoffset = 0;      trb->Zoffset = att->Zoffset;   }   trb->Base.Width = trb->TexImage->Width;   trb->Base.Height = trb->TexImage->Height;   trb->Base.InternalFormat = trb->TexImage->InternalFormat;   /* XXX may need more special cases here */   if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z24_S8) {      trb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;      trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;   }   else if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z16) {      trb->Base._ActualFormat = GL_DEPTH_COMPONENT;      trb->Base.DataType = GL_UNSIGNED_SHORT;   }   else if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z32) {      trb->Base._ActualFormat = GL_DEPTH_COMPONENT;      trb->Base.DataType = GL_UNSIGNED_INT;   }   else {      trb->Base._ActualFormat = trb->TexImage->InternalFormat;      trb->Base.DataType = CHAN_TYPE;   }   trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat;#if 0   /* fix/avoid this assertion someday */   ASSERT(trb->Base._BaseFormat == GL_RGB ||          trb->Base._BaseFormat == GL_RGBA ||          trb->Base._BaseFormat == GL_DEPTH_COMPONENT);#endif   trb->Base.Data = trb->TexImage->Data;   trb->Base.RedBits = trb->TexImage->TexFormat->RedBits;   trb->Base.GreenBits = trb->TexImage->TexFormat->GreenBits;   trb->Base.BlueBits = trb->TexImage->TexFormat->BlueBits;   trb->Base.AlphaBits = trb->TexImage->TexFormat->AlphaBits;   trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits;}/** * Called when rendering to a texture image begins, or when changing * the dest mipmap level, cube face, etc. * This is a fallback routine for software render-to-texture. * * Called via the glRenderbufferTexture1D/2D/3D() functions * and elsewhere (such as glTexImage2D). * * The image we're rendering into is * att->Texture->Image[att->CubeMapFace][att->TextureLevel]; * It'll never be NULL. * * \param fb  the framebuffer object the texture is being bound to * \param att  the fb attachment point of the texture * * \sa _mesa_framebuffer_renderbuffer */void_mesa_render_texture(GLcontext *ctx,                     struct gl_framebuffer *fb,                     struct gl_renderbuffer_attachment *att){   (void) fb;   if (!att->Renderbuffer) {      wrap_texture(ctx, att);   }   update_wrapper(ctx, att);}void_mesa_finish_render_texture(GLcontext *ctx,                            struct gl_renderbuffer_attachment *att){   /* do nothing */   /* The renderbuffer texture wrapper will get deleted by the    * normal mechanism for deleting renderbuffers.    */   (void) ctx;   (void) att;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -