drawprim.c revision 0ac83e2abcde6d1badbbeaf979676be588dd64bb
/*
* WINED3D draw functions
*
* Copyright 2002-2004 Jason Edmeades
* Copyright 2002-2004 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2006, 2008 Henri Verbeet
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009 Henri Verbeet for CodeWeavers
*
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
* other than GPL or LGPL is available it will apply instead, Oracle elects to use only
* the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
* a choice of LGPL license versions is made available with the language indicating
* that LGPLv2 or any later version may be used, or where a choice of which version
* of the LGPL is applied is otherwise unspecified.
*/
#include "config.h"
#include "wined3d_private.h"
#include <stdio.h>
#include <math.h>
#ifdef DEBUG_misha
#include "../VBox/VBoxDbgGl.h"
#endif
#ifdef VBOX_WITH_WINE_FIXES
#endif
/* Context activation is done by the caller. */
static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size,
const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count)
{
if (idx_size)
{
if (instance_count)
{
{
FIXME("Instanced drawing not supported.\n");
}
else
{
if (start_instance)
checkGLcall("glDrawElementsInstancedBaseVertex");
}
}
{
checkGLcall("glDrawElementsBaseVertex");
}
else
{
checkGLcall("glDrawElements");
}
}
else
{
checkGLcall("glDrawArrays");
}
}
/*
* Actually draw using the supplied information.
* Slower GL version which extracts info about each vertex in turn
*/
/* Context activation is done by the caller. */
static void drawStridedSlow(const struct wined3d_device *device, const struct wined3d_context *context,
{
unsigned int textureNo = 0;
const struct wined3d_stream_info_element *element;
/* Variable Initialization */
if (idxSize)
{
/* Immediate mode drawing can't make use of indices in a vbo - get the
* data from the index buffer. If the index buffer has no vbo (not
* supported or other reason), or with user pointer drawing idxData
* will be non-NULL. */
if (!idxData)
} else if (idxData) {
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
return;
}
/* Start drawing in GL */
{
}
{
}
else
{
}
{
}
else
{
}
{
/* special case where the fog density is stored in the specular alpha channel */
{
{
}
else
{
if (!warned)
{
/* TODO: Use the fog table code from old ddraw */
FIXME("Implement fog for transformed vertices in software\n");
}
}
}
}
{
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
}
{
{
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
continue;
}
if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;
if (coordIdx > 7)
{
continue;
}
else if (coordIdx < 0)
{
continue;
}
{
}
else
{
else
}
}
/* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
* Guess it's not necessary(we crash then anyway) and would only eat CPU time
*/
/* For each primitive */
/* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
* function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
*/
/* For indexed data, we need to go a few more strides in */
if (idxData)
{
/* Indexed so work out the number of strides to skip */
if (idxSize == 2)
else
}
{
int coord_idx;
const void *ptr;
if (!(tmp_tex_mask & 1)) continue;
ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
}
/* Diffuse -------------------------------- */
if (diffuse) {
{
unsigned char i;
float color[4];
for (i = 0; i < num_untracked_materials; ++i)
{
}
}
}
/* Specular ------------------------------- */
if (specular) {
if (specular_fog)
{
}
}
/* Normal -------------------------------- */
if (normal)
{
}
/* Position -------------------------------- */
if (position) {
}
/* For non indexed mode, step onto next parts */
if (!idxData) ++SkipnStrides;
}
checkGLcall("glEnd and previous calls");
}
/* Context activation is done by the caller. */
{
switch(format)
{
case WINED3DFMT_R32_FLOAT:
break;
case WINED3DFMT_R32G32_FLOAT:
break;
break;
break;
case WINED3DFMT_R8G8B8A8_UINT:
break;
{
break;
}
/* else fallthrough */
break;
case WINED3DFMT_R16G16_SINT:
break;
break;
case WINED3DFMT_R16G16_SNORM:
{
break;
}
case WINED3DFMT_R16G16_UNORM:
{
break;
}
break;
break;
FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
/*glVertexAttrib3usvARB(instancedData[j], (GLushort *) ptr); Does not exist */
break;
FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
/*glVertexAttrib3NusvARB(instancedData[j], (GLushort *) ptr); Does not exist */
break;
case WINED3DFMT_R16G16_FLOAT:
/* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
* byte float according to the IEEE standard
*/
{
/* Not supported by GL_ARB_half_float_vertex */
}
else
{
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
}
break;
{
/* Not supported by GL_ARB_half_float_vertex */
}
else
{
float x = float_16_to_32(((const unsigned short *)ptr) + 0);
}
break;
default:
break;
}
}
/* Context activation is done by the caller. */
static void drawStridedSlowVs(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
{
int i;
if (idxSize)
{
/* Immediate mode drawing can't make use of indices in a vbo - get the
* data from the index buffer. If the index buffer has no vbo (not
* supported or other reason), or with user pointer drawing idxData
* will be non-NULL. */
if (!idxData)
} else if (idxData) {
ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
return;
}
/* Start drawing in GL */
{
if (idxData)
{
/* Indexed so work out the number of strides to skip */
if (idxSize == 2)
else
}
for (i = MAX_ATTRIBS - 1; i >= 0; i--)
{
{
if (i == 0)
{
# ifdef DEBUG_misha
ERR("Test it!\n");
# endif
}
#endif
continue;
}
}
SkipnStrides++;
}
}
/* Context activation is done by the caller. */
static void drawStridedInstanced(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
{
int numInstancedAttribs = 0, j;
UINT i;
if (!idxSize)
{
/* This is a nasty thing. MSDN says no hardware supports that and apps have to use software vertex processing.
* We don't support this for now
*
* Shouldn't be too hard to support with opengl, in theory just call glDrawArrays instead of drawElements.
* But the StreamSourceFreq value has a different meaning in that situation.
*/
FIXME("Non-indexed instanced drawing is not supported\n");
return;
}
{
{
}
}
for (i = 0; i < instance_count; ++i)
{
/* Specify the instanced attributes using immediate mode calls */
for(j = 0; j < numInstancedAttribs; j++) {
{
}
}
{
checkGLcall("glDrawElementsBaseVertex");
}
else
{
checkGLcall("glDrawElements");
}
}
}
{
unsigned int i;
{
struct wined3d_stream_info_element *e;
if (!(s->use_map & (1 << i))) continue;
e = &s->elements[i];
if (e->data.buffer_object)
{
e->data.buffer_object = 0;
}
}
}
/* Routine common to the draw primitive and draw indexed primitive routines */
{
const struct wined3d_stream_info *stream_info;
struct wined3d_stream_info si_emulated;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
unsigned int i;
if (!index_count) return;
{
/* Invalidate the back buffer memory so LockRect will read it the next time */
{
if (target)
{
}
}
}
/* Signals other modules that a drawing is in progress and the stateblock finalized */
{
WARN("Invalid context, skipping draw.\n");
return;
}
{
/* Note that this depends on the context_acquire() call above to set
* context->render_offscreen properly. We don't currently take the
* Z-compare function into account, but we could skip loading the
* depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
* that we never copy the stencil data.*/
DWORD location = context->render_offscreen ? device->fb.depth_stencil->draw_binding : SFLAG_INDRAWABLE;
{
else
}
}
#endif
{
WARN("Unable to apply draw state, skipping draw.\n");
device->czvDrawVertices = 0;
#endif
return;
}
device->czvDrawVertices = 0;
#endif
#ifdef DEBUG_misha
#endif
{
}
{
FIXME("Point sprite coordinate origin switching not supported.\n");
}
if (device->instance_count)
if (indexed)
{
else
{
}
idx_size = 2;
else
idx_size = 4;
}
{
{
if (!warned++)
FIXME("Using software emulation because not all material properties could be tracked.\n");
else
WARN_(d3d_perf)("Using software emulation because not all material properties could be tracked.\n");
}
{
/* Either write a pipeline replacement shader or convert the
* specular alpha from unsigned byte to a float in the vertex
* buffer. */
if (!warned++)
FIXME("Using software emulation because manual fog coordinates are provided.\n");
else
}
if (emulation)
{
}
}
{
/* Immediate mode drawing. */
{
if (!warned++)
FIXME("Using immediate mode with vertex shaders for half float emulation.\n");
else
}
else
{
}
}
{
/* Instancing emulation by mixing immediate mode and arrays. */
}
else
{
}
if (ib_query)
for (i = 0; i < device->num_buffer_queries; ++i)
{
}
TRACE("Done all gl drawing\n");
/* Control goes back to the device, stateblock values may change again */
}