Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentexrender.c
Go to the documentation of this file.
00001 00002 #include "context.h" 00003 #include "fbobject.h" 00004 #include "texformat.h" 00005 #include "texrender.h" 00006 #include "renderbuffer.h" 00007 00008 00009 /* 00010 * Render-to-texture code for GL_EXT_framebuffer_object 00011 */ 00012 00013 00017 struct texture_renderbuffer 00018 { 00019 struct gl_renderbuffer Base; 00020 struct gl_texture_image *TexImage; 00021 StoreTexelFunc Store; 00022 GLint Yoffset; 00023 GLint Zoffset; 00026 }; 00027 00028 00032 static void 00033 texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00034 GLint x, GLint y, void *values) 00035 { 00036 const struct texture_renderbuffer *trb 00037 = (const struct texture_renderbuffer *) rb; 00038 const GLint z = trb->Zoffset; 00039 GLuint i; 00040 00041 ASSERT(trb->TexImage->Width == rb->Width); 00042 ASSERT(trb->TexImage->Height == rb->Height); 00043 00044 y += trb->Yoffset; 00045 00046 if (rb->DataType == CHAN_TYPE) { 00047 GLchan *rgbaOut = (GLchan *) values; 00048 for (i = 0; i < count; i++) { 00049 trb->TexImage->FetchTexelc(trb->TexImage, x + i, y, z, rgbaOut + 4 * i); 00050 } 00051 } 00052 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00053 GLushort *zValues = (GLushort *) values; 00054 for (i = 0; i < count; i++) { 00055 GLfloat flt; 00056 trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt); 00057 zValues[i] = (GLushort) (flt * 0xffff); 00058 } 00059 } 00060 else if (rb->DataType == GL_UNSIGNED_INT) { 00061 GLuint *zValues = (GLuint *) values; 00062 /* 00063 const GLdouble scale = (GLdouble) 0xffffffff; 00064 */ 00065 for (i = 0; i < count; i++) { 00066 GLfloat flt; 00067 trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt); 00068 #if 0 00069 /* this should work, but doesn't (overflow due to low precision) */ 00070 zValues[i] = (GLuint) (flt * scale); 00071 #else 00072 /* temporary hack */ 00073 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; 00074 #endif 00075 } 00076 } 00077 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00078 GLuint *zValues = (GLuint *) values; 00079 for (i = 0; i < count; i++) { 00080 GLfloat flt; 00081 trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt); 00082 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; 00083 } 00084 } 00085 else { 00086 _mesa_problem(ctx, "invalid rb->DataType in texture_get_row"); 00087 } 00088 } 00089 00090 00091 static void 00092 texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00093 const GLint x[], const GLint y[], void *values) 00094 { 00095 const struct texture_renderbuffer *trb 00096 = (const struct texture_renderbuffer *) rb; 00097 const GLint z = trb->Zoffset; 00098 GLuint i; 00099 00100 if (rb->DataType == CHAN_TYPE) { 00101 GLchan *rgbaOut = (GLchan *) values; 00102 for (i = 0; i < count; i++) { 00103 trb->TexImage->FetchTexelc(trb->TexImage, x[i], y[i] + trb->Yoffset, 00104 z, rgbaOut + 4 * i); 00105 } 00106 } 00107 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00108 GLushort *zValues = (GLushort *) values; 00109 for (i = 0; i < count; i++) { 00110 GLfloat flt; 00111 trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset, 00112 z, &flt); 00113 zValues[i] = (GLushort) (flt * 0xffff); 00114 } 00115 } 00116 else if (rb->DataType == GL_UNSIGNED_INT) { 00117 GLuint *zValues = (GLuint *) values; 00118 for (i = 0; i < count; i++) { 00119 GLfloat flt; 00120 trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset, 00121 z, &flt); 00122 #if 0 00123 zValues[i] = (GLuint) (flt * 0xffffffff); 00124 #else 00125 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; 00126 #endif 00127 } 00128 } 00129 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00130 GLuint *zValues = (GLuint *) values; 00131 for (i = 0; i < count; i++) { 00132 GLfloat flt; 00133 trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset, 00134 z, &flt); 00135 zValues[i] = ((GLuint) (flt * 0xffffff)) << 8; 00136 } 00137 } 00138 else { 00139 _mesa_problem(ctx, "invalid rb->DataType in texture_get_values"); 00140 } 00141 } 00142 00143 00147 static void 00148 texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00149 GLint x, GLint y, const void *values, const GLubyte *mask) 00150 { 00151 const struct texture_renderbuffer *trb 00152 = (const struct texture_renderbuffer *) rb; 00153 const GLint z = trb->Zoffset; 00154 GLuint i; 00155 00156 y += trb->Yoffset; 00157 00158 if (rb->DataType == CHAN_TYPE) { 00159 const GLchan *rgba = (const GLchan *) values; 00160 for (i = 0; i < count; i++) { 00161 if (!mask || mask[i]) { 00162 trb->Store(trb->TexImage, x + i, y, z, rgba); 00163 } 00164 rgba += 4; 00165 } 00166 } 00167 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00168 const GLushort *zValues = (const GLushort *) values; 00169 for (i = 0; i < count; i++) { 00170 if (!mask || mask[i]) { 00171 trb->Store(trb->TexImage, x + i, y, z, zValues + i); 00172 } 00173 } 00174 } 00175 else if (rb->DataType == GL_UNSIGNED_INT) { 00176 const GLuint *zValues = (const GLuint *) values; 00177 for (i = 0; i < count; i++) { 00178 if (!mask || mask[i]) { 00179 trb->Store(trb->TexImage, x + i, y, z, zValues + i); 00180 } 00181 } 00182 } 00183 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00184 const GLuint *zValues = (const GLuint *) values; 00185 for (i = 0; i < count; i++) { 00186 if (!mask || mask[i]) { 00187 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff)); 00188 trb->Store(trb->TexImage, x + i, y, z, &flt); 00189 } 00190 } 00191 } 00192 else { 00193 _mesa_problem(ctx, "invalid rb->DataType in texture_put_row"); 00194 } 00195 } 00196 00200 static void 00201 texture_put_row_rgb(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00202 GLint x, GLint y, const void *values, const GLubyte *mask) 00203 { 00204 const struct texture_renderbuffer *trb 00205 = (const struct texture_renderbuffer *) rb; 00206 const GLint z = trb->Zoffset; 00207 GLuint i; 00208 00209 y += trb->Yoffset; 00210 00211 if (rb->DataType == CHAN_TYPE) { 00212 const GLchan *rgb = (const GLchan *) values; 00213 for (i = 0; i < count; i++) { 00214 if (!mask || mask[i]) { 00215 trb->Store(trb->TexImage, x + i, y, z, rgb); 00216 } 00217 rgb += 3; 00218 } 00219 } 00220 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00221 const GLushort *zValues = (const GLushort *) values; 00222 for (i = 0; i < count; i++) { 00223 if (!mask || mask[i]) { 00224 trb->Store(trb->TexImage, x + i, y, z, zValues + i); 00225 } 00226 } 00227 } 00228 else if (rb->DataType == GL_UNSIGNED_INT) { 00229 const GLuint *zValues = (const GLuint *) values; 00230 for (i = 0; i < count; i++) { 00231 if (!mask || mask[i]) { 00232 trb->Store(trb->TexImage, x + i, y, z, zValues + i); 00233 } 00234 } 00235 } 00236 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00237 const GLuint *zValues = (const GLuint *) values; 00238 for (i = 0; i < count; i++) { 00239 if (!mask || mask[i]) { 00240 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff)); 00241 trb->Store(trb->TexImage, x + i, y, z, &flt); 00242 } 00243 } 00244 } 00245 else { 00246 _mesa_problem(ctx, "invalid rb->DataType in texture_put_row"); 00247 } 00248 } 00249 00250 00251 static void 00252 texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00253 GLint x, GLint y, const void *value, const GLubyte *mask) 00254 { 00255 const struct texture_renderbuffer *trb 00256 = (const struct texture_renderbuffer *) rb; 00257 const GLint z = trb->Zoffset; 00258 GLuint i; 00259 00260 y += trb->Yoffset; 00261 00262 if (rb->DataType == CHAN_TYPE) { 00263 const GLchan *rgba = (const GLchan *) value; 00264 for (i = 0; i < count; i++) { 00265 if (!mask || mask[i]) { 00266 trb->Store(trb->TexImage, x + i, y, z, rgba); 00267 } 00268 } 00269 } 00270 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00271 const GLushort zValue = *((const GLushort *) value); 00272 for (i = 0; i < count; i++) { 00273 if (!mask || mask[i]) { 00274 trb->Store(trb->TexImage, x + i, y, z, &zValue); 00275 } 00276 } 00277 } 00278 else if (rb->DataType == GL_UNSIGNED_INT) { 00279 const GLuint zValue = *((const GLuint *) value); 00280 for (i = 0; i < count; i++) { 00281 if (!mask || mask[i]) { 00282 trb->Store(trb->TexImage, x + i, y, z, &zValue); 00283 } 00284 } 00285 } 00286 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00287 const GLuint zValue = *((const GLuint *) value); 00288 const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff)); 00289 for (i = 0; i < count; i++) { 00290 if (!mask || mask[i]) { 00291 trb->Store(trb->TexImage, x + i, y, z, &flt); 00292 } 00293 } 00294 } 00295 else { 00296 _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_row"); 00297 } 00298 } 00299 00300 00301 static void 00302 texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, 00303 const GLint x[], const GLint y[], const void *values, 00304 const GLubyte *mask) 00305 { 00306 const struct texture_renderbuffer *trb 00307 = (const struct texture_renderbuffer *) rb; 00308 const GLint z = trb->Zoffset; 00309 GLuint i; 00310 00311 if (rb->DataType == CHAN_TYPE) { 00312 const GLchan *rgba = (const GLchan *) values; 00313 for (i = 0; i < count; i++) { 00314 if (!mask || mask[i]) { 00315 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba); 00316 } 00317 rgba += 4; 00318 } 00319 } 00320 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00321 const GLushort *zValues = (const GLushort *) values; 00322 for (i = 0; i < count; i++) { 00323 if (!mask || mask[i]) { 00324 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i); 00325 } 00326 } 00327 } 00328 else if (rb->DataType == GL_UNSIGNED_INT) { 00329 const GLuint *zValues = (const GLuint *) values; 00330 for (i = 0; i < count; i++) { 00331 if (!mask || mask[i]) { 00332 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, zValues + i); 00333 } 00334 } 00335 } 00336 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00337 const GLuint *zValues = (const GLuint *) values; 00338 for (i = 0; i < count; i++) { 00339 if (!mask || mask[i]) { 00340 GLfloat flt = (GLfloat) ((zValues[i] >> 8) * (1.0 / 0xffffff)); 00341 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); 00342 } 00343 } 00344 } 00345 else { 00346 _mesa_problem(ctx, "invalid rb->DataType in texture_put_values"); 00347 } 00348 } 00349 00350 00351 static void 00352 texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb, 00353 GLuint count, const GLint x[], const GLint y[], 00354 const void *value, const GLubyte *mask) 00355 { 00356 const struct texture_renderbuffer *trb 00357 = (const struct texture_renderbuffer *) rb; 00358 const GLint z = trb->Zoffset; 00359 GLuint i; 00360 00361 if (rb->DataType == CHAN_TYPE) { 00362 const GLchan *rgba = (const GLchan *) value; 00363 for (i = 0; i < count; i++) { 00364 if (!mask || mask[i]) { 00365 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, rgba); 00366 } 00367 } 00368 } 00369 else if (rb->DataType == GL_UNSIGNED_INT) { 00370 const GLuint zValue = *((const GLuint *) value); 00371 for (i = 0; i < count; i++) { 00372 if (!mask || mask[i]) { 00373 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue); 00374 } 00375 } 00376 } 00377 else if (rb->DataType == GL_UNSIGNED_SHORT) { 00378 const GLushort zValue = *((const GLushort *) value); 00379 for (i = 0; i < count; i++) { 00380 if (!mask || mask[i]) { 00381 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &zValue); 00382 } 00383 } 00384 } 00385 else if (rb->DataType == GL_UNSIGNED_INT_24_8_EXT) { 00386 const GLuint zValue = *((const GLuint *) value); 00387 const GLfloat flt = (GLfloat) ((zValue >> 8) * (1.0 / 0xffffff)); 00388 for (i = 0; i < count; i++) { 00389 if (!mask || mask[i]) { 00390 trb->Store(trb->TexImage, x[i], y[i] + trb->Yoffset, z, &flt); 00391 } 00392 } 00393 } 00394 else { 00395 _mesa_problem(ctx, "invalid rb->DataType in texture_put_mono_values"); 00396 } 00397 } 00398 00399 00400 static void 00401 delete_texture_wrapper(struct gl_renderbuffer *rb) 00402 { 00403 ASSERT(rb->RefCount == 0); 00404 _mesa_free(rb); 00405 } 00406 00407 00413 static void 00414 wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att) 00415 { 00416 struct texture_renderbuffer *trb; 00417 const GLuint name = 0; 00418 00419 ASSERT(att->Type == GL_TEXTURE); 00420 ASSERT(att->Renderbuffer == NULL); 00421 00422 trb = CALLOC_STRUCT(texture_renderbuffer); 00423 if (!trb) { 00424 _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture"); 00425 return; 00426 } 00427 00428 /* init base gl_renderbuffer fields */ 00429 _mesa_init_renderbuffer(&trb->Base, name); 00430 /* plug in our texture_renderbuffer-specific functions */ 00431 trb->Base.Delete = delete_texture_wrapper; 00432 trb->Base.AllocStorage = NULL; /* illegal! */ 00433 trb->Base.GetRow = texture_get_row; 00434 trb->Base.GetValues = texture_get_values; 00435 trb->Base.PutRow = texture_put_row; 00436 trb->Base.PutRowRGB = texture_put_row_rgb; 00437 trb->Base.PutMonoRow = texture_put_mono_row; 00438 trb->Base.PutValues = texture_put_values; 00439 trb->Base.PutMonoValues = texture_put_mono_values; 00440 00441 /* update attachment point */ 00442 _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base)); 00443 } 00444 00445 00446 00452 static void 00453 update_wrapper(GLcontext *ctx, const struct gl_renderbuffer_attachment *att) 00454 { 00455 struct texture_renderbuffer *trb 00456 = (struct texture_renderbuffer *) att->Renderbuffer; 00457 00458 (void) ctx; 00459 ASSERT(trb); 00460 00461 trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 00462 ASSERT(trb->TexImage); 00463 00464 trb->Store = trb->TexImage->TexFormat->StoreTexel; 00465 ASSERT(trb->Store); 00466 00467 if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) { 00468 trb->Yoffset = att->Zoffset; 00469 trb->Zoffset = 0; 00470 } 00471 else { 00472 trb->Yoffset = 0; 00473 trb->Zoffset = att->Zoffset; 00474 } 00475 00476 trb->Base.Width = trb->TexImage->Width; 00477 trb->Base.Height = trb->TexImage->Height; 00478 trb->Base.InternalFormat = trb->TexImage->InternalFormat; 00479 /* XXX may need more special cases here */ 00480 if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z24_S8) { 00481 trb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; 00482 trb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; 00483 } 00484 else if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z16) { 00485 trb->Base._ActualFormat = GL_DEPTH_COMPONENT; 00486 trb->Base.DataType = GL_UNSIGNED_SHORT; 00487 } 00488 else if (trb->TexImage->TexFormat->MesaFormat == MESA_FORMAT_Z32) { 00489 trb->Base._ActualFormat = GL_DEPTH_COMPONENT; 00490 trb->Base.DataType = GL_UNSIGNED_INT; 00491 } 00492 else { 00493 trb->Base._ActualFormat = trb->TexImage->InternalFormat; 00494 trb->Base.DataType = CHAN_TYPE; 00495 } 00496 trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat; 00497 #if 0 00498 /* fix/avoid this assertion someday */ 00499 ASSERT(trb->Base._BaseFormat == GL_RGB || 00500 trb->Base._BaseFormat == GL_RGBA || 00501 trb->Base._BaseFormat == GL_DEPTH_COMPONENT); 00502 #endif 00503 trb->Base.Data = trb->TexImage->Data; 00504 00505 trb->Base.RedBits = trb->TexImage->TexFormat->RedBits; 00506 trb->Base.GreenBits = trb->TexImage->TexFormat->GreenBits; 00507 trb->Base.BlueBits = trb->TexImage->TexFormat->BlueBits; 00508 trb->Base.AlphaBits = trb->TexImage->TexFormat->AlphaBits; 00509 trb->Base.DepthBits = trb->TexImage->TexFormat->DepthBits; 00510 } 00511 00512 00513 00531 void 00532 _mesa_render_texture(GLcontext *ctx, 00533 struct gl_framebuffer *fb, 00534 struct gl_renderbuffer_attachment *att) 00535 { 00536 (void) fb; 00537 00538 if (!att->Renderbuffer) { 00539 wrap_texture(ctx, att); 00540 } 00541 update_wrapper(ctx, att); 00542 } 00543 00544 00545 void 00546 _mesa_finish_render_texture(GLcontext *ctx, 00547 struct gl_renderbuffer_attachment *att) 00548 { 00549 /* do nothing */ 00550 /* The renderbuffer texture wrapper will get deleted by the 00551 * normal mechanism for deleting renderbuffers. 00552 */ 00553 (void) ctx; 00554 (void) att; 00555 } Generated on Tue May 22 2012 04:24:14 for ReactOS by
1.7.6.1
|