wined3d: Move the stream source binding code to context.c.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5c2522d713
commit
437861f1dc
|
@ -4987,6 +4987,527 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
|
|||
context_release(context);
|
||||
}
|
||||
|
||||
void context_unload_tex_coords(const struct wined3d_context *context)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
unsigned int texture_idx;
|
||||
|
||||
for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
|
||||
{
|
||||
gl_info->gl_ops.ext.p_glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx);
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
|
||||
GLuint *current_bo, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
unsigned int mapped_stage = 0;
|
||||
unsigned int texture_idx;
|
||||
|
||||
for (texture_idx = 0; texture_idx < context->d3d_info->limits.ffp_blend_stages; ++texture_idx)
|
||||
{
|
||||
unsigned int coord_idx = state->texture_states[texture_idx][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
|
||||
if ((mapped_stage = context->tex_unit_map[texture_idx]) == WINED3D_UNMAPPED_STAGE)
|
||||
continue;
|
||||
|
||||
if (mapped_stage >= gl_info->limits.texture_coords)
|
||||
{
|
||||
FIXME("Attempted to load unsupported texture coordinate %u.\n", mapped_stage);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coord_idx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
|
||||
{
|
||||
const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx];
|
||||
|
||||
TRACE("Setting up texture %u, idx %d, coord_idx %u, data {%#x:%p}.\n",
|
||||
texture_idx, mapped_stage, coord_idx, e->data.buffer_object, e->data.addr);
|
||||
|
||||
if (*current_bo != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
*current_bo = e->data.buffer_object;
|
||||
}
|
||||
|
||||
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
|
||||
checkGLcall("glClientActiveTextureARB");
|
||||
|
||||
/* The coords to supply depend completely on the fvf/vertex shader. */
|
||||
gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
if (gl_info->supported[NV_REGISTER_COMBINERS])
|
||||
{
|
||||
/* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
|
||||
for (texture_idx = mapped_stage + 1; texture_idx < gl_info->limits.textures; ++texture_idx)
|
||||
{
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
checkGLcall("loadTexCoords");
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in context_load_vertex_data().
|
||||
* TODO: Only load/unload arrays if we have to. */
|
||||
static void context_unload_vertex_data(const struct wined3d_context *context)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
||||
context_unload_tex_coords(context);
|
||||
}
|
||||
|
||||
static void context_load_vertex_data(struct wined3d_context *context,
|
||||
const struct wined3d_stream_info *si, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
const struct wined3d_stream_info_element *e;
|
||||
GLuint current_bo;
|
||||
|
||||
TRACE("context %p, si %p, state %p.\n", context, si, state);
|
||||
|
||||
/* This is used for the fixed-function pipeline only, and the
|
||||
* fixed-function pipeline doesn't do instancing. */
|
||||
context->instance_count = 0;
|
||||
current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
|
||||
|
||||
/* Blend data */
|
||||
if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
|
||||
|| si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
|
||||
{
|
||||
/* TODO: Support vertex blending in immediate mode draws. No need to
|
||||
* write a FIXME here, this is done after the general vertex
|
||||
* declaration decoding. */
|
||||
WARN("Vertex blending not supported.\n");
|
||||
}
|
||||
|
||||
/* Point Size */
|
||||
if (si->use_map & (1u << WINED3D_FFP_PSIZE))
|
||||
{
|
||||
/* No such functionality in the fixed-function GL pipeline. */
|
||||
WARN("Per-vertex point size not supported.\n");
|
||||
}
|
||||
|
||||
/* Position */
|
||||
if (si->use_map & (1u << WINED3D_FFP_POSITION))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_POSITION];
|
||||
|
||||
if (current_bo != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
current_bo = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
|
||||
e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glVertexPointer(...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
|
||||
}
|
||||
|
||||
/* Normals */
|
||||
if (si->use_map & (1u << WINED3D_FFP_NORMAL))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_NORMAL];
|
||||
|
||||
if (current_bo != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
current_bo = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glNormalPointer(...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
|
||||
checkGLcall("glNormal3f(0, 0, 0)");
|
||||
}
|
||||
|
||||
/* Diffuse colour */
|
||||
if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_DIFFUSE];
|
||||
|
||||
if (current_bo != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
current_bo = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
|
||||
e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
checkGLcall("glColor4f(1, 1, 1, 1)");
|
||||
}
|
||||
|
||||
/* Specular colour */
|
||||
if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
|
||||
{
|
||||
TRACE("Setting specular colour.\n");
|
||||
|
||||
e = &si->elements[WINED3D_FFP_SPECULAR];
|
||||
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
{
|
||||
GLenum type = e->format->gl_vtx_type;
|
||||
GLint format = e->format->gl_vtx_format;
|
||||
|
||||
if (current_bo != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
current_bo = e->data.buffer_object;
|
||||
}
|
||||
|
||||
if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
|
||||
{
|
||||
/* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
|
||||
* contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
|
||||
* vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
|
||||
* 4 component secondary colors use it
|
||||
*/
|
||||
TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE:
|
||||
TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Add 4 component specular colour pointers for type %#x.\n", type);
|
||||
/* Make sure that the right colour component is dropped. */
|
||||
TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
|
||||
}
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
||||
checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Specular colour is not supported in this GL implementation.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
{
|
||||
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
|
||||
checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Specular colour is not supported in this GL implementation.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture coordinates */
|
||||
context_load_tex_coords(context, si, ¤t_bo, state);
|
||||
}
|
||||
|
||||
static void context_unload_numbered_array(struct wined3d_context *context, unsigned int i)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
GL_EXTCALL(glDisableVertexAttribArray(i));
|
||||
checkGLcall("glDisableVertexAttribArray");
|
||||
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
|
||||
GL_EXTCALL(glVertexAttribDivisor(i, 0));
|
||||
|
||||
context->numbered_array_mask &= ~(1u << i);
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in loadNumberedArrays.
|
||||
* TODO: Only load / unload arrays if we have to. */
|
||||
static void context_unload_numbered_arrays(struct wined3d_context *context)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Disable any attributes. */
|
||||
for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i)
|
||||
{
|
||||
context_unload_numbered_array(context, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void context_load_numbered_arrays(struct wined3d_context *context,
|
||||
const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
GLuint current_bo;
|
||||
unsigned int i;
|
||||
|
||||
/* Default to no instancing. */
|
||||
context->instance_count = 0;
|
||||
current_bo = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0u : 0;
|
||||
|
||||
for (i = 0; i < MAX_ATTRIBS; ++i)
|
||||
{
|
||||
const struct wined3d_stream_info_element *element = &stream_info->elements[i];
|
||||
const struct wined3d_stream_state *stream;
|
||||
|
||||
if (!(stream_info->use_map & (1u << i)))
|
||||
{
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
context_unload_numbered_array(context, i);
|
||||
if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE)
|
||||
GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f));
|
||||
else
|
||||
GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
|
||||
continue;
|
||||
}
|
||||
|
||||
stream = &state->streams[element->stream_idx];
|
||||
|
||||
if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
|
||||
context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
|
||||
|
||||
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribDivisor(i, element->divisor));
|
||||
}
|
||||
else if (element->divisor)
|
||||
{
|
||||
/* Unload instanced arrays, they will be loaded using immediate
|
||||
* mode instead. */
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
context_unload_numbered_array(context, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE("Loading array %u [VBO=%u].\n", i, element->data.buffer_object);
|
||||
|
||||
if (element->stride)
|
||||
{
|
||||
if (current_bo != element->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
current_bo = element->data.buffer_object;
|
||||
}
|
||||
/* Use the VBO to find out if a vertex buffer exists, not the vb
|
||||
* pointer. vb can point to a user pointer data blob. In that case
|
||||
* current_bo will be 0. If there is a vertex buffer but no vbo we
|
||||
* won't be load converted attributes anyway. */
|
||||
if (vs && vs->reg_maps.shader_version.major >= 4
|
||||
&& (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER))
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
|
||||
element->stride, element->data.addr + state->load_base_vertex_index * element->stride));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
|
||||
element->format->gl_normalized, element->stride,
|
||||
element->data.addr + state->load_base_vertex_index * element->stride));
|
||||
}
|
||||
|
||||
if (!(context->numbered_array_mask & (1u << i)))
|
||||
{
|
||||
GL_EXTCALL(glEnableVertexAttribArray(i));
|
||||
context->numbered_array_mask |= (1u << i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stride = 0 means always the same values.
|
||||
* glVertexAttribPointer() doesn't do that. Instead disable the
|
||||
* pointer and set up the attribute statically. But we have to
|
||||
* figure out the system memory address. */
|
||||
const BYTE *ptr = element->data.addr;
|
||||
if (element->data.buffer_object)
|
||||
ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context);
|
||||
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
context_unload_numbered_array(context, i);
|
||||
|
||||
switch (element->format->id)
|
||||
{
|
||||
case WINED3DFMT_R32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R8G8B8A8_UINT:
|
||||
GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
|
||||
break;
|
||||
case WINED3DFMT_B8G8R8A8_UNORM:
|
||||
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
|
||||
{
|
||||
const DWORD *src = (const DWORD *)ptr;
|
||||
DWORD c = *src & 0xff00ff00u;
|
||||
c |= (*src & 0xff0000u) >> 16;
|
||||
c |= (*src & 0xffu) << 16;
|
||||
GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
|
||||
break;
|
||||
}
|
||||
/* else fallthrough */
|
||||
case WINED3DFMT_R8G8B8A8_UNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16_SINT:
|
||||
GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_SINT:
|
||||
GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16_SNORM:
|
||||
{
|
||||
const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
|
||||
GL_EXTCALL(glVertexAttrib4Nsv(i, s));
|
||||
break;
|
||||
}
|
||||
case WINED3DFMT_R16G16_UNORM:
|
||||
{
|
||||
const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
|
||||
GL_EXTCALL(glVertexAttrib4Nusv(i, s));
|
||||
break;
|
||||
}
|
||||
case WINED3DFMT_R16G16B16A16_SNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_UNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R10G10B10X2_UINT:
|
||||
FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n");
|
||||
/*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
|
||||
break;
|
||||
case WINED3DFMT_R10G10B10X2_SNORM:
|
||||
FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n");
|
||||
/*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
|
||||
break;
|
||||
case WINED3DFMT_R16G16_FLOAT:
|
||||
if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
|
||||
{
|
||||
/* Not supported by GL_ARB_half_float_vertex. */
|
||||
GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
||||
GL_EXTCALL(glVertexAttrib2f(i, x, y));
|
||||
}
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_FLOAT:
|
||||
if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
|
||||
{
|
||||
/* Not supported by GL_ARB_half_float_vertex. */
|
||||
GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
||||
float z = float_16_to_32(((const unsigned short *)ptr) + 2);
|
||||
float w = float_16_to_32(((const unsigned short *)ptr) + 3);
|
||||
GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("Unexpected declaration in stride 0 attributes.\n");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
checkGLcall("Loading numbered arrays");
|
||||
}
|
||||
|
||||
void context_update_stream_sources(struct wined3d_context *context, const struct wined3d_state *state)
|
||||
{
|
||||
BOOL load_numbered = context->d3d_info->ffp_generic_attributes
|
||||
|| (use_vs(state) && !context->use_immediate_mode_draw);
|
||||
BOOL load_named = !context->d3d_info->ffp_generic_attributes
|
||||
&& !use_vs(state) && !context->use_immediate_mode_draw;
|
||||
|
||||
if (context->numbered_array_mask && !load_numbered)
|
||||
{
|
||||
context_unload_numbered_arrays(context);
|
||||
context->numbered_array_mask = 0;
|
||||
}
|
||||
else if (context->namedArraysLoaded)
|
||||
{
|
||||
context_unload_vertex_data(context);
|
||||
context->namedArraysLoaded = FALSE;
|
||||
}
|
||||
|
||||
if (load_numbered)
|
||||
{
|
||||
TRACE("Loading numbered arrays.\n");
|
||||
context_load_numbered_arrays(context, &context->stream_info, state);
|
||||
}
|
||||
else if (load_named)
|
||||
{
|
||||
TRACE("Loading vertex data.\n");
|
||||
context_load_vertex_data(context, &context->stream_info, state);
|
||||
context->namedArraysLoaded = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, struct gl_texture *texture,
|
||||
GLenum target, unsigned int level, enum wined3d_texture_filter_type filter)
|
||||
{
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
ULONG CDECL wined3d_blend_state_incref(struct wined3d_blend_state *state)
|
||||
{
|
||||
|
@ -3303,76 +3302,6 @@ static void transform_texture(struct wined3d_context *context, const struct wine
|
|||
checkGLcall("glLoadMatrixf");
|
||||
}
|
||||
|
||||
static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
unsigned int texture_idx;
|
||||
|
||||
for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
|
||||
{
|
||||
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
|
||||
GLuint *curVBO, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
unsigned int mapped_stage = 0;
|
||||
unsigned int textureNo;
|
||||
|
||||
for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
|
||||
{
|
||||
int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
|
||||
|
||||
mapped_stage = context->tex_unit_map[textureNo];
|
||||
if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
|
||||
|
||||
if (mapped_stage >= gl_info->limits.texture_coords)
|
||||
{
|
||||
FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coordIdx < MAX_TEXTURES && (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
|
||||
{
|
||||
const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
|
||||
|
||||
TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
|
||||
textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
|
||||
|
||||
if (*curVBO != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
*curVBO = e->data.buffer_object;
|
||||
}
|
||||
|
||||
GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
|
||||
checkGLcall("glClientActiveTextureARB");
|
||||
|
||||
/* The coords to supply depend completely on the fvf / vertex shader */
|
||||
gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
if (gl_info->supported[NV_REGISTER_COMBINERS])
|
||||
{
|
||||
/* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
|
||||
for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
|
||||
{
|
||||
GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
checkGLcall("loadTexCoords");
|
||||
}
|
||||
|
||||
static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
|
||||
|
@ -3543,8 +3472,8 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d
|
|||
*/
|
||||
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
|
||||
|
||||
unload_tex_coords(gl_info);
|
||||
load_tex_coords(context, &context->stream_info, &curVBO, state);
|
||||
context_unload_tex_coords(context);
|
||||
context_load_tex_coords(context, &context->stream_info, &curVBO, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3916,465 +3845,18 @@ static void transform_projection(struct wined3d_context *context, const struct w
|
|||
checkGLcall("glLoadMatrixf");
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in load_vertex_data.
|
||||
* TODO: Only load / unload arrays if we have to. */
|
||||
static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
||||
unload_tex_coords(gl_info);
|
||||
}
|
||||
|
||||
static inline void unload_numbered_array(struct wined3d_context *context, int i)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
GL_EXTCALL(glDisableVertexAttribArray(i));
|
||||
checkGLcall("glDisableVertexAttribArray");
|
||||
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
|
||||
GL_EXTCALL(glVertexAttribDivisor(i, 0));
|
||||
|
||||
context->numbered_array_mask &= ~(1u << i);
|
||||
}
|
||||
|
||||
/* This should match any arrays loaded in loadNumberedArrays
|
||||
* TODO: Only load / unload arrays if we have to. */
|
||||
static void unload_numbered_arrays(struct wined3d_context *context)
|
||||
{
|
||||
/* disable any attribs (this is the same for both GLSL and ARB modes) */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
|
||||
unload_numbered_array(context, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void load_numbered_arrays(struct wined3d_context *context,
|
||||
const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
|
||||
unsigned int i;
|
||||
|
||||
/* Default to no instancing */
|
||||
context->instance_count = 0;
|
||||
|
||||
for (i = 0; i < MAX_ATTRIBS; ++i)
|
||||
{
|
||||
const struct wined3d_stream_info_element *element = &stream_info->elements[i];
|
||||
const struct wined3d_stream_state *stream;
|
||||
|
||||
if (!(stream_info->use_map & (1u << i)))
|
||||
{
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
unload_numbered_array(context, i);
|
||||
if (!use_vs(state) && i == WINED3D_FFP_DIFFUSE)
|
||||
GL_EXTCALL(glVertexAttrib4f(i, 1.0f, 1.0f, 1.0f, 1.0f));
|
||||
else
|
||||
GL_EXTCALL(glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f));
|
||||
continue;
|
||||
}
|
||||
|
||||
stream = &state->streams[element->stream_idx];
|
||||
|
||||
if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
|
||||
context->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
|
||||
|
||||
if (gl_info->supported[ARB_INSTANCED_ARRAYS])
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribDivisor(i, element->divisor));
|
||||
}
|
||||
else if (element->divisor)
|
||||
{
|
||||
/* Unload instanced arrays, they will be loaded using
|
||||
* immediate mode instead. */
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
unload_numbered_array(context, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE_(d3d_shader)("Loading array %u [VBO=%u].\n", i, element->data.buffer_object);
|
||||
|
||||
if (element->stride)
|
||||
{
|
||||
if (curVBO != element->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, element->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
curVBO = element->data.buffer_object;
|
||||
}
|
||||
/* Use the VBO to find out if a vertex buffer exists, not the vb
|
||||
* pointer. vb can point to a user pointer data blob. In that case
|
||||
* curVBO will be 0. If there is a vertex buffer but no vbo we
|
||||
* won't be load converted attributes anyway. */
|
||||
if (vs && vs->reg_maps.shader_version.major >= 4
|
||||
&& (element->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_INTEGER))
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribIPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
|
||||
element->stride, element->data.addr + state->load_base_vertex_index * element->stride));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_EXTCALL(glVertexAttribPointer(i, element->format->gl_vtx_format, element->format->gl_vtx_type,
|
||||
element->format->gl_normalized, element->stride,
|
||||
element->data.addr + state->load_base_vertex_index * element->stride));
|
||||
}
|
||||
|
||||
if (!(context->numbered_array_mask & (1u << i)))
|
||||
{
|
||||
GL_EXTCALL(glEnableVertexAttribArray(i));
|
||||
context->numbered_array_mask |= (1u << i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stride = 0 means always the same values.
|
||||
* glVertexAttribPointer doesn't do that. Instead disable the
|
||||
* pointer and set up the attribute statically. But we have to
|
||||
* figure out the system memory address. */
|
||||
const BYTE *ptr = element->data.addr;
|
||||
if (element->data.buffer_object)
|
||||
ptr += (ULONG_PTR)wined3d_buffer_load_sysmem(stream->buffer, context);
|
||||
|
||||
if (context->numbered_array_mask & (1u << i))
|
||||
unload_numbered_array(context, i);
|
||||
|
||||
switch (element->format->id)
|
||||
{
|
||||
case WINED3DFMT_R32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib1fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib2fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib3fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R32G32B32A32_FLOAT:
|
||||
GL_EXTCALL(glVertexAttrib4fv(i, (const GLfloat *)ptr));
|
||||
break;
|
||||
|
||||
case WINED3DFMT_R8G8B8A8_UINT:
|
||||
GL_EXTCALL(glVertexAttrib4ubv(i, ptr));
|
||||
break;
|
||||
case WINED3DFMT_B8G8R8A8_UNORM:
|
||||
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
|
||||
{
|
||||
const DWORD *src = (const DWORD *)ptr;
|
||||
DWORD c = *src & 0xff00ff00u;
|
||||
c |= (*src & 0xff0000u) >> 16;
|
||||
c |= (*src & 0xffu) << 16;
|
||||
GL_EXTCALL(glVertexAttrib4Nubv(i, (GLubyte *)&c));
|
||||
break;
|
||||
}
|
||||
/* else fallthrough */
|
||||
case WINED3DFMT_R8G8B8A8_UNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nubv(i, ptr));
|
||||
break;
|
||||
|
||||
case WINED3DFMT_R16G16_SINT:
|
||||
GL_EXTCALL(glVertexAttrib2sv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_SINT:
|
||||
GL_EXTCALL(glVertexAttrib4sv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
|
||||
case WINED3DFMT_R16G16_SNORM:
|
||||
{
|
||||
const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
|
||||
GL_EXTCALL(glVertexAttrib4Nsv(i, s));
|
||||
break;
|
||||
}
|
||||
case WINED3DFMT_R16G16_UNORM:
|
||||
{
|
||||
const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
|
||||
GL_EXTCALL(glVertexAttrib4Nusv(i, s));
|
||||
break;
|
||||
}
|
||||
case WINED3DFMT_R16G16B16A16_SNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nsv(i, (const GLshort *)ptr));
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_UNORM:
|
||||
GL_EXTCALL(glVertexAttrib4Nusv(i, (const GLushort *)ptr));
|
||||
break;
|
||||
|
||||
case WINED3DFMT_R10G10B10X2_UINT:
|
||||
FIXME("Unsure about WINED3DDECLTYPE_UDEC3.\n");
|
||||
/*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
|
||||
break;
|
||||
case WINED3DFMT_R10G10B10X2_SNORM:
|
||||
FIXME("Unsure about WINED3DDECLTYPE_DEC3N.\n");
|
||||
/*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
|
||||
break;
|
||||
|
||||
case WINED3DFMT_R16G16_FLOAT:
|
||||
if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
|
||||
{
|
||||
/* Not supported by GL_ARB_half_float_vertex. */
|
||||
GL_EXTCALL(glVertexAttrib2hvNV(i, (const GLhalfNV *)ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
||||
GL_EXTCALL(glVertexAttrib2f(i, x, y));
|
||||
}
|
||||
break;
|
||||
case WINED3DFMT_R16G16B16A16_FLOAT:
|
||||
if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
|
||||
{
|
||||
/* Not supported by GL_ARB_half_float_vertex. */
|
||||
GL_EXTCALL(glVertexAttrib4hvNV(i, (const GLhalfNV *)ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
|
||||
float y = float_16_to_32(((const unsigned short *)ptr) + 1);
|
||||
float z = float_16_to_32(((const unsigned short *)ptr) + 2);
|
||||
float w = float_16_to_32(((const unsigned short *)ptr) + 3);
|
||||
GL_EXTCALL(glVertexAttrib4f(i, x, y, z, w));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR("Unexpected declaration in stride 0 attributes.\n");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
checkGLcall("Loading numbered arrays");
|
||||
}
|
||||
|
||||
static void load_vertex_data(struct wined3d_context *context,
|
||||
const struct wined3d_stream_info *si, const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
|
||||
const struct wined3d_stream_info_element *e;
|
||||
|
||||
TRACE("Using fast vertex array code\n");
|
||||
|
||||
/* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
|
||||
context->instance_count = 0;
|
||||
|
||||
/* Blend Data ---------------------------------------------- */
|
||||
if ((si->use_map & (1u << WINED3D_FFP_BLENDWEIGHT))
|
||||
|| si->use_map & (1u << WINED3D_FFP_BLENDINDICES))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
|
||||
|
||||
/* TODO: Support vertex blending in immediate mode draws. No need to
|
||||
* write a FIXME here, this is done after the general vertex
|
||||
* declaration decoding. */
|
||||
WARN("Vertex blending not supported.\n");
|
||||
}
|
||||
|
||||
/* Point Size ----------------------------------------------*/
|
||||
if (si->use_map & (1u << WINED3D_FFP_PSIZE))
|
||||
{
|
||||
/* no such functionality in the fixed function GL pipeline */
|
||||
TRACE("Cannot change ptSize here in openGl\n");
|
||||
/* TODO: Implement this function in using shaders if they are available */
|
||||
}
|
||||
|
||||
/* Vertex Pointers -----------------------------------------*/
|
||||
if (si->use_map & (1u << WINED3D_FFP_POSITION))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_POSITION];
|
||||
|
||||
if (curVBO != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
curVBO = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
|
||||
e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glVertexPointer(...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
|
||||
}
|
||||
|
||||
/* Normals -------------------------------------------------*/
|
||||
if (si->use_map & (1u << WINED3D_FFP_NORMAL))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_NORMAL];
|
||||
|
||||
if (curVBO != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
curVBO = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glNormalPointer(...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
|
||||
checkGLcall("glNormal3f(0, 0, 0)");
|
||||
}
|
||||
|
||||
/* Diffuse Colour --------------------------------------------*/
|
||||
if (si->use_map & (1u << WINED3D_FFP_DIFFUSE))
|
||||
{
|
||||
e = &si->elements[WINED3D_FFP_DIFFUSE];
|
||||
|
||||
if (curVBO != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
curVBO = e->data.buffer_object;
|
||||
}
|
||||
|
||||
TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
|
||||
e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
|
||||
checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
checkGLcall("glColor4f(1, 1, 1, 1)");
|
||||
}
|
||||
|
||||
/* Specular Colour ------------------------------------------*/
|
||||
if (si->use_map & (1u << WINED3D_FFP_SPECULAR))
|
||||
{
|
||||
TRACE("setting specular colour\n");
|
||||
|
||||
e = &si->elements[WINED3D_FFP_SPECULAR];
|
||||
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
{
|
||||
GLenum type = e->format->gl_vtx_type;
|
||||
GLint format = e->format->gl_vtx_format;
|
||||
|
||||
if (curVBO != e->data.buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_ARRAY_BUFFER, e->data.buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
curVBO = e->data.buffer_object;
|
||||
}
|
||||
|
||||
if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
|
||||
{
|
||||
/* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
|
||||
* contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
|
||||
* vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
|
||||
* 4 component secondary colors use it
|
||||
*/
|
||||
TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE:
|
||||
TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Add 4 component specular color pointers for type %x\n", type);
|
||||
/* Make sure that the right color component is dropped */
|
||||
TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride);
|
||||
GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
|
||||
e->data.addr + state->load_base_vertex_index * e->stride));
|
||||
checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
|
||||
}
|
||||
}
|
||||
gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
||||
checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Specular colour is not supported in this GL implementation.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl_info->supported[EXT_SECONDARY_COLOR])
|
||||
{
|
||||
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
|
||||
checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Specular colour is not supported in this GL implementation.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture coords -------------------------------------------*/
|
||||
load_tex_coords(context, si, &curVBO, state);
|
||||
}
|
||||
|
||||
static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
BOOL load_numbered = context->d3d_info->ffp_generic_attributes
|
||||
|| (use_vs(state) && !context->use_immediate_mode_draw);
|
||||
BOOL load_named = !context->d3d_info->ffp_generic_attributes
|
||||
&& !use_vs(state) && !context->use_immediate_mode_draw;
|
||||
|
||||
if (isStateDirty(context, STATE_VDECL)) return;
|
||||
if (context->numbered_array_mask && !load_numbered)
|
||||
{
|
||||
unload_numbered_arrays(context);
|
||||
context->numbered_array_mask = 0;
|
||||
}
|
||||
else if (context->namedArraysLoaded)
|
||||
{
|
||||
unload_vertex_data(context->gl_info);
|
||||
context->namedArraysLoaded = FALSE;
|
||||
}
|
||||
|
||||
if (load_numbered)
|
||||
{
|
||||
TRACE("Loading numbered arrays\n");
|
||||
load_numbered_arrays(context, &context->stream_info, state);
|
||||
}
|
||||
else if (load_named)
|
||||
{
|
||||
TRACE("Loading vertex data\n");
|
||||
load_vertex_data(context, &context->stream_info, state);
|
||||
context->namedArraysLoaded = TRUE;
|
||||
}
|
||||
if (isStateDirty(context, STATE_VDECL))
|
||||
return;
|
||||
context_update_stream_sources(context, state);
|
||||
}
|
||||
|
||||
static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
if (isStateDirty(context, STATE_STREAMSRC))
|
||||
return;
|
||||
streamsrc(context, state, STATE_STREAMSRC);
|
||||
context_update_stream_sources(context, state);
|
||||
}
|
||||
|
||||
static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
|
|
|
@ -2178,6 +2178,8 @@ void context_gl_resource_released(struct wined3d_device *device,
|
|||
GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN;
|
||||
void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
|
||||
void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
|
||||
void context_load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
|
||||
GLuint *current_bo, const struct wined3d_state *state) DECLSPEC_HIDDEN;
|
||||
void *context_map_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data,
|
||||
size_t size, GLenum binding, DWORD flags) DECLSPEC_HIDDEN;
|
||||
struct wined3d_context *context_reacquire(const struct wined3d_device *device,
|
||||
|
@ -2194,8 +2196,11 @@ void context_state_drawbuf(struct wined3d_context *context,
|
|||
void context_state_fb(struct wined3d_context *context,
|
||||
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
|
||||
void context_texture_update(struct wined3d_context *context, const struct wined3d_texture *texture) DECLSPEC_HIDDEN;
|
||||
void context_unload_tex_coords(const struct wined3d_context *context) DECLSPEC_HIDDEN;
|
||||
void context_unmap_bo_address(struct wined3d_context *context,
|
||||
const struct wined3d_bo_address *data, GLenum binding) DECLSPEC_HIDDEN;
|
||||
void context_update_stream_sources(struct wined3d_context *context,
|
||||
const struct wined3d_state *state) DECLSPEC_HIDDEN;
|
||||
|
||||
/*****************************************************************************
|
||||
* Internal representation of a light
|
||||
|
|
Loading…
Reference in New Issue