winemac: Implement WGL_ARB_render_texture.
This commit is contained in:
parent
be7231bea3
commit
8bbf09b412
|
@ -72,6 +72,10 @@ struct wgl_pbuffer
|
|||
{
|
||||
CGLPBufferObj pbuffer;
|
||||
int format;
|
||||
BOOL no_texture;
|
||||
int max_level;
|
||||
GLint level;
|
||||
GLenum face;
|
||||
};
|
||||
|
||||
static CFMutableDictionaryRef dc_pbuffers;
|
||||
|
@ -1315,7 +1319,8 @@ static void make_context_current(struct wgl_context *context, BOOL read)
|
|||
macdrv_make_context_current(context->context, view);
|
||||
else
|
||||
{
|
||||
CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, 0, 0, 0);
|
||||
CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, pbuffer->face,
|
||||
pbuffer->level, 0);
|
||||
CGLSetCurrentContext(context->cglcontext);
|
||||
}
|
||||
}
|
||||
|
@ -1408,6 +1413,81 @@ static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_wglBindTexImageARB
|
||||
*
|
||||
* WGL_ARB_render_texture: wglBindTexImageARB
|
||||
*/
|
||||
static BOOL macdrv_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
|
||||
{
|
||||
struct wgl_context *context = NtCurrentTeb()->glContext;
|
||||
GLenum source;
|
||||
CGLError err;
|
||||
|
||||
TRACE("pbuffer %p iBuffer 0x%x\n", pbuffer, iBuffer);
|
||||
|
||||
if (pbuffer->no_texture)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (!context->draw_view && context->draw_pbuffer == pbuffer)
|
||||
opengl_funcs.gl.p_glFlush();
|
||||
|
||||
switch (iBuffer)
|
||||
{
|
||||
case WGL_FRONT_LEFT_ARB:
|
||||
if (pixel_formats[pbuffer->format].stereo)
|
||||
source = GL_FRONT_LEFT;
|
||||
else
|
||||
source = GL_FRONT;
|
||||
break;
|
||||
case WGL_FRONT_RIGHT_ARB:
|
||||
source = GL_FRONT_RIGHT;
|
||||
break;
|
||||
case WGL_BACK_LEFT_ARB:
|
||||
if (pixel_formats[pbuffer->format].stereo)
|
||||
source = GL_BACK_LEFT;
|
||||
else
|
||||
source = GL_BACK;
|
||||
break;
|
||||
case WGL_BACK_RIGHT_ARB:
|
||||
source = GL_BACK_RIGHT;
|
||||
break;
|
||||
case WGL_AUX0_ARB: source = GL_AUX0; break;
|
||||
case WGL_AUX1_ARB: source = GL_AUX1; break;
|
||||
case WGL_AUX2_ARB: source = GL_AUX2; break;
|
||||
case WGL_AUX3_ARB: source = GL_AUX3; break;
|
||||
|
||||
case WGL_AUX4_ARB:
|
||||
case WGL_AUX5_ARB:
|
||||
case WGL_AUX6_ARB:
|
||||
case WGL_AUX7_ARB:
|
||||
case WGL_AUX8_ARB:
|
||||
case WGL_AUX9_ARB:
|
||||
FIXME("unsupported source buffer 0x%x\n", iBuffer);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return GL_FALSE;
|
||||
|
||||
default:
|
||||
WARN("unknown source buffer 0x%x\n", iBuffer);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, source);
|
||||
if (err != kCGLNoError)
|
||||
{
|
||||
WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_wglChoosePixelFormatARB
|
||||
*
|
||||
|
@ -1623,9 +1703,13 @@ static BOOL macdrv_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,
|
|||
break;
|
||||
|
||||
case WGL_DRAW_TO_PBUFFER_ARB:
|
||||
case WGL_BIND_TO_TEXTURE_RGB_ARB:
|
||||
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
|
||||
if (valid.pbuffer && (!pf.pbuffer != !value)) goto cant_match;
|
||||
pf.pbuffer = (value != 0);
|
||||
valid.pbuffer = 1;
|
||||
if (attr == WGL_BIND_TO_TEXTURE_RGBA_ARB && !alpha_bits)
|
||||
alpha_bits = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1704,6 +1788,8 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
|
|||
const int *piAttribList)
|
||||
{
|
||||
struct wgl_pbuffer* pbuffer;
|
||||
GLenum target = 0;
|
||||
GLenum internalFormat = 0;
|
||||
CGLError err;
|
||||
|
||||
TRACE("hdc %p iPixelFormat %d iWidth %d iHeight %d piAttribList %p\n",
|
||||
|
@ -1730,6 +1816,70 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
|
|||
FIXME("WGL_PBUFFER_LARGEST_ARB: %d; ignoring\n", value);
|
||||
break;
|
||||
|
||||
case WGL_TEXTURE_FORMAT_ARB:
|
||||
switch (value)
|
||||
{
|
||||
case WGL_TEXTURE_RGBA_ARB:
|
||||
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGBA_ARB\n");
|
||||
internalFormat = GL_RGBA;
|
||||
break;
|
||||
case WGL_TEXTURE_RGB_ARB:
|
||||
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGB_ARB\n");
|
||||
internalFormat = GL_RGB;
|
||||
break;
|
||||
case WGL_NO_TEXTURE_ARB:
|
||||
TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_NO_TEXTURE_ARB\n");
|
||||
internalFormat = 0;
|
||||
break;
|
||||
default:
|
||||
WARN("unknown WGL_TEXTURE_FORMAT_ARB value 0x%x\n", value);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case WGL_TEXTURE_TARGET_ARB:
|
||||
pbuffer->face = 0;
|
||||
switch (value)
|
||||
{
|
||||
case WGL_NO_TEXTURE_ARB:
|
||||
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_NO_TEXTURE_ARB\n");
|
||||
target = 0;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_ARB:
|
||||
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_CUBE_MAP_ARB\n");
|
||||
target = GL_TEXTURE_CUBE_MAP;
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
break;
|
||||
case WGL_TEXTURE_1D_ARB:
|
||||
FIXME("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_1D_ARB; not supported\n");
|
||||
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
|
||||
goto done;
|
||||
case WGL_TEXTURE_2D_ARB:
|
||||
TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_2D_ARB\n");
|
||||
target = GL_TEXTURE_2D;
|
||||
break;
|
||||
default:
|
||||
WARN("unknown WGL_TEXTURE_TARGET_ARB value 0x%x\n", value);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case WGL_MIPMAP_TEXTURE_ARB:
|
||||
TRACE("WGL_MIPMAP_TEXTURE_ARB: %d\n", value);
|
||||
pbuffer->max_level = 0;
|
||||
if (value)
|
||||
{
|
||||
int size = min(iWidth, iHeight) / 2;
|
||||
while (size)
|
||||
{
|
||||
pbuffer->max_level++;
|
||||
size /= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("unknown attribute 0x%x\n", attr);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
|
@ -1737,7 +1887,15 @@ static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat,
|
|||
}
|
||||
}
|
||||
|
||||
err = CGLCreatePBuffer(iWidth, iHeight, GL_TEXTURE_RECTANGLE, GL_RGB, 0, &pbuffer->pbuffer);
|
||||
if (!target || !internalFormat)
|
||||
{
|
||||
pbuffer->no_texture = TRUE;
|
||||
/* no actual way to turn off ability to texture; use most permissive target */
|
||||
target = GL_TEXTURE_RECTANGLE;
|
||||
internalFormat = GL_RGB;
|
||||
}
|
||||
|
||||
err = CGLCreatePBuffer(iWidth, iHeight, target, internalFormat, pbuffer->max_level, &pbuffer->pbuffer);
|
||||
if (err != kCGLNoError)
|
||||
{
|
||||
WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err));
|
||||
|
@ -2085,9 +2243,14 @@ static BOOL macdrv_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int i
|
|||
break;
|
||||
|
||||
case WGL_DRAW_TO_PBUFFER_ARB:
|
||||
case WGL_BIND_TO_TEXTURE_RGB_ARB:
|
||||
piValues[i] = pf->pbuffer ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
|
||||
case WGL_BIND_TO_TEXTURE_RGBA_ARB:
|
||||
piValues[i] = (pf->pbuffer && color_modes[pf->color_mode].alpha_bits) ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
|
||||
case WGL_MAX_PBUFFER_WIDTH_ARB:
|
||||
piValues[i] = gl_info.max_viewport_dims[0];
|
||||
break;
|
||||
|
@ -2304,6 +2467,65 @@ static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribut
|
|||
/* Mac PBuffers can't be lost */
|
||||
*piValue = GL_FALSE;
|
||||
break;
|
||||
case WGL_TEXTURE_FORMAT_ARB:
|
||||
if (pbuffer->no_texture)
|
||||
*piValue = WGL_NO_TEXTURE_ARB;
|
||||
else switch (internalFormat)
|
||||
{
|
||||
case GL_RGBA:
|
||||
*piValue = WGL_TEXTURE_RGBA_ARB;
|
||||
break;
|
||||
case GL_RGB:
|
||||
default:
|
||||
*piValue = WGL_TEXTURE_RGB_ARB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WGL_TEXTURE_TARGET_ARB:
|
||||
if (pbuffer->no_texture)
|
||||
*piValue = WGL_NO_TEXTURE_ARB;
|
||||
else switch (target)
|
||||
{
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_RECTANGLE:
|
||||
default:
|
||||
*piValue = WGL_TEXTURE_2D_ARB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WGL_MIPMAP_TEXTURE_ARB:
|
||||
*piValue = (pbuffer->max_level > 0);
|
||||
break;
|
||||
case WGL_MIPMAP_LEVEL_ARB:
|
||||
*piValue = pbuffer->level;
|
||||
break;
|
||||
case WGL_CUBE_MAP_FACE_ARB:
|
||||
switch (pbuffer->face)
|
||||
{
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
||||
default:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
||||
*piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("invalid attribute 0x%x\n", iAttribute);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
|
@ -2344,6 +2566,104 @@ static int macdrv_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc)
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* macdrv_wglReleaseTexImageARB
|
||||
*
|
||||
* WGL_ARB_render_texture: wglReleaseTexImageARB
|
||||
*/
|
||||
static BOOL macdrv_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
|
||||
{
|
||||
struct wgl_context *context = NtCurrentTeb()->glContext;
|
||||
CGLError err;
|
||||
|
||||
TRACE("pbuffer %p iBuffer 0x%x; stub!\n", pbuffer, iBuffer);
|
||||
|
||||
if (pbuffer->no_texture)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, GL_NONE);
|
||||
if (err != kCGLNoError)
|
||||
{
|
||||
WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
|
||||
SetLastError(ERROR_INVALID_OPERATION);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* macdrv_wglSetPbufferAttribARB
|
||||
*
|
||||
* WGL_ARB_render_texture: wglSetPbufferAttribARB
|
||||
*/
|
||||
static BOOL macdrv_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *piAttribList)
|
||||
{
|
||||
struct wgl_context *context = NtCurrentTeb()->glContext;
|
||||
|
||||
TRACE("pbuffer %p piAttribList %p\n", pbuffer, piAttribList);
|
||||
|
||||
for ( ; piAttribList && *piAttribList; piAttribList += 2)
|
||||
{
|
||||
int attr = piAttribList[0];
|
||||
int value = piAttribList[1];
|
||||
switch (attr)
|
||||
{
|
||||
case WGL_MIPMAP_LEVEL_ARB:
|
||||
TRACE("WGL_MIPMAP_LEVEL_ARB: %d\n", value);
|
||||
pbuffer->level = value;
|
||||
break;
|
||||
case WGL_CUBE_MAP_FACE_ARB:
|
||||
switch (value)
|
||||
{
|
||||
case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
|
||||
break;
|
||||
case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
|
||||
TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\n");
|
||||
pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
||||
break;
|
||||
default:
|
||||
WARN("unknown WGL_CUBE_MAP_FACE_ARB value 0x%x\n", value);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return GL_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("invalide attribute 0x%x\n", attr);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (context && context->draw_pbuffer == pbuffer)
|
||||
make_context_current(context, FALSE);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* macdrv_wglSetPixelFormatWINE
|
||||
*
|
||||
|
@ -2401,6 +2721,11 @@ static void load_extensions(void)
|
|||
opengl_funcs.ext.p_wglGetPbufferDCARB = macdrv_wglGetPbufferDCARB;
|
||||
opengl_funcs.ext.p_wglQueryPbufferARB = macdrv_wglQueryPbufferARB;
|
||||
opengl_funcs.ext.p_wglReleasePbufferDCARB = macdrv_wglReleasePbufferDCARB;
|
||||
|
||||
register_extension("WGL_ARB_render_texture");
|
||||
opengl_funcs.ext.p_wglBindTexImageARB = macdrv_wglBindTexImageARB;
|
||||
opengl_funcs.ext.p_wglReleaseTexImageARB = macdrv_wglReleaseTexImageARB;
|
||||
opengl_funcs.ext.p_wglSetPbufferAttribARB = macdrv_wglSetPbufferAttribARB;
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
|
|
Loading…
Reference in New Issue