Merge branch 'master' into cmake
This commit is contained in:
commit
62d08ec8bf
|
|
@ -1184,6 +1184,7 @@ string AIBehaviors::behavior_status(string ai_type) {
|
|||
|
||||
default:
|
||||
cout<<"Invalid value!"<<endl;
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -880,13 +880,13 @@ HTML_STYLESHEET = $(DOXYGEN_HTML_STYLESHEET)
|
|||
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
|
||||
# The allowed range is 0 to 359.
|
||||
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_HUE = 228
|
||||
|
||||
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
|
||||
# the colors in the HTML output. For a value of 0 the output will use
|
||||
# grayscales only. A value of 255 will produce the most vivid colors.
|
||||
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_SAT = 99
|
||||
|
||||
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
|
||||
# the luminance component of the colors in the HTML output. Values below
|
||||
|
|
@ -895,7 +895,7 @@ HTML_COLORSTYLE_SAT = 100
|
|||
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
|
||||
# and 100 does not change the gamma.
|
||||
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_COLORSTYLE_GAMMA = 56
|
||||
|
||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||
# page will contain the date and time when the page was generated. Setting
|
||||
|
|
@ -1451,6 +1451,7 @@ INCLUDE_FILE_PATTERNS =
|
|||
PREDEFINED = TVOLATILE= \
|
||||
INLINE=inline \
|
||||
PUBLISHED=public \
|
||||
protected=private \
|
||||
INLINE_LINMATH=inline \
|
||||
INLINE_MATHUTIL=inline \
|
||||
EXTENSION(x)= \
|
||||
|
|
|
|||
|
|
@ -863,13 +863,13 @@ HTML_STYLESHEET = $(DOXYGEN_HTML_STYLESHEET)
|
|||
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
|
||||
# The allowed range is 0 to 359.
|
||||
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_HUE = 228
|
||||
|
||||
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
|
||||
# the colors in the HTML output. For a value of 0 the output will use
|
||||
# grayscales only. A value of 255 will produce the most vivid colors.
|
||||
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_SAT = 99
|
||||
|
||||
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
|
||||
# the luminance component of the colors in the HTML output. Values below
|
||||
|
|
@ -878,7 +878,7 @@ HTML_COLORSTYLE_SAT = 100
|
|||
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
|
||||
# and 100 does not change the gamma.
|
||||
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_COLORSTYLE_GAMMA = 56
|
||||
|
||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||
# page will contain the date and time when the page was generated. Setting
|
||||
|
|
|
|||
|
|
@ -20,21 +20,17 @@ from pandac.PandaModules import Point3, Vec3, Vec4, Point2
|
|||
from pandac.PandaModules import NodePath, PandaNode
|
||||
from pandac.PandaModules import Filename
|
||||
from pandac.PandaModules import AuxBitplaneAttrib
|
||||
from pandac.PandaModules import RenderState, Texture, Shader
|
||||
from pandac.PandaModules import RenderState, Texture, Shader, ATSNone
|
||||
import sys,os
|
||||
|
||||
CARTOON_BODY="""
|
||||
float4 cartoondelta = k_cartoonseparation * texpix_txaux.xwyw;
|
||||
float4 cartoon_p0 = l_texcoordN + cartoondelta.xyzw;
|
||||
float4 cartoon_c0 = tex2D(k_txaux, cartoon_p0.xy);
|
||||
float4 cartoon_p1 = l_texcoordN - cartoondelta.xyzw;
|
||||
float4 cartoon_c1 = tex2D(k_txaux, cartoon_p1.xy);
|
||||
float4 cartoon_p2 = l_texcoordN + cartoondelta.wzyx;
|
||||
float4 cartoon_c2 = tex2D(k_txaux, cartoon_p2.xy);
|
||||
float4 cartoon_p3 = l_texcoordN - cartoondelta.wzyx;
|
||||
float4 cartoon_c3 = tex2D(k_txaux, cartoon_p3.xy);
|
||||
float4 cartoon_mx = max(cartoon_c0,max(cartoon_c1,max(cartoon_c2,cartoon_c3)));
|
||||
float4 cartoon_mn = min(cartoon_c0,min(cartoon_c1,min(cartoon_c2,cartoon_c3)));
|
||||
float4 cartoon_c0 = tex2D(k_txaux, %(texcoord)s + cartoondelta.xy);
|
||||
float4 cartoon_c1 = tex2D(k_txaux, %(texcoord)s - cartoondelta.xy);
|
||||
float4 cartoon_c2 = tex2D(k_txaux, %(texcoord)s + cartoondelta.wz);
|
||||
float4 cartoon_c3 = tex2D(k_txaux, %(texcoord)s - cartoondelta.wz);
|
||||
float4 cartoon_mx = max(cartoon_c0, max(cartoon_c1, max(cartoon_c2, cartoon_c3)));
|
||||
float4 cartoon_mn = min(cartoon_c0, min(cartoon_c1, min(cartoon_c2, cartoon_c3)));
|
||||
float cartoon_thresh = saturate(dot(cartoon_mx - cartoon_mn, float4(3,3,0,0)) - 0.5);
|
||||
o_color = lerp(o_color, k_cartooncolor, cartoon_thresh);
|
||||
"""
|
||||
|
|
@ -125,7 +121,6 @@ class CommonFilters:
|
|||
self.task = None
|
||||
|
||||
def reconfigure(self, fullrebuild, changed):
|
||||
|
||||
""" Reconfigure is called whenever any configuration change is made. """
|
||||
|
||||
configuration = self.configuration
|
||||
|
|
@ -138,36 +133,46 @@ class CommonFilters:
|
|||
return
|
||||
|
||||
auxbits = 0
|
||||
needtex = {}
|
||||
needtex["color"] = True
|
||||
needtex = set(["color"])
|
||||
needtexcoord = set(["color"])
|
||||
|
||||
if ("CartoonInk" in configuration):
|
||||
needtex["aux"] = True
|
||||
needtex.add("aux")
|
||||
auxbits |= AuxBitplaneAttrib.ABOAuxNormal
|
||||
needtexcoord.add("aux")
|
||||
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
needtex["depth"] = True
|
||||
needtex["ssao0"] = True
|
||||
needtex["ssao1"] = True
|
||||
needtex["ssao2"] = True
|
||||
needtex["aux"] = True
|
||||
needtex.add("depth")
|
||||
needtex.add("ssao0")
|
||||
needtex.add("ssao1")
|
||||
needtex.add("ssao2")
|
||||
needtex.add("aux")
|
||||
auxbits |= AuxBitplaneAttrib.ABOAuxNormal
|
||||
needtexcoord.add("ssao2")
|
||||
|
||||
if ("BlurSharpen" in configuration):
|
||||
needtex["blur0"] = True
|
||||
needtex["blur1"] = True
|
||||
needtex.add("blur0")
|
||||
needtex.add("blur1")
|
||||
needtexcoord.add("blur1")
|
||||
|
||||
if ("Bloom" in configuration):
|
||||
needtex["bloom0"] = True
|
||||
needtex["bloom1"] = True
|
||||
needtex["bloom2"] = True
|
||||
needtex["bloom3"] = True
|
||||
needtex.add("bloom0")
|
||||
needtex.add("bloom1")
|
||||
needtex.add("bloom2")
|
||||
needtex.add("bloom3")
|
||||
auxbits |= AuxBitplaneAttrib.ABOGlow
|
||||
needtexcoord.add("bloom3")
|
||||
|
||||
if ("ViewGlow" in configuration):
|
||||
auxbits |= AuxBitplaneAttrib.ABOGlow
|
||||
|
||||
if ("VolumetricLighting" in configuration):
|
||||
needtex[configuration["VolumetricLighting"].source] = True
|
||||
|
||||
for tex in needtex:
|
||||
self.textures[tex] = Texture("scene-"+tex)
|
||||
self.textures[tex] = Texture("scene-" + tex)
|
||||
self.textures[tex].setWrapU(Texture.WMClamp)
|
||||
self.textures[tex].setWrapV(Texture.WMClamp)
|
||||
needtexpix = True
|
||||
|
||||
self.finalQuad = self.manager.renderSceneInto(textures = self.textures, auxbits=auxbits)
|
||||
if (self.finalQuad == None):
|
||||
|
|
@ -228,97 +233,112 @@ class CommonFilters:
|
|||
self.bloom[3].setShaderInput("src", bloom2)
|
||||
self.bloom[3].setShader(self.loadShader("filter-bloomy.sha"))
|
||||
|
||||
texcoords = {}
|
||||
texcoordPadding = {}
|
||||
|
||||
for tex in needtexcoord:
|
||||
if self.textures[tex].getAutoTextureScale() != ATSNone or \
|
||||
"HalfPixelShift" in configuration:
|
||||
texcoords[tex] = "l_texcoord_" + tex
|
||||
texcoordPadding["l_texcoord_" + tex] = tex
|
||||
else:
|
||||
# Share unpadded texture coordinates.
|
||||
texcoords[tex] = "l_texcoord"
|
||||
texcoordPadding["l_texcoord"] = None
|
||||
|
||||
texcoordSets = list(enumerate(texcoordPadding.keys()))
|
||||
|
||||
text = "//Cg\n"
|
||||
text += "void vshader(float4 vtx_position : POSITION,\n"
|
||||
text += " out float4 l_position : POSITION,\n"
|
||||
text += " uniform float4 texpad_txcolor,\n"
|
||||
text += " uniform float4 texpix_txcolor,\n"
|
||||
text += " out float4 l_texcoordC : TEXCOORD0,\n"
|
||||
if ("CartoonInk" in configuration):
|
||||
text += " uniform float4 texpad_txaux,\n"
|
||||
text += " uniform float4 texpix_txaux,\n"
|
||||
text += " out float4 l_texcoordN : TEXCOORD1,\n"
|
||||
if ("Bloom" in configuration):
|
||||
text += " uniform float4 texpad_txbloom3,\n"
|
||||
text += " out float4 l_texcoordB : TEXCOORD2,\n"
|
||||
if ("BlurSharpen" in configuration):
|
||||
text += " uniform float4 texpad_txblur1,\n"
|
||||
text += " out float4 l_texcoordBS : TEXCOORD3,\n"
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
text += " uniform float4 texpad_txssao2,\n"
|
||||
text += " out float4 l_texcoordAO : TEXCOORD4,\n"
|
||||
text += " uniform float4x4 mat_modelproj)\n"
|
||||
text += " out float4 l_position : POSITION,\n"
|
||||
|
||||
for texcoord, padTex in texcoordPadding.items():
|
||||
if padTex is not None:
|
||||
text += " uniform float4 texpad_tx%s,\n" % (padTex)
|
||||
if ("HalfPixelShift" in configuration):
|
||||
text += " uniform float4 texpix_tx%s,\n" % (padTex)
|
||||
|
||||
for i, name in texcoordSets:
|
||||
text += " out float2 %s : TEXCOORD%d,\n" % (name, i)
|
||||
|
||||
text += " uniform float4x4 mat_modelproj)\n"
|
||||
text += "{\n"
|
||||
text += " l_position=mul(mat_modelproj, vtx_position);\n"
|
||||
text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n"
|
||||
if ("CartoonInk" in configuration):
|
||||
text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n"
|
||||
if ("Bloom" in configuration):
|
||||
text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n"
|
||||
if ("BlurSharpen" in configuration):
|
||||
text += " l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n"
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
text += " l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n"
|
||||
if ("HalfPixelShift" in configuration):
|
||||
text += " l_texcoordC+=texpix_txcolor*0.5;\n"
|
||||
if ("CartoonInk" in configuration):
|
||||
text += " l_texcoordN+=texpix_txaux*0.5;\n"
|
||||
text += " l_position = mul(mat_modelproj, vtx_position);\n"
|
||||
|
||||
for texcoord, padTex in texcoordPadding.items():
|
||||
if padTex is None:
|
||||
text += " %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n" % (texcoord)
|
||||
else:
|
||||
text += " %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n" % (texcoord, padTex, padTex)
|
||||
|
||||
if ("HalfPixelShift" in configuration):
|
||||
text += " %s += texpix_tx%s.xy * 0.5;\n" % (texcoord, padTex)
|
||||
|
||||
text += "}\n"
|
||||
|
||||
text += "void fshader(\n"
|
||||
text += "float4 l_texcoordC : TEXCOORD0,\n"
|
||||
text += "uniform float4 texpix_txcolor,\n"
|
||||
if ("CartoonInk" in configuration):
|
||||
text += "float4 l_texcoordN : TEXCOORD1,\n"
|
||||
text += "uniform float4 texpix_txaux,\n"
|
||||
if ("Bloom" in configuration):
|
||||
text += "float4 l_texcoordB : TEXCOORD2,\n"
|
||||
if ("BlurSharpen" in configuration):
|
||||
text += "float4 l_texcoordBS : TEXCOORD3,\n"
|
||||
text += "uniform float4 k_blurval,\n"
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
text += "float4 l_texcoordAO : TEXCOORD4,\n"
|
||||
|
||||
for i, name in texcoordSets:
|
||||
text += " float2 %s : TEXCOORD%d,\n" % (name, i)
|
||||
|
||||
for key in self.textures:
|
||||
text += "uniform sampler2D k_tx" + key + ",\n"
|
||||
text += " uniform sampler2D k_tx" + key + ",\n"
|
||||
|
||||
if ("CartoonInk" in configuration):
|
||||
text += "uniform float4 k_cartoonseparation,\n"
|
||||
text += "uniform float4 k_cartooncolor,\n"
|
||||
if ("VolumetricLighting" in configuration):
|
||||
text += "uniform float4 k_casterpos,\n"
|
||||
text += "uniform float4 k_vlparams,\n"
|
||||
text += "out float4 o_color : COLOR)\n"
|
||||
text += "{\n"
|
||||
text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n"
|
||||
if ("CartoonInk" in configuration):
|
||||
text += CARTOON_BODY
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
text += "o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n"
|
||||
text += " uniform float4 k_cartoonseparation,\n"
|
||||
text += " uniform float4 k_cartooncolor,\n"
|
||||
text += " uniform float4 texpix_txaux,\n"
|
||||
|
||||
if ("BlurSharpen" in configuration):
|
||||
text += " o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n"
|
||||
if ("Bloom" in configuration):
|
||||
text += "o_color = saturate(o_color);\n";
|
||||
text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n"
|
||||
text += "o_color = 1-((1-bloom)*(1-o_color));\n"
|
||||
if ("ViewGlow" in configuration):
|
||||
text += "o_color.r = o_color.a;\n"
|
||||
text += " uniform float4 k_blurval,\n"
|
||||
|
||||
if ("VolumetricLighting" in configuration):
|
||||
text += "float decay = 1.0f;\n"
|
||||
text += "float2 curcoord = l_texcoordC.xy;\n"
|
||||
text += "float2 lightdir = curcoord - k_casterpos.xy;\n"
|
||||
text += "lightdir *= k_vlparams.x;\n"
|
||||
text += "half4 sample = tex2D(k_txcolor, curcoord);\n"
|
||||
text += "float3 vlcolor = sample.rgb * sample.a;\n"
|
||||
text += "for (int i = 0; i < %s; i++) {\n" % (int(configuration["VolumetricLighting"].numsamples))
|
||||
text += " curcoord -= lightdir;\n"
|
||||
text += " sample = tex2D(k_tx%s, curcoord);\n" % (configuration["VolumetricLighting"].source)
|
||||
text += " sample *= sample.a * decay;//*weight\n"
|
||||
text += " vlcolor += sample.rgb;\n"
|
||||
text += " decay *= k_vlparams.y;\n"
|
||||
text += "}\n"
|
||||
text += "o_color += float4(vlcolor * k_vlparams.z, 1);\n"
|
||||
text += " uniform float4 k_casterpos,\n"
|
||||
text += " uniform float4 k_vlparams,\n"
|
||||
text += " out float4 o_color : COLOR)\n"
|
||||
text += "{\n"
|
||||
text += " o_color = tex2D(k_txcolor, %s);\n" % (texcoords["color"])
|
||||
if ("CartoonInk" in configuration):
|
||||
text += CARTOON_BODY % {"texcoord" : texcoords["aux"]}
|
||||
if ("AmbientOcclusion" in configuration):
|
||||
text += " o_color *= tex2D(k_txssao2, %s).r;\n" % (texcoords["ssao2"])
|
||||
if ("BlurSharpen" in configuration):
|
||||
text += " o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n" % (texcoords["blur1"])
|
||||
if ("Bloom" in configuration):
|
||||
text += " o_color = saturate(o_color);\n";
|
||||
text += " float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n" % (texcoords["bloom3"])
|
||||
text += " o_color = 1-((1-bloom)*(1-o_color));\n"
|
||||
if ("ViewGlow" in configuration):
|
||||
text += " o_color.r = o_color.a;\n"
|
||||
if ("VolumetricLighting" in configuration):
|
||||
text += " float decay = 1.0f;\n"
|
||||
text += " float2 curcoord = %s;\n" % (texcoords["color"])
|
||||
text += " float2 lightdir = curcoord - k_casterpos.xy;\n"
|
||||
text += " lightdir *= k_vlparams.x;\n"
|
||||
text += " half4 sample = tex2D(k_txcolor, curcoord);\n"
|
||||
text += " float3 vlcolor = sample.rgb * sample.a;\n"
|
||||
text += " for (int i = 0; i < %s; i++) {\n" % (int(configuration["VolumetricLighting"].numsamples))
|
||||
text += " curcoord -= lightdir;\n"
|
||||
text += " sample = tex2D(k_tx%s, curcoord);\n" % (configuration["VolumetricLighting"].source)
|
||||
text += " sample *= sample.a * decay;//*weight\n"
|
||||
text += " vlcolor += sample.rgb;\n"
|
||||
text += " decay *= k_vlparams.y;\n"
|
||||
text += " }\n"
|
||||
text += " o_color += float4(vlcolor * k_vlparams.z, 1);\n"
|
||||
|
||||
if ("GammaAdjust" in configuration):
|
||||
gamma = configuration["GammaAdjust"]
|
||||
if gamma == 0.5:
|
||||
text += " o_color.rgb = sqrt(o_color.rgb);\n"
|
||||
elif gamma == 2.0:
|
||||
text += " o_color.rgb *= o_color.rgb;\n"
|
||||
elif gamma != 1.0:
|
||||
text += " o_color.rgb = pow(o_color.rgb, %ff);\n" % (gamma)
|
||||
|
||||
if ("Inverted" in configuration):
|
||||
text += "o_color = float4(1, 1, 1, 1) - o_color;\n"
|
||||
text += " o_color = float4(1, 1, 1, 1) - o_color;\n"
|
||||
text += "}\n"
|
||||
print text
|
||||
|
||||
self.finalQuad.setShader(Shader.make(text))
|
||||
for tex in self.textures:
|
||||
|
|
@ -504,3 +524,17 @@ class CommonFilters:
|
|||
return self.reconfigure(True, "AmbientOcclusion")
|
||||
return True
|
||||
|
||||
def setGammaAdjust(self, gamma):
|
||||
""" Applies additional gamma correction to the image. 1.0 = no correction. """
|
||||
old_gamma = self.configuration.get("GammaAdjust", 1.0)
|
||||
if old_gamma != gamma:
|
||||
self.configuration["GammaAdjust"] = gamma
|
||||
return self.reconfigure(True, "GammaAdjust")
|
||||
return True
|
||||
|
||||
def delGammaAdjust(self):
|
||||
if ("GammaAdjust" in self.configuration):
|
||||
old_gamma = self.configuration["GammaAdjust"]
|
||||
del self.configuration["GammaAdjust"]
|
||||
return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
#include <list>
|
||||
#include "socket_base.h"
|
||||
|
||||
enum CloseState
|
||||
enum CloseState
|
||||
{
|
||||
ConnectionDoNotClose,
|
||||
ConnectionDoClose
|
||||
ConnectionDoNotClose,
|
||||
ConnectionDoClose
|
||||
};
|
||||
// RHH
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -20,15 +20,15 @@ enum CloseState
|
|||
//
|
||||
// The general operation if get connection..
|
||||
// do you have a message
|
||||
// process message
|
||||
// process message
|
||||
// go back to do you have a message or close connection
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template < class _INCLASS1,class _IN_LISTEN, class MESSAGE_READER_BUF, class MESSAGE_READER_UPPASS> class BaseIncomingSet : public std::list<_INCLASS1 *>
|
||||
{
|
||||
typedef std::list<_INCLASS1 *> BaseClass;
|
||||
typedef TYPENAME BaseClass::iterator iterator;
|
||||
typedef std::list<_INCLASS1 *> BaseClass;
|
||||
typedef TYPENAME BaseClass::iterator iterator;
|
||||
_IN_LISTEN _Listener;
|
||||
|
||||
inline void AddFromListener(void);
|
||||
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
// typedef typename BaseIncomingSet<_INCLASS1, _IN_LISTEN, MESSAGE_READER_BUF, MESSAGE_READER_UPPASS>::LinkNode LinkNode;
|
||||
|
||||
// typedef SentDblLinkListNode_Gm SentDblLinkListNode_Gm;
|
||||
// typedef SentDblLinkListNode_Gm SentDblLinkListNode_Gm;
|
||||
inline BaseIncomingSet(void);
|
||||
inline BaseIncomingSet(BaseIncomingSet &in);
|
||||
virtual ~BaseIncomingSet();
|
||||
|
|
@ -50,10 +50,6 @@ public:
|
|||
virtual CloseState ProcessNewConnection(SOCKET socket);
|
||||
inline void AddToFDSet(Socket_fdset &set);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// inline LinkNode * GetRoot(void) { return &this->sentenal; };
|
||||
BaseIncomingSet &operator=( BaseIncomingSet &inval);
|
||||
void Reset();
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddFromListener
|
||||
// Description : Read incoming connections off the listener
|
||||
//
|
||||
// Return type : inline void
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddFromListener(void)
|
||||
{
|
||||
Socket_Address Addr1;
|
||||
SOCKET newsck;
|
||||
|
||||
|
||||
|
||||
|
||||
while(_Listener.GetIncomingConnection(newsck,Addr1) == true)
|
||||
{
|
||||
{
|
||||
CloseState cl= ProcessNewConnection(newsck);
|
||||
if(cl == ConnectionDoNotClose)
|
||||
{
|
||||
|
|
@ -22,52 +22,52 @@ inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READ
|
|||
}
|
||||
else
|
||||
DO_CLOSE(newsck);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpReader
|
||||
// Description : Tries to read a record off the incoming socket
|
||||
//
|
||||
// Return type : inline void
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : Time_Clock currentTime
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline int BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpReader(Time_Clock ¤tTime)
|
||||
{
|
||||
{
|
||||
MESSAGE_READER_BUF message;
|
||||
|
||||
|
||||
iterator lpNext, lp;
|
||||
for (lpNext = lp = BaseClass::begin(); lp != BaseClass::end() ; lp = lpNext)
|
||||
{
|
||||
lpNext++;
|
||||
|
||||
lpNext++;
|
||||
|
||||
int ans = (*lp)->ReadIt(message, sizeof(message),currentTime);
|
||||
if(ans < 0)
|
||||
{
|
||||
delete *lp;
|
||||
erase(lp);
|
||||
}
|
||||
this->erase(lp);
|
||||
}
|
||||
if(ans > 0)
|
||||
{
|
||||
CloseState cs = (*lp)->ProcessMessage(message,currentTime);
|
||||
if( cs == ConnectionDoClose)
|
||||
{
|
||||
delete *lp;
|
||||
erase(lp);
|
||||
this->erase(lp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddAConection
|
||||
// Description : Adds a member to the base container
|
||||
//
|
||||
// Return type : inline void
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : _INCLASS1 * newt
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddAConection(_INCLASS1 * newt)
|
||||
{
|
||||
push_back(newt);
|
||||
|
|
@ -75,17 +75,17 @@ inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READ
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet
|
||||
// Description : core constructor
|
||||
//
|
||||
// Return type : inline
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet(void)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet(BaseIncomingSet &in)
|
||||
{
|
||||
|
||||
|
|
@ -93,10 +93,10 @@ BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::~BaseIncomingSet
|
||||
// Description : The Destructot .. will delete all members.. ??
|
||||
//
|
||||
// Return type :
|
||||
//
|
||||
// Return type :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::~BaseIncomingSet()
|
||||
{
|
||||
for(iterator ii = BaseClass::begin(); ii != BaseClass::end(); ii++)
|
||||
|
|
@ -105,76 +105,76 @@ BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : & BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::GetListener
|
||||
// Description : Retyurns a pointer to the listener in this class
|
||||
//
|
||||
// Return type : inline _IN_LISTEN
|
||||
//
|
||||
// Return type : inline _IN_LISTEN
|
||||
// Argument : void
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline _IN_LISTEN & BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::GetListener(void)
|
||||
{
|
||||
return this->Listener;
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline _IN_LISTEN & BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::GetListener(void)
|
||||
{
|
||||
return this->Listener;
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::init
|
||||
// Description : the second part of the 2 phase power up.. Opends the listener
|
||||
//
|
||||
// Return type : inline bool
|
||||
//
|
||||
// Return type : inline bool
|
||||
// Argument : Socket_Address &WhereFrom
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline bool BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::init(Socket_Address &WhereFrom)
|
||||
{
|
||||
if(_Listener.OpenForListen(WhereFrom,true) != true)
|
||||
return false;
|
||||
return false;
|
||||
_Listener.SetNonBlocking();
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpAll
|
||||
// Description : THis is the polled interface to this class
|
||||
//
|
||||
// Return type : inline void
|
||||
//
|
||||
// Return type : inline void
|
||||
// Argument : Time_Clock ¤tTime
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpAll(Time_Clock ¤tTime)
|
||||
{
|
||||
PumpReader(currentTime); // I MOVED ORDER TO FINE TUNE THE READ OPERATIONS
|
||||
AddFromListener();
|
||||
AddFromListener();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::ProcessNewConnection
|
||||
// Description : this is the vertual function call when a new connection is created
|
||||
// Description : this is the vertual function call when a new connection is created
|
||||
// manly here for loging if needed...
|
||||
//
|
||||
// Return type : CloseState
|
||||
//
|
||||
// Return type : CloseState
|
||||
// Argument : SOCKET socket
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
CloseState BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::ProcessNewConnection(SOCKET socket)
|
||||
{
|
||||
return ConnectionDoNotClose;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function name : void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddToFDSet
|
||||
// Description : Add LIstener and Client to the FD set for polled reading
|
||||
//
|
||||
// Return type : inline
|
||||
// Description : Add LIstener and Client to the FD set for polled reading
|
||||
//
|
||||
// Return type : inline
|
||||
// Argument : Socket_Selector &set
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddToFDSet(Socket_fdset &set1)
|
||||
{
|
||||
{
|
||||
if(_Listener.Active())
|
||||
set1.setForSocket(_Listener);
|
||||
iterator lp;
|
||||
|
||||
|
||||
for (lp = BaseClass::begin(); lp != BaseClass::end(); lp = lp++)
|
||||
set1.setForSocket((*lp)->val);
|
||||
}
|
||||
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS> &BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::operator=
|
||||
(BaseIncomingSet &inval)
|
||||
{
|
||||
|
|
@ -184,18 +184,18 @@ inline BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UP
|
|||
}
|
||||
|
||||
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
template <class _INCLASS1,class _IN_LISTEN,typename MESSAGE_READER_BUF, typename MESSAGE_READER_UPPASS>
|
||||
inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::Reset()
|
||||
{
|
||||
_Listener.Close();
|
||||
iterator lpNext, lp;
|
||||
for (lpNext = lp = BaseClass::begin(); lp != BaseClass::end() ; lp = lpNext)
|
||||
{
|
||||
lpNext++;
|
||||
lpNext++;
|
||||
(*lp)->Reset();
|
||||
delete *lp;
|
||||
erase(lp);
|
||||
}
|
||||
this->erase(lp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,21 @@
|
|||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
/* It makes sense to use "App Paths\panda3d.exe". However, Microsoft
|
||||
decided in their infinite wisdom to disable Redirection for that
|
||||
key from Windows 7 onward, so we can't rely on it producing a
|
||||
result appropriate to the right architecture when both the 32-bit
|
||||
and 64-bit versions of the runtime are installed. Beh. */
|
||||
|
||||
#define UNINST_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Panda3D Game Engine"
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
int i;
|
||||
char buffer [BUFFER_SIZE];
|
||||
char buffer[BUFFER_SIZE];
|
||||
char* p3dfile;
|
||||
char* runtime = NULL;
|
||||
DWORD size;
|
||||
|
|
@ -37,56 +46,82 @@ int main (int argc, char* argv[]) {
|
|||
char *cmd;
|
||||
char *newcmd;
|
||||
HKEY hKey = 0;
|
||||
char buf [1024] = {0};
|
||||
DWORD dwType = 0;
|
||||
char buf[1024] = {0};
|
||||
DWORD dwType = REG_SZ;
|
||||
DWORD dwBufSize = sizeof(buf);
|
||||
size = GetModuleFileName (NULL, buffer, BUFFER_SIZE);
|
||||
size = GetModuleFileName(NULL, buffer, BUFFER_SIZE);
|
||||
assert (size > 0);
|
||||
|
||||
/* Chop off the .exe and replace it by .p3d. */
|
||||
p3dfile = (char*) malloc (size + 1);
|
||||
memcpy (p3dfile, buffer, size);
|
||||
p3dfile [size] = 0;
|
||||
memcpy (p3dfile + size - 3, "p3d", 3);
|
||||
p3dfile = (char*) _alloca(size + 1);
|
||||
memcpy(p3dfile, buffer, size);
|
||||
p3dfile[size] = 0;
|
||||
memcpy(p3dfile + size - 3, "p3d", 3);
|
||||
|
||||
/* Find the Panda3D applet\DefaultIcon key and extract the path to the runtime from there. */
|
||||
if (RegOpenKey (HKEY_CLASSES_ROOT, "Panda3D applet\\DefaultIcon", &hKey) == ERROR_SUCCESS) {
|
||||
dwType = REG_SZ;
|
||||
if (RegQueryValueEx(hKey, 0, 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
|
||||
for (i = dwBufSize - 1; i >= 0; --i) {
|
||||
if (buf [i] == '/' || buf [i] == '\\') {
|
||||
runtime = (char*) malloc (i + 13);
|
||||
memcpy (runtime, buf, i);
|
||||
runtime [i] = 0;
|
||||
strcat (runtime, "\\panda3d.exe");
|
||||
break;
|
||||
}
|
||||
/* Find the location of panda3d.exe using the registry path. */
|
||||
#ifdef _WIN64
|
||||
/* If we're on 64-bit Windows, try the 64-bit registry first. */
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINST_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueEx(hKey, "DisplayIcon", 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
|
||||
char *slash = strrchr(buf, '\\');
|
||||
if (slash != NULL) {
|
||||
strcpy(slash, "\\panda3d.exe");
|
||||
runtime = buf;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "Failed to read registry key. Try reinstalling the Panda3D Runtime.\n");
|
||||
return 1;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
} else {
|
||||
fprintf (stderr, "The Panda3D Runtime does not appear to be installed!\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* On 32-bit Windows, or no 64-bit Runtime installed. Try 32-bit registry. */
|
||||
if (runtime == NULL) {
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINST_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueEx(hKey, "DisplayIcon", 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
|
||||
char *slash = strrchr(buf, '\\');
|
||||
if (slash != NULL) {
|
||||
strcpy(slash, "\\panda3d.exe");
|
||||
runtime = buf;
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
/* Backward compatibility: Runtime 1.0.4 and below looked for the below key, even though the
|
||||
above keys should work fine, but let's just be certain.
|
||||
Find the Panda3D applet\DefaultIcon key and extract the path to the runtime from there. */
|
||||
if (runtime == NULL) {
|
||||
if (RegOpenKey(HKEY_CLASSES_ROOT, "Panda3D applet\\DefaultIcon", &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueEx(hKey, 0, 0, &dwType, (BYTE*) buf, &dwBufSize) == ERROR_SUCCESS) {
|
||||
char *slash = strrchr(buf, '\\');
|
||||
if (slash != NULL) {
|
||||
strcpy(slash, "\\panda3d.exe");
|
||||
runtime = buf;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Failed to read registry key. Try reinstalling the Panda3D Runtime.\n");
|
||||
return 1;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
} else {
|
||||
fprintf(stderr, "The Panda3D Runtime does not appear to be installed!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (runtime == NULL) {
|
||||
fprintf (stderr, "Failed to find panda3d.exe in registry. Try reinstalling the Panda3D Runtime.\n");
|
||||
fprintf(stderr, "Failed to find panda3d.exe in registry. Try reinstalling the Panda3D Runtime.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Build the command-line and run panda3d.exe. */
|
||||
cmd = GetCommandLine();
|
||||
newcmd = (char*) malloc (strlen(runtime) + strlen(p3dfile) + strlen (cmd) - strlen (argv[0]) + 7);
|
||||
sprintf (newcmd, "\"%s\" \"%s\" %s", runtime, p3dfile, cmd + strlen (argv[0]));
|
||||
newcmd = (char*) _alloca(strlen(runtime) + strlen(p3dfile) + strlen(cmd) - strlen (argv[0]) + 7);
|
||||
sprintf(newcmd, "\"%s\" \"%s\" %s", runtime, p3dfile, cmd + strlen(argv[0]));
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
if (CreateProcess(runtime, newcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
}
|
||||
free (newcmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ parser.add_option('-l', '--license', dest = 'license',
|
|||
default = None)
|
||||
parser.add_option('-w', '--website', dest = 'website',
|
||||
help = 'The product website',
|
||||
default = 'http://www.panda3d.org')
|
||||
default = 'https://www.panda3d.org')
|
||||
parser.add_option('', '--start', dest = 'start',
|
||||
help = 'Specify this option to add a start menu',
|
||||
action = 'store_true', default = False)
|
||||
|
|
@ -65,6 +65,9 @@ parser.add_option('', '--pvk', dest = 'pvk',
|
|||
parser.add_option('', '--mssdk', dest = 'mssdk',
|
||||
help = 'The path to the MS Platform SDK directory (Windows only). mssdk/bin should contain cabarc.exe and signcode.exe.',
|
||||
default = None)
|
||||
parser.add_option('', '--regview', dest = 'regview',
|
||||
help = 'Which registry view to use, 64 or 32.',
|
||||
default = None)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
|
|
@ -221,7 +224,7 @@ def parseDependenciesUnix(tempFile):
|
|||
filenames.append(l.strip().split(' ', 1)[0])
|
||||
return filenames
|
||||
|
||||
def addDependencies(path, pathname, file, pluginDependencies, dependentFiles):
|
||||
def addDependencies(path, pathname, file, pluginDependencies, dependentFiles, required=True):
|
||||
""" Checks the named file for DLL dependencies, and adds any
|
||||
appropriate dependencies found into pluginDependencies and
|
||||
dependentFiles. """
|
||||
|
|
@ -271,7 +274,10 @@ def addDependencies(path, pathname, file, pluginDependencies, dependentFiles):
|
|||
break
|
||||
pathname = None
|
||||
if not pathname:
|
||||
sys.exit("Couldn't find %s." % (dfile))
|
||||
if required:
|
||||
sys.exit("Couldn't find %s." % (dfile))
|
||||
sys.stderr.write("Warning: couldn't find %s." % (dfile))
|
||||
continue
|
||||
pathname = os.path.abspath(pathname)
|
||||
dependentFiles[dfilelower] = pathname
|
||||
|
||||
|
|
@ -553,6 +559,9 @@ def makeInstaller():
|
|||
CMD += '/DPANDA3DW="' + panda3dw + '" '
|
||||
CMD += '/DPANDA3DW_PATH="' + pluginFiles[panda3dw] + '" '
|
||||
|
||||
if options.regview:
|
||||
CMD += '/DREGVIEW=%s ' % (options.regview)
|
||||
|
||||
dependencies = dependentFiles.items()
|
||||
for i in range(len(dependencies)):
|
||||
CMD += '/DDEP%s="%s" ' % (i, dependencies[i][0])
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
!include "MUI.nsh"
|
||||
!include LogicLib.nsh
|
||||
!include FileAssociation.nsh
|
||||
|
||||
; Several variables are assumed to be pre-defined by the caller. See
|
||||
; make_installer.py in this directory.
|
||||
|
|
@ -9,18 +8,18 @@
|
|||
!define UNINSTALL_CONFIRM "Are you sure you want to completely remove $(^Name) and all of its components?"
|
||||
!define UNINSTALL_LINK_NAME "Uninstall"
|
||||
!define WEBSITE_LINK_NAME "Website"
|
||||
!define PLID "@panda3d.org/Panda3D Runtime,version=0.0"
|
||||
!define PLID "@panda3d.org/Panda3D Runtime"
|
||||
|
||||
; HM NIS Edit Wizard helper defines
|
||||
!define APP_INTERNAL_NAME "Panda3D"
|
||||
|
||||
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${OCX}"
|
||||
!define PRODUCT_DIR_REGKEY_PANDA3D "Software\Microsoft\Windows\CurrentVersion\App Paths\${PANDA3D}"
|
||||
!define PRODUCT_DIR_REGKEY_PANDA3DW "Software\Microsoft\Windows\CurrentVersion\App Paths\${PANDA3DW}"
|
||||
!define PRODUCT_DIR_REGKEY_OCX "Software\Microsoft\Windows\CurrentVersion\App Paths\${OCX}"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
!define PROG_GROUPNAME "${PRODUCT_NAME}"
|
||||
|
||||
!define FIREFOX_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe"
|
||||
|
||||
SetCompressor lzma
|
||||
|
||||
; MUI Settings
|
||||
|
|
@ -60,16 +59,32 @@ InstallDir "${INSTALL_DIR}"
|
|||
UninstallIcon "${INSTALL_ICON}"
|
||||
!endif
|
||||
WindowIcon on
|
||||
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
|
||||
|
||||
ShowInstDetails show
|
||||
ShowUnInstDetails show
|
||||
|
||||
Function .onInit
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
ClearErrors
|
||||
|
||||
ReadRegStr $0 ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation"
|
||||
|
||||
IfErrors +2 0
|
||||
StrCpy $INSTDIR $0
|
||||
|
||||
FunctionEnd
|
||||
|
||||
Section "MainSection" SEC01
|
||||
SetShellVarContext all
|
||||
SetOutPath "$INSTDIR"
|
||||
SetOverwrite ifdiff
|
||||
|
||||
!ifdef OCX_PATH
|
||||
File "${OCX_PATH}"
|
||||
!endif
|
||||
File "${NPAPI_PATH}"
|
||||
File "${PANDA3D_PATH}"
|
||||
File "${PANDA3DW_PATH}"
|
||||
|
|
@ -100,8 +115,6 @@ Section "MainSection" SEC01
|
|||
!ifdef DEP7P
|
||||
File "${DEP7P}"
|
||||
!endif
|
||||
|
||||
${registerExtension} "$INSTDIR\${PANDA3DW}" ".p3d" "Panda3D applet"
|
||||
|
||||
!ifdef ADD_START_MENU
|
||||
; Start->Programs links
|
||||
|
|
@ -127,14 +140,41 @@ Section -AdditionalIcons
|
|||
SectionEnd
|
||||
|
||||
Section -Post
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
WriteUninstaller "$INSTDIR\uninst.exe"
|
||||
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\${OCX}"
|
||||
|
||||
WriteRegStr HKCR ".p3d" "" "Panda3D applet"
|
||||
WriteRegStr HKCR ".p3d" "Content Type" "application/x-panda3d"
|
||||
WriteRegStr HKCR ".p3d" "PerceivedType" "application"
|
||||
WriteRegStr HKCR "Panda3D applet" "" "Panda3D applet"
|
||||
WriteRegStr HKCR "Panda3D applet\DefaultIcon" "" "$INSTDIR\${PANDA3DW}"
|
||||
WriteRegStr HKCR "Panda3D applet\shell" "" "open"
|
||||
WriteRegStr HKCR "Panda3D applet\shell\open\command" "" '"$INSTDIR\${PANDA3DW}" "%1"'
|
||||
WriteRegExpandStr HKCR "Panda3D applet\shell\open2" "" "Open &with Command Prompt"
|
||||
;WriteRegExpandStr HKCR "Panda3D applet\shell\open2" "MUIVerb" "@%SystemRoot%\System32\wshext.dll,-4511"
|
||||
WriteRegExpandStr HKCR "Panda3D applet\shell\open2\command" "" '"$INSTDIR\${PANDA3D}" "%1"'
|
||||
|
||||
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY_PANDA3D}" "" "$INSTDIR\${PANDA3D}"
|
||||
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY_PANDA3DW}" "" "$INSTDIR\${PANDA3DW}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${OCX}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PANDA3D}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoModify" 1
|
||||
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoRepair" 1
|
||||
|
||||
SectionGetSize SEC01 $0
|
||||
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "EstimatedSize" $0
|
||||
|
||||
# Delete keys we used in older versions
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_OCX}"
|
||||
DeleteRegKey HKCR "Panda3D applet\shell\edit"
|
||||
SectionEnd
|
||||
|
||||
|
||||
|
|
@ -149,16 +189,23 @@ Function un.onInit
|
|||
FunctionEnd
|
||||
|
||||
Function .onInstSuccess
|
||||
# Register ActiveX
|
||||
ExecWait 'regsvr32 /s "$INSTDIR/${OCX}"'
|
||||
# Register ActiveX
|
||||
ExecWait 'regsvr32 /s "$INSTDIR/${OCX}"'
|
||||
|
||||
# Register Mozilla Plugin
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Description" "Runs 3-D games and interactive applets"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Path" "$INSTDIR\${NPAPI}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "ProductName" "${PRODUCT_NAME_SHORT}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Vendor" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Version" "${PRODUCT_VERSION}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}\MimeTypes" "application/x-panda3d" ""
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
# Register Mozilla Plugin
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Description" "Runs 3-D games and interactive applets"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Path" "$INSTDIR\${NPAPI}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "ProductName" "${PRODUCT_NAME_SHORT}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Vendor" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}" "Version" "${PRODUCT_VERSION}"
|
||||
WriteRegStr HKLM "SOFTWARE\MozillaPlugins\${PLID}\MimeTypes\application/x-panda3d" "Description" "Panda3D applet"
|
||||
|
||||
# Remove old stuff
|
||||
DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID},version=0.0"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
|
@ -196,6 +243,10 @@ Section Uninstall
|
|||
Delete "$INSTDIR\${DEP7}"
|
||||
!endif
|
||||
|
||||
!ifdef REGVIEW
|
||||
SetRegView ${REGVIEW}
|
||||
!endif
|
||||
|
||||
# The following loop uninstalls the plugin where it may have been
|
||||
# copied into one of the Mozilla Extensions dirs. Older versions of
|
||||
# the installer would have done this, but now we just update the
|
||||
|
|
@ -215,8 +266,10 @@ Mozilla-Uninstall-Loop:
|
|||
Mozilla-Uninstall-End:
|
||||
|
||||
DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID}"
|
||||
DeleteRegKey HKLM "SOFTWARE\MozillaPlugins\${PLID},version=0.0"
|
||||
|
||||
${unregisterExtension} ".p3d" "Panda3D applet"
|
||||
DeleteRegKey HKCR ".p3d"
|
||||
DeleteRegKey HKCR "Panda3D applet"
|
||||
|
||||
# Remove the user's "Panda3D" directory, where all of the downloaded
|
||||
# contents are installed. Too bad we can't do this for every system
|
||||
|
|
@ -239,7 +292,9 @@ Mozilla-Uninstall-End:
|
|||
RMDir "$INSTDIR"
|
||||
|
||||
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_PANDA3D}"
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_PANDA3DW}"
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY_OCX}"
|
||||
SetAutoClose true
|
||||
SectionEnd
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ import __builtin__
|
|||
from StringIO import StringIO
|
||||
import marshal
|
||||
import ElementTree as ET
|
||||
from HTMLParser import HTMLParser
|
||||
import BpDb
|
||||
import unicodedata
|
||||
import bisect
|
||||
|
|
@ -4201,75 +4200,6 @@ if __debug__ and __name__ == '__main__':
|
|||
assert unescapeHtmlString('as%32df') == 'as2df'
|
||||
assert unescapeHtmlString('asdf%32') == 'asdf2'
|
||||
|
||||
class HTMLStringToElements(HTMLParser):
|
||||
def __init__(self, str, *a, **kw):
|
||||
self._elements = []
|
||||
self._elementStack = Stack()
|
||||
HTMLParser.__init__(self, *a, **kw)
|
||||
self.feed(str)
|
||||
self.close()
|
||||
|
||||
def getElements(self):
|
||||
return self._elements
|
||||
|
||||
def _handleNewElement(self, element):
|
||||
if len(self._elementStack):
|
||||
self._elementStack.top().append(element)
|
||||
else:
|
||||
self._elements.append(element)
|
||||
self._elementStack.push(element)
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
kwArgs = {}
|
||||
for name, value in attrs:
|
||||
kwArgs[name] = value
|
||||
el = ET.Element(tag, **kwArgs)
|
||||
self._handleNewElement(el)
|
||||
|
||||
def handle_data(self, data):
|
||||
# this ignores text outside of a tag
|
||||
if len(self._elementStack):
|
||||
self._elementStack.top().text = data
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
top = self._elementStack.top()
|
||||
if len(top.getchildren()) == 0:
|
||||
# insert a comment to prevent ElementTree from using <... /> convention
|
||||
# force it to create a tag closer a la </tag>
|
||||
# prevents problems in certain browsers
|
||||
if top.tag == 'script' and top.get('type') == 'text/javascript':
|
||||
if top.text == None:
|
||||
top.text = '// force tag closer'
|
||||
else:
|
||||
self.handle_comment('force tag closer')
|
||||
self._elementStack.pop()
|
||||
self._elementStack.pop()
|
||||
|
||||
def handle_comment(self, data):
|
||||
comment = ET.Comment(data)
|
||||
self._handleNewElement(comment)
|
||||
|
||||
def str2elements(str):
|
||||
return HTMLStringToElements(str).getElements()
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
s = ScratchPad()
|
||||
assert len(str2elements('')) == 0
|
||||
s.br = str2elements('<br>')
|
||||
assert len(s.br) == 1
|
||||
assert s.br[0].tag == 'br'
|
||||
s.b = str2elements('<b><br></b>')
|
||||
assert len(s.b) == 1
|
||||
assert len(s.b[0].getchildren()) == 1
|
||||
s.a = str2elements('<a href=\'/\'>test</a>')
|
||||
assert len(s.a) == 1
|
||||
assert s.a[0].get('href') == '/'
|
||||
assert s.a[0].text == 'test'
|
||||
s.c = str2elements('<!--testComment-->')
|
||||
assert len(s.c) == 1
|
||||
assert s.c[0].text == 'testComment'
|
||||
del s
|
||||
|
||||
def repeatableRepr(obj):
|
||||
if type(obj) is types.DictType:
|
||||
keys = obj.keys()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ __all__ = ['ShowBase', 'WindowControls']
|
|||
# Annoying and very noisy, but sometimes useful
|
||||
#import VerboseImport
|
||||
|
||||
from pandac.PandaModules import *
|
||||
from panda3d.core import *
|
||||
from panda3d.direct import *
|
||||
|
||||
# This needs to be available early for DirectGUI imports
|
||||
import __builtin__
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import sys
|
|||
import os
|
||||
import marshal
|
||||
import imp
|
||||
import struct
|
||||
import types
|
||||
import __builtin__
|
||||
|
||||
|
|
@ -286,7 +285,8 @@ class VFSLoader:
|
|||
code = None
|
||||
data = vfile.readFile(True)
|
||||
if data[:4] == imp.get_magic():
|
||||
t = struct.unpack('<I', data[4:8])[0]
|
||||
t = ord(data[4]) + (ord(data[5]) << 8) + \
|
||||
(ord(data[6]) << 16) + (ord(data[7]) << 24)
|
||||
if not timestamp or t == timestamp:
|
||||
code = marshal.loads(data[8:])
|
||||
else:
|
||||
|
|
@ -314,7 +314,10 @@ class VFSLoader:
|
|||
pass
|
||||
else:
|
||||
f.write('\0\0\0\0')
|
||||
f.write(struct.pack('<I', self.timestamp))
|
||||
f.write(chr(self.timestamp & 0xff) +
|
||||
chr((self.timestamp >> 8) & 0xff) +
|
||||
chr((self.timestamp >> 16) & 0xff) +
|
||||
chr((self.timestamp >> 24) & 0xff))
|
||||
f.write(marshal.dumps(code))
|
||||
f.flush()
|
||||
f.seek(0, 0)
|
||||
|
|
|
|||
|
|
@ -102,15 +102,16 @@ elif bl.endswith('.exe'):
|
|||
basename = os.path.splitext(basename)[0]
|
||||
|
||||
startfile = args[0]
|
||||
startmod = startfile
|
||||
if startfile.endswith('.py') or startfile.endswith('.pyw') or \
|
||||
startfile.endswith('.pyc') or startfile.endswith('.pyo'):
|
||||
startfile = os.path.splitext(startfile)[0]
|
||||
startmod = os.path.splitext(startfile)[0]
|
||||
|
||||
compileToExe = False
|
||||
if outputType == 'dll':
|
||||
freezer.addModule(startfile)
|
||||
freezer.addModule(startmod, filename = startfile)
|
||||
else:
|
||||
freezer.addModule(startfile, newName = '__main__')
|
||||
freezer.addModule('__main__', filename = startfile)
|
||||
compileToExe = True
|
||||
|
||||
freezer.done(compileToExe = compileToExe)
|
||||
|
|
|
|||
|
|
@ -390,11 +390,7 @@ cinf(double v) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float
|
||||
make_nan(float) {
|
||||
#ifndef _WIN32
|
||||
return nanf("");
|
||||
#else
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -403,11 +399,7 @@ make_nan(float) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double
|
||||
make_nan(double) {
|
||||
#ifndef _WIN32
|
||||
return nan("");
|
||||
#else
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -119,3 +119,23 @@ INLINE string ExecutionEnvironment::
|
|||
get_dtool_name() {
|
||||
return get_ptr()->ns_get_dtool_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ExecutionEnvironment::set_binary_name
|
||||
// Access: Public, Static
|
||||
// Description: Do not use.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ExecutionEnvironment::
|
||||
set_binary_name(const string &name) {
|
||||
get_ptr()->_binary_name = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ExecutionEnvironment::set_dtool_name
|
||||
// Access: Public, Static
|
||||
// Description: Do not use.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ExecutionEnvironment::
|
||||
set_dtool_name(const string &name) {
|
||||
get_ptr()->_dtool_name = name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
// And this is for GetModuleFileName().
|
||||
#include <windows.h>
|
||||
|
||||
// And this is for CommandLineToArgvW.
|
||||
#include <shellapi.h>
|
||||
|
||||
// SHGetSpecialFolderPath()
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
|
@ -74,12 +77,11 @@ extern char **environ;
|
|||
#define PREREAD_ENVIRONMENT
|
||||
#endif
|
||||
|
||||
|
||||
// We define the symbol HAVE_GLOBAL_ARGV if we have global variables
|
||||
// named GLOBAL_ARGC/GLOBAL_ARGV that we can read at static init time
|
||||
// to determine our command-line arguments.
|
||||
|
||||
#if defined(HAVE_GLOBAL_ARGV) && defined(PROTOTYPE_GLOBAL_ARGV)
|
||||
#if !defined(WIN32_VC) && defined(HAVE_GLOBAL_ARGV) && defined(PROTOTYPE_GLOBAL_ARGV)
|
||||
extern char **GLOBAL_ARGV;
|
||||
extern int GLOBAL_ARGC;
|
||||
#endif
|
||||
|
|
@ -298,7 +300,7 @@ ns_get_environment_variable(const string &var) const {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyGILState_Release(state);
|
||||
|
||||
if (main_dir.empty()) {
|
||||
|
|
@ -613,7 +615,7 @@ read_environment_variables() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ExecutionEnvironment::
|
||||
read_args() {
|
||||
|
||||
#ifndef ANDROID
|
||||
// First, we need to fill in _dtool_name. This contains
|
||||
// the full path to the p3dtool library.
|
||||
|
||||
|
|
@ -762,7 +764,39 @@ read_args() {
|
|||
// Next we need to fill in _args, which is a vector containing
|
||||
// the command-line arguments that the executable was invoked with.
|
||||
|
||||
#if defined(IS_FREEBSD)
|
||||
#if defined(WIN32_VC)
|
||||
|
||||
// We cannot rely on __argv when Python is linked in Unicode mode.
|
||||
// Instead, let's use GetCommandLine.
|
||||
|
||||
LPWSTR cmdline = GetCommandLineW();
|
||||
int argc = 0;
|
||||
LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
|
||||
|
||||
if (wargv == NULL) {
|
||||
cerr << "CommandLineToArgvW failed; command-line arguments unavailable to config.\n";
|
||||
|
||||
} else {
|
||||
TextEncoder encoder;
|
||||
encoder.set_encoding(Filename::get_filesystem_encoding());
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
wstring wtext(wargv[i]);
|
||||
encoder.set_wtext(wtext);
|
||||
|
||||
if (i == 0) {
|
||||
if (_binary_name.empty()) {
|
||||
_binary_name = encoder.get_text();
|
||||
}
|
||||
} else {
|
||||
_args.push_back(encoder.get_text());
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree(wargv);
|
||||
}
|
||||
|
||||
#elif defined(IS_FREEBSD)
|
||||
// In FreeBSD, we can use sysctl to determine the command-line arguments.
|
||||
|
||||
size_t bufsize = 4096;
|
||||
|
|
@ -786,13 +820,17 @@ read_args() {
|
|||
#elif defined(HAVE_GLOBAL_ARGV)
|
||||
int argc = GLOBAL_ARGC;
|
||||
|
||||
if (_binary_name.empty() && argc > 0) {
|
||||
_binary_name = GLOBAL_ARGV[0];
|
||||
// This really needs to be resolved against PATH.
|
||||
}
|
||||
// On Windows, __argv can be NULL when the main entry point is
|
||||
// compiled in Unicode mode (as is the case with Python 3)
|
||||
if (GLOBAL_ARGV != NULL) {
|
||||
if (_binary_name.empty() && argc > 0) {
|
||||
_binary_name = GLOBAL_ARGV[0];
|
||||
// This really needs to be resolved against PATH.
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
_args.push_back(GLOBAL_ARGV[i]);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
_args.push_back(GLOBAL_ARGV[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_PROC_SELF_CMDLINE) || defined(HAVE_PROC_CURPROC_CMDLINE)
|
||||
|
|
@ -835,7 +873,7 @@ read_args() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
// Try to use realpath to get cleaner paths.
|
||||
|
||||
if (!_binary_name.empty()) {
|
||||
|
|
@ -851,7 +889,9 @@ read_args() {
|
|||
_dtool_name = newpath;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // _WIN32
|
||||
|
||||
#endif // ANDROID
|
||||
|
||||
if (_dtool_name.empty()) {
|
||||
_dtool_name = _binary_name;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ PUBLISHED:
|
|||
INLINE static string get_binary_name();
|
||||
INLINE static string get_dtool_name();
|
||||
|
||||
INLINE static void set_binary_name(const string &name);
|
||||
INLINE static void set_dtool_name(const string &name);
|
||||
|
||||
static Filename get_cwd();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ TVOLATILE AtomicAdjust::Pointer Filename::_user_appdata_directory;
|
|||
TVOLATILE AtomicAdjust::Pointer Filename::_common_appdata_directory;
|
||||
TypeHandle Filename::_type_handle;
|
||||
|
||||
#ifdef ANDROID
|
||||
string Filename::_internal_data_dir;
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* begin Win32-specific code */
|
||||
|
||||
|
|
@ -463,7 +467,7 @@ Filename Filename::
|
|||
temporary(const string &dirname, const string &prefix, const string &suffix,
|
||||
Type type) {
|
||||
Filename fdirname = dirname;
|
||||
#ifdef WIN32
|
||||
#if defined(_WIN32) || defined(ANDROID)
|
||||
// The Windows tempnam() function doesn't do a good job of choosing
|
||||
// a temporary directory. Choose one ourselves.
|
||||
if (fdirname.empty()) {
|
||||
|
|
@ -527,7 +531,7 @@ get_home_directory() {
|
|||
if (home_directory.empty()) {
|
||||
#ifdef WIN32
|
||||
wchar_t buffer[MAX_PATH];
|
||||
|
||||
|
||||
// On Windows, fall back to the "My Documents" folder.
|
||||
if (SHGetSpecialFolderPathW(NULL, buffer, CSIDL_PERSONAL, true)) {
|
||||
Filename dirname = from_os_specific_w(buffer);
|
||||
|
|
@ -538,15 +542,22 @@ get_home_directory() {
|
|||
}
|
||||
}
|
||||
|
||||
#elif defined(ANDROID)
|
||||
// Temporary hack.
|
||||
home_directory = "/data/data/org.panda3d.sdk";
|
||||
|
||||
#elif defined(IS_OSX)
|
||||
home_directory = get_osx_home_directory();
|
||||
|
||||
|
||||
#elif defined(ANDROID)
|
||||
home_directory = _internal_data_dir;
|
||||
|
||||
#else
|
||||
// Posix case: check /etc/passwd?
|
||||
|
||||
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
|
||||
if (home_directory.empty()) {
|
||||
// Fallback case.
|
||||
home_directory = ExecutionEnvironment::get_cwd();
|
||||
|
|
@ -559,7 +570,7 @@ get_home_directory() {
|
|||
delete newdir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (*(Filename *)_home_directory);
|
||||
}
|
||||
|
||||
|
|
@ -589,6 +600,10 @@ get_temp_directory() {
|
|||
#elif defined(IS_OSX)
|
||||
temp_directory = get_osx_temp_directory();
|
||||
|
||||
#elif defined(ANDROID)
|
||||
temp_directory.set_dirname(_internal_data_dir);
|
||||
temp_directory.set_basename("cache");
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
temp_directory = "/tmp";
|
||||
|
|
@ -638,6 +653,10 @@ get_user_appdata_directory() {
|
|||
#elif defined(IS_OSX)
|
||||
user_appdata_directory = get_osx_user_appdata_directory();
|
||||
|
||||
#elif defined(ANDROID)
|
||||
user_appdata_directory.set_dirname(_internal_data_dir);
|
||||
user_appdata_directory.set_basename("files");
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
user_appdata_directory = get_home_directory();
|
||||
|
|
@ -687,6 +706,10 @@ get_common_appdata_directory() {
|
|||
#elif defined(IS_OSX)
|
||||
common_appdata_directory = get_osx_common_appdata_directory();
|
||||
|
||||
#elif defined(ANDROID)
|
||||
common_appdata_directory.set_dirname(_internal_data_dir);
|
||||
common_appdata_directory.set_basename("files");
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
common_appdata_directory = "/var";
|
||||
|
|
|
|||
|
|
@ -263,6 +263,11 @@ protected:
|
|||
static TVOLATILE AtomicAdjust::Pointer _user_appdata_directory;
|
||||
static TVOLATILE AtomicAdjust::Pointer _common_appdata_directory;
|
||||
|
||||
#ifdef ANDROID
|
||||
public:
|
||||
static string _internal_data_dir;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -2743,7 +2743,9 @@ int GetParnetDepth(CPPType *type) {
|
|||
} else if (TypeManager::is_wchar_pointer(type)) {
|
||||
} else if (TypeManager::is_pointer_to_PyObject(type)) {
|
||||
} else if (TypeManager::is_pointer_to_Py_buffer(type)) {
|
||||
} else if (TypeManager::is_pointer(type) || TypeManager::is_reference(type) || TypeManager::is_struct(type)) {
|
||||
} else if (TypeManager::is_pointer(type) ||
|
||||
TypeManager::is_reference(type) ||
|
||||
TypeManager::is_struct(type)) {
|
||||
++answer;
|
||||
int deepest = 0;
|
||||
TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)), false);
|
||||
|
|
@ -3276,6 +3278,36 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
|||
only_pyobjects = false;
|
||||
++num_params;
|
||||
|
||||
} else if (TypeManager::is_pointer_to_PyStringObject(type)) {
|
||||
if (args_type == AT_single_arg) {
|
||||
// This is a single-arg function, so there's no need
|
||||
// to convert anything.
|
||||
param_name = "arg";
|
||||
extra_param_check += " && PyString_Check(arg)";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyStringObject *" << param_name << ";\n";
|
||||
format_specifiers += "S";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
pexpr_string = param_name;
|
||||
expected_params += "string";
|
||||
++num_params;
|
||||
|
||||
} else if (TypeManager::is_pointer_to_PyUnicodeObject(type)) {
|
||||
if (args_type == AT_single_arg) {
|
||||
// This is a single-arg function, so there's no need
|
||||
// to convert anything.
|
||||
param_name = "arg";
|
||||
extra_param_check += " && PyUnicode_Check(arg)";
|
||||
} else {
|
||||
indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
|
||||
format_specifiers += "U";
|
||||
parameter_list += ", &" + param_name;
|
||||
}
|
||||
pexpr_string = param_name;
|
||||
expected_params += "unicode";
|
||||
++num_params;
|
||||
|
||||
} else if (TypeManager::is_pointer_to_PyObject(type)) {
|
||||
if (args_type == AT_single_arg) {
|
||||
// This is a single-arg function, so there's no need
|
||||
|
|
@ -3605,7 +3637,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
|||
if (true) {
|
||||
indent(out, indent_level)
|
||||
<< "if (PyErr_Occurred()) {\n";
|
||||
delete_return_value(out, indent_level, remap, return_expr);
|
||||
delete_return_value(out, indent_level + 2, remap, return_expr);
|
||||
indent(out, indent_level)
|
||||
<< " if (PyErr_ExceptionMatches(PyExc_TypeError)) {\n";
|
||||
indent(out, indent_level)
|
||||
|
|
|
|||
|
|
@ -1199,8 +1199,91 @@ is_PyObject(CPPType *type) {
|
|||
return is_PyObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_extension:
|
||||
case CPPDeclaration::ST_struct:
|
||||
return (type->get_local_name(&parser) == "PyObject" ||
|
||||
type->get_local_name(&parser) == "_object");
|
||||
type->get_local_name(&parser) == "PyTypeObject" ||
|
||||
type->get_local_name(&parser) == "PyStringObject" ||
|
||||
type->get_local_name(&parser) == "PyUnicodeObject" ||
|
||||
type->get_local_name(&parser) == "_object" ||
|
||||
type->get_local_name(&parser) == "_typeobject");
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_pointer_to_PyStringObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyStringObject *.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_pointer_to_PyStringObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_pointer_to_PyStringObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_pointer:
|
||||
return is_PyStringObject(type->as_pointer_type()->_pointing_at);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_PyStringObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyStringObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_PyStringObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_PyStringObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_extension:
|
||||
case CPPDeclaration::ST_struct:
|
||||
return (type->get_local_name(&parser) == "PyStringObject");
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_pointer_to_PyUnicodeObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyStringObject *.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_pointer_to_PyUnicodeObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_pointer_to_PyUnicodeObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_pointer:
|
||||
return is_PyUnicodeObject(type->as_pointer_type()->_pointing_at);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_PyUnicodeObject
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is PyUnicodeObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_PyUnicodeObject(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_PyUnicodeObject(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_extension:
|
||||
case CPPDeclaration::ST_struct:
|
||||
return (type->get_local_name(&parser) == "PyUnicodeObject");
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -1238,6 +1321,7 @@ is_Py_buffer(CPPType *type) {
|
|||
return is_Py_buffer(type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_extension:
|
||||
case CPPDeclaration::ST_struct:
|
||||
return (type->get_local_name(&parser) == "Py_buffer");
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -94,6 +94,10 @@ public:
|
|||
static bool is_const_ref_to_pointer_to_base(CPPType *type);
|
||||
static bool is_pointer_to_PyObject(CPPType *type);
|
||||
static bool is_PyObject(CPPType *type);
|
||||
static bool is_pointer_to_PyStringObject(CPPType *type);
|
||||
static bool is_PyStringObject(CPPType *type);
|
||||
static bool is_pointer_to_PyUnicodeObject(CPPType *type);
|
||||
static bool is_PyUnicodeObject(CPPType *type);
|
||||
static bool is_pointer_to_Py_buffer(CPPType *type);
|
||||
static bool is_Py_buffer(CPPType *type);
|
||||
static bool involves_unpublished(CPPType *type);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@
|
|||
struct _object;
|
||||
typedef _object PyObject;
|
||||
|
||||
struct _typeobject;
|
||||
typedef _typeobject PyTypeObject;
|
||||
|
||||
struct PyStringObject;
|
||||
struct PyUnicodeObject;
|
||||
|
||||
class PyThreadState;
|
||||
typedef int Py_ssize_t;
|
||||
struct Py_buffer;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
struct AAssetManager;
|
||||
struct AAsset;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
typedef unsigned char jboolean; /* unsigned 8 bits */
|
||||
typedef signed char jbyte; /* signed 8 bits */
|
||||
typedef unsigned short jchar; /* unsigned 16 bits */
|
||||
typedef short jshort; /* signed 16 bits */
|
||||
typedef int jint; /* signed 32 bits */
|
||||
typedef long long jlong; /* signed 64 bits */
|
||||
typedef float jfloat; /* 32-bit IEEE 754 */
|
||||
typedef double jdouble; /* 64-bit IEEE 754 */
|
||||
|
||||
typedef jint jsize;
|
||||
|
||||
typedef void* jobject;
|
||||
typedef jobject jclass;
|
||||
typedef jobject jstring;
|
||||
typedef jobject jarray;
|
||||
typedef jarray jobjectArray;
|
||||
typedef jarray jbooleanArray;
|
||||
typedef jarray jbyteArray;
|
||||
typedef jarray jcharArray;
|
||||
typedef jarray jshortArray;
|
||||
typedef jarray jintArray;
|
||||
typedef jarray jlongArray;
|
||||
typedef jarray jfloatArray;
|
||||
typedef jarray jdoubleArray;
|
||||
typedef jobject jthrowable;
|
||||
typedef jobject jweak;
|
||||
|
||||
struct _jfieldID; /* opaque structure */
|
||||
typedef struct _jfieldID* jfieldID; /* field IDs */
|
||||
|
||||
struct _jmethodID; /* opaque structure */
|
||||
typedef struct _jmethodID* jmethodID; /* method IDs */
|
||||
|
||||
struct JNIInvokeInterface;
|
||||
|
||||
struct _JNIEnv;
|
||||
struct _JavaVM;
|
||||
typedef _JNIEnv JNIEnv;
|
||||
typedef _JavaVM JavaVM;
|
||||
|
|
@ -121,6 +121,8 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyString_AsStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyString_FromString(...);
|
||||
EXPCL_PYSTUB int PyString_FromStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyString_InternFromString(...);
|
||||
EXPCL_PYSTUB int PyString_InternInPlace(...);
|
||||
EXPCL_PYSTUB int PyString_Size(...);
|
||||
EXPCL_PYSTUB int PyString_Type(...);
|
||||
EXPCL_PYSTUB int PySys_GetObject(...);
|
||||
|
|
@ -152,6 +154,8 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyUnicode_FromStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyUnicode_FromWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicode_GetSize(...);
|
||||
EXPCL_PYSTUB int PyUnicode_InternFromString(...);
|
||||
EXPCL_PYSTUB int PyUnicode_InternInPlace(...);
|
||||
EXPCL_PYSTUB int PyUnicode_Type(...);
|
||||
EXPCL_PYSTUB int Py_BuildValue(...);
|
||||
EXPCL_PYSTUB int Py_InitModule4(...);
|
||||
|
|
@ -296,6 +300,8 @@ int PyString_AsString(...) { return 0; }
|
|||
int PyString_AsStringAndSize(...) { return 0; }
|
||||
int PyString_FromString(...) { return 0; }
|
||||
int PyString_FromStringAndSize(...) { return 0; }
|
||||
int PyString_InternFromString(...) { return 0; }
|
||||
int PyString_InternInPlace(...) { return 0; }
|
||||
int PyString_Size(...) { return 0; }
|
||||
int PyString_Type(...) { return 0; }
|
||||
int PySys_GetObject(...) { return 0; }
|
||||
|
|
@ -327,6 +333,8 @@ int PyUnicode_FromString(...) { return 0; }
|
|||
int PyUnicode_FromStringAndSize(...) { return 0; }
|
||||
int PyUnicode_FromWideChar(...) { return 0; }
|
||||
int PyUnicode_GetSize(...) { return 0; }
|
||||
int PyUnicode_InternFromString(...) { return 0; }
|
||||
int PyUnicode_InternInPlace(...) { return 0; }
|
||||
int PyUnicode_Type(...) { return 0; }
|
||||
int Py_BuildValue(...) { return 0; }
|
||||
int Py_InitModule4(...) { return 0; }
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import time
|
|||
import os
|
||||
import sys
|
||||
|
||||
## jGenPyCode tries to get the directory for Direct from the sys.path. This only works if you
|
||||
## have installed the sdk using a installer. This would not work if the installer was
|
||||
## jGenPyCode tries to get the directory for Direct from the sys.path. This only works if you
|
||||
## have installed the sdk using a installer. This would not work if the installer was
|
||||
## never used and everything was grabbed into a virgin environment using cvs.
|
||||
sys.path.append(os.getcwd())
|
||||
|
||||
|
|
@ -88,14 +88,14 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
|
|||
"VRPN", "OPENSSL", # Transport
|
||||
"FFTW", # Algorithm helpers
|
||||
"ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION", # Augmented Reality
|
||||
"NPAPI", "AWESOMIUM", # Browser embedding
|
||||
"GTK2", "WX", "FLTK", # Toolkit support
|
||||
"ROCKET", # GUI libraries
|
||||
"GTK2", # GTK2 is used for PStats on Unix
|
||||
"NPAPI", "MFC", "WX", "FLTK", # Used for web plug-in only
|
||||
"ROCKET", "AWESOMIUM", # GUI libraries
|
||||
"CARBON", "COCOA", # Mac OS X toolkits
|
||||
"X11", "XF86DGA", "XRANDR", "XCURSOR", # Unix platform support
|
||||
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", # Toolchain
|
||||
"SKEL", # Example SKEL project
|
||||
"PANDAFX", # Some distortion special lenses
|
||||
"PANDAFX", # Some distortion special lenses
|
||||
"PANDAPARTICLESYSTEM", # Built in particle system
|
||||
"CONTRIB", # Experimental
|
||||
"SSE2", "NEON", # Compiler features
|
||||
|
|
@ -216,7 +216,7 @@ def parseopts(args):
|
|||
if STRDXSDKVERSION == '':
|
||||
print("No DirectX SDK version specified. Using 'default' DirectX SDK search")
|
||||
STRDXSDKVERSION = 'default'
|
||||
elif (option=="--platform-sdk"):
|
||||
elif (option=="--platform-sdk"):
|
||||
STRMSPLATFORMVERSION = value.strip().lower()
|
||||
if STRMSPLATFORMVERSION == '':
|
||||
print("No MS Platform SDK version specified. Using 'default' MS Platform SDK search")
|
||||
|
|
@ -234,7 +234,7 @@ def parseopts(args):
|
|||
if (option=="--everything" or option.startswith("--use-")
|
||||
or option=="--nothing" or option.startswith("--no-")):
|
||||
anything = 1
|
||||
except:
|
||||
except:
|
||||
usage(0)
|
||||
print("Exception while parsing commandline:", sys.exc_info()[0])
|
||||
if (anything==0): usage(0)
|
||||
|
|
@ -492,7 +492,7 @@ if (COMPILER == "MSVC"):
|
|||
LibName(pkg, 'dxerr.lib')
|
||||
else:
|
||||
LibName(pkg, 'dxerrVNUM.lib'.replace("VNUM", vnum))
|
||||
LibName(pkg, 'ddraw.lib')
|
||||
#LibName(pkg, 'ddraw.lib')
|
||||
LibName(pkg, 'dxguid.lib')
|
||||
IncDirectory("ALWAYS", GetThirdpartyDir() + "extras/include")
|
||||
LibName("WINSOCK", "wsock32.lib")
|
||||
|
|
@ -536,7 +536,6 @@ if (COMPILER == "MSVC"):
|
|||
if (PkgSkip("FFTW")==0): LibName("FFTW", GetThirdpartyDir() + "fftw/lib/fftw.lib")
|
||||
if (PkgSkip("ARTOOLKIT")==0):LibName("ARTOOLKIT",GetThirdpartyDir() + "artoolkit/lib/libAR.lib")
|
||||
if (PkgSkip("FCOLLADA")==0): LibName("FCOLLADA", GetThirdpartyDir() + "fcollada/lib/FCollada.lib")
|
||||
if (PkgSkip("SQUISH")==0): LibName("SQUISH", GetThirdpartyDir() + "squish/lib/squish.lib")
|
||||
if (PkgSkip("OPENCV")==0): LibName("OPENCV", GetThirdpartyDir() + "opencv/lib/cv.lib")
|
||||
if (PkgSkip("OPENCV")==0): LibName("OPENCV", GetThirdpartyDir() + "opencv/lib/highgui.lib")
|
||||
if (PkgSkip("OPENCV")==0): LibName("OPENCV", GetThirdpartyDir() + "opencv/lib/cvaux.lib")
|
||||
|
|
@ -548,6 +547,11 @@ if (COMPILER == "MSVC"):
|
|||
if (PkgSkip("FFMPEG")==0): LibName("FFMPEG", GetThirdpartyDir() + "ffmpeg/lib/avutil.lib")
|
||||
if (PkgSkip("SWSCALE")==0): LibName("SWSCALE", GetThirdpartyDir() + "ffmpeg/lib/swscale.lib")
|
||||
if (PkgSkip("SWRESAMPLE")==0):LibName("SWRESAMPLE",GetThirdpartyDir() + "ffmpeg/lib/swresample.lib")
|
||||
if (PkgSkip("SQUISH")==0):
|
||||
if GetOptimize() <= 2:
|
||||
LibName("SQUISH", GetThirdpartyDir() + "squish/lib/squishd.lib")
|
||||
else:
|
||||
LibName("SQUISH", GetThirdpartyDir() + "squish/lib/squish.lib")
|
||||
if (PkgSkip("ROCKET")==0):
|
||||
LibName("ROCKET", GetThirdpartyDir() + "rocket/lib/RocketCore.lib")
|
||||
LibName("ROCKET", GetThirdpartyDir() + "rocket/lib/RocketControls.lib")
|
||||
|
|
@ -663,21 +667,6 @@ if (COMPILER=="GCC"):
|
|||
IncDirectory("ALWAYS", "/usr/local/include")
|
||||
LibDirectory("ALWAYS", "/usr/local/lib")
|
||||
|
||||
if GetHost() != "darwin":
|
||||
# Workaround for an issue where pkg-config does not include this path
|
||||
if GetTargetArch() in ("x86_64", "amd64"):
|
||||
if (os.path.isdir("/usr/lib64/glib-2.0/include")):
|
||||
IncDirectory("GTK2", "/usr/lib64/glib-2.0/include")
|
||||
if (os.path.isdir("/usr/lib64/gtk-2.0/include")):
|
||||
IncDirectory("GTK2", "/usr/lib64/gtk-2.0/include")
|
||||
|
||||
if (os.path.isdir("/usr/X11R6/lib64")):
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib64")
|
||||
else:
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib")
|
||||
else:
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib")
|
||||
|
||||
fcollada_libs = ("FColladaD", "FColladaSD", "FColladaS")
|
||||
# WARNING! The order of the ffmpeg libraries matters!
|
||||
ffmpeg_libs = ("libavformat", "libavcodec", "libavutil")
|
||||
|
|
@ -752,6 +741,22 @@ if (COMPILER=="GCC"):
|
|||
SmartPkgEnable("XF86DGA", "xxf86dga", "Xxf86dga", "X11/extensions/xf86dga.h")
|
||||
SmartPkgEnable("XCURSOR", "xcursor", "Xcursor", "X11/Xcursor/Xcursor.h")
|
||||
|
||||
if GetHost() != "darwin":
|
||||
# Workaround for an issue where pkg-config does not include this path
|
||||
if GetTargetArch() in ("x86_64", "amd64"):
|
||||
if (os.path.isdir("/usr/lib64/glib-2.0/include")):
|
||||
IncDirectory("GTK2", "/usr/lib64/glib-2.0/include")
|
||||
if (os.path.isdir("/usr/lib64/gtk-2.0/include")):
|
||||
IncDirectory("GTK2", "/usr/lib64/gtk-2.0/include")
|
||||
|
||||
if not PkgSkip("X11"):
|
||||
if (os.path.isdir("/usr/X11R6/lib64")):
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib64")
|
||||
else:
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib")
|
||||
elif not PkgSkip("X11"):
|
||||
LibDirectory("ALWAYS", "/usr/X11R6/lib")
|
||||
|
||||
if (RUNTIME):
|
||||
# For the runtime, all packages are required
|
||||
for pkg in ["OPENSSL", "ZLIB", "NPAPI", "JPEG", "PNG"]:
|
||||
|
|
@ -924,7 +929,7 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += "/DWINVER=0x601 "
|
||||
cmd += "/Fo" + obj + " /nologo /c"
|
||||
if (GetTargetArch() != 'x64' and PkgSkip("SSE2") == 0):
|
||||
cmd += " /arch:SSE2"
|
||||
cmd += " /arch:SSE2"
|
||||
for x in ipath: cmd += " /I" + x
|
||||
for (opt,dir) in INCDIRECTORIES:
|
||||
if (opt=="ALWAYS") or (opt in opts): cmd += " /I" + BracketNameWithQuotes(dir)
|
||||
|
|
@ -936,7 +941,7 @@ def CompileCxx(obj,src,opts):
|
|||
if (optlevel==1): cmd += " /MDd /Zi /RTCs /GS"
|
||||
if (optlevel==2): cmd += " /MDd /Zi"
|
||||
if (optlevel==3): cmd += " /MD /Zi /O2 /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING"
|
||||
if (optlevel==4):
|
||||
if (optlevel==4):
|
||||
cmd += " /MD /Zi /Ox /Ob2 /Oi /Ot /fp:fast /DFORCE_INLINING /DNDEBUG /GL"
|
||||
cmd += " /Oy /Zp16" # jean-claude add /Zp16 insures correct static alignment for SSEx
|
||||
|
||||
|
|
@ -982,11 +987,11 @@ def CompileCxx(obj,src,opts):
|
|||
if (optlevel==3):
|
||||
cmd += " /MD /Zi /O2 /Oi /Ot /arch:SSE3"
|
||||
cmd += " /Ob0"
|
||||
cmd += " /Qipo-" # beware of IPO !!!
|
||||
cmd += " /Qipo-" # beware of IPO !!!
|
||||
## Lesson learned: Don't use /GL flag -> end result is MESSY
|
||||
## ----------------------------------------------------------------
|
||||
if (optlevel==4):
|
||||
cmd += " /MD /Zi /O3 /Oi /Ot /Ob0 /Yc /DNDEBUG" # /Ob0 a ete rajoute en cours de route a 47%
|
||||
cmd += " /MD /Zi /O3 /Oi /Ot /Ob0 /Yc /DNDEBUG" # /Ob0 a ete rajoute en cours de route a 47%
|
||||
cmd += " /Qipo" # optimization multi file
|
||||
|
||||
# for 3 & 4 optimization levels
|
||||
|
|
@ -998,7 +1003,7 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += " /Qopt-matmul" # needs /O2 or /O3
|
||||
cmd += " /Qprec-div-"
|
||||
cmd += " /Qsimd"
|
||||
|
||||
|
||||
cmd += " /QxHost" # compile for target host; Compiling for distribs should probably strictly enforce /arch:..
|
||||
cmd += " /Quse-intel-optimized-headers" # use intel optimized headers
|
||||
cmd += " /Qparallel" # enable parallelization
|
||||
|
|
@ -1006,7 +1011,7 @@ def CompileCxx(obj,src,opts):
|
|||
|
||||
## PCH files coexistence: the /Qpchi option causes the Intel C++ Compiler to name its
|
||||
## PCH files with a .pchi filename suffix and reduce build time.
|
||||
## The /Qpchi option is on by default but interferes with Microsoft libs; so use /Qpchi- to turn it off.
|
||||
## The /Qpchi option is on by default but interferes with Microsoft libs; so use /Qpchi- to turn it off.
|
||||
## I need to have a deeper look at this since the compile time is quite influenced by this setting !!!
|
||||
cmd += " /Qpchi-" # keep it this way!
|
||||
|
||||
|
|
@ -1024,7 +1029,7 @@ def CompileCxx(obj,src,opts):
|
|||
## Use this option if you always define a class before you declare a pointer to a member of the class.
|
||||
## The compiler will issue an error if it encounters a pointer declaration before the class is defined.
|
||||
## Alternate: #pragma pointers_to_members
|
||||
|
||||
|
||||
cmd += " /Fd" + os.path.splitext(obj)[0] + ".pdb"
|
||||
building = GetValueOption(opts, "BUILDING:")
|
||||
if (building): cmd += " /DBUILDING_" + building
|
||||
|
|
@ -1032,10 +1037,10 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += " /bigobj"
|
||||
|
||||
# level of warnings and optimization reports
|
||||
if GetVerbose():
|
||||
if GetVerbose():
|
||||
cmd += " /W3 " # or /W4 or /Wall
|
||||
cmd += " /Qopt-report:2 /Qopt-report-phase:hlo /Qopt-report-phase:hpo" # some optimization reports
|
||||
else:
|
||||
else:
|
||||
cmd += " /W1 "
|
||||
cmd += " /EHa /Zm300 /DWIN32_VC /DWIN32"
|
||||
if GetTargetArch() == 'x64':
|
||||
|
|
@ -1043,10 +1048,10 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += " " + BracketNameWithQuotes(src)
|
||||
|
||||
oscmd(cmd)
|
||||
|
||||
|
||||
if (COMPILER=="GCC"):
|
||||
if (src.endswith(".c")): cmd = GetCC() +' -fPIC -c -o ' + obj
|
||||
else: cmd = GetCXX()+' -ftemplate-depth-30 -fPIC -c -o ' + obj
|
||||
else: cmd = GetCXX()+' -ftemplate-depth-50 -fPIC -c -o ' + obj
|
||||
for (opt, dir) in INCDIRECTORIES:
|
||||
if (opt=="ALWAYS") or (opt in opts): cmd += ' -I' + BracketNameWithQuotes(dir)
|
||||
for (opt,var,val) in DEFSYMBOLS:
|
||||
|
|
@ -1070,9 +1075,12 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += ' --sysroot=%s -no-canonical-prefixes' % (SDK["SYSROOT"])
|
||||
|
||||
# Android-specific flags.
|
||||
arch = GetTargetArch()
|
||||
|
||||
if GetTarget() == "android":
|
||||
cmd += ' -I%s/include' % (SDK["ANDROID_STL"])
|
||||
cmd += ' -I%s/libs/%s/include' % (SDK["ANDROID_STL"], SDK["ANDROID_ABI"])
|
||||
cmd += ' -ffunction-sections -funwind-tables'
|
||||
arch = GetTargetArch()
|
||||
if arch == 'armv7a':
|
||||
cmd += ' -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__'
|
||||
cmd += ' -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16'
|
||||
|
|
@ -1111,9 +1119,9 @@ def CompileCxx(obj,src,opts):
|
|||
else:
|
||||
cmd += " -pthread"
|
||||
|
||||
if PkgSkip("SSE2") == 0:
|
||||
if PkgSkip("SSE2") == 0 and not arch.startswith("arm"):
|
||||
cmd += " -msse2"
|
||||
|
||||
|
||||
if (optlevel==1): cmd += " -ggdb -D_DEBUG"
|
||||
if (optlevel==2): cmd += " -O1 -D_DEBUG"
|
||||
if (optlevel==3): cmd += " -O2"
|
||||
|
|
@ -1217,7 +1225,7 @@ def CompileIgate(woutd,wsrc,opts):
|
|||
# NOTE: this 1600 value is the version number for VC2010.
|
||||
cmd += ' -D_MSC_VER=1600 -D"_declspec(param)=" -D_near -D_far -D__near -D__far -D__stdcall'
|
||||
if (COMPILER=="GCC"):
|
||||
cmd += ' -DCPPPARSER -D__STDC__=1 -D__cplusplus -D__inline -D__const=const'
|
||||
cmd += ' -DCPPPARSER -D__STDC__=1 -D__cplusplus -D__inline -D__const=const -D__attribute__\(x\)='
|
||||
if GetTargetArch() in ("x86_64", "amd64"):
|
||||
cmd += ' -D_LP64'
|
||||
else:
|
||||
|
|
@ -1339,7 +1347,7 @@ def CompileLink(dll, obj, opts):
|
|||
if ("MFC" not in opts):
|
||||
cmd += " /NOD:MFC90.LIB /NOD:MFC80.LIB /NOD:LIBCMT"
|
||||
cmd += " /NOD:LIBCI.LIB /DEBUG"
|
||||
cmd += " /nod:libc /nod:libcmtd /nod:atlthunk /nod:atls"
|
||||
cmd += " /nod:libc /nod:libcmtd /nod:atlthunk /nod:atls /nod:atlsd"
|
||||
if (GetOrigExt(dll) != ".exe"): cmd += " /DLL"
|
||||
optlevel = GetOptimizeOption(opts)
|
||||
if (optlevel==1): cmd += " /MAP /MAPINFO:EXPORTS /NOD:MSVCRT.LIB /NOD:MSVCPRT.LIB /NOD:MSVCIRT.LIB"
|
||||
|
|
@ -1390,7 +1398,7 @@ def CompileLink(dll, obj, opts):
|
|||
oscmd(cmd)
|
||||
else:
|
||||
cmd = "xilink"
|
||||
if GetVerbose(): cmd += " /verbose:lib"
|
||||
if GetVerbose(): cmd += " /verbose:lib"
|
||||
if HasTargetArch():
|
||||
cmd += " /MACHINE:" + GetTargetArch().upper()
|
||||
if ("MFC" not in opts):
|
||||
|
|
@ -1495,7 +1503,7 @@ def CompileLink(dll, obj, opts):
|
|||
|
||||
# Android-specific flags.
|
||||
if GetTarget() == 'android':
|
||||
cmd += " -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
|
||||
cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
|
||||
if GetTargetArch() == 'armv7a':
|
||||
cmd += " -march=armv7-a -Wl,--fix-cortex-a8"
|
||||
cmd += ' -lc -lm'
|
||||
|
|
@ -2130,7 +2138,7 @@ def WriteConfigSettings():
|
|||
|
||||
if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"):
|
||||
dtool_config["HAVE_WIN_TOUCHINPUT"] = '1'
|
||||
|
||||
|
||||
if (GetOptimize() <= 3):
|
||||
dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
|
||||
|
||||
|
|
@ -3168,6 +3176,7 @@ if (not RUNTIME):
|
|||
TargetAdd('libp3gobj.in', opts=['IMOD:panda3d.core', 'ILIB:libp3gobj', 'SRCDIR:panda/src/gobj'])
|
||||
TargetAdd('libp3gobj_igate.obj', input='libp3gobj.in', opts=["DEPENDENCYONLY"])
|
||||
TargetAdd('p3gobj_geomVertexArrayData_ext.obj', opts=OPTS, input='geomVertexArrayData_ext.cxx')
|
||||
TargetAdd('p3gobj_internalName_ext.obj', opts=OPTS, input='internalName_ext.cxx')
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/pgraphnodes/
|
||||
|
|
@ -3539,6 +3548,7 @@ if (not RUNTIME):
|
|||
TargetAdd('libpanda.dll', input='p3putil_typedWritable_ext.obj')
|
||||
TargetAdd('libpanda.dll', input='p3pnmimage_pfmFile_ext.obj')
|
||||
TargetAdd('libpanda.dll', input='p3gobj_geomVertexArrayData_ext.obj')
|
||||
TargetAdd('libpanda.dll', input='p3gobj_internalName_ext.obj')
|
||||
TargetAdd('libpanda.dll', input='p3pgraph_ext_composite.obj')
|
||||
TargetAdd('libpanda.dll', input='p3display_graphicsStateGuardian_ext.obj')
|
||||
|
||||
|
|
@ -3825,16 +3835,15 @@ if (PkgSkip("OPENSSL")==0 and not RTDIST and not RUNTIME and PkgSkip("DEPLOYTOOL
|
|||
TargetAdd('build_patch.exe', input=COMMON_PANDA_LIBS_PYSTUB)
|
||||
TargetAdd('build_patch.exe', opts=OPTS)
|
||||
|
||||
if not PkgSkip("ZLIB"):
|
||||
TargetAdd('check_adler_check_adler.obj', opts=OPTS, input='check_adler.cxx')
|
||||
TargetAdd('check_adler.exe', input=['check_adler_check_adler.obj'])
|
||||
TargetAdd('check_adler.exe', input=COMMON_PANDA_LIBS_PYSTUB)
|
||||
TargetAdd('check_adler.exe', opts=OPTS)
|
||||
TargetAdd('check_adler_check_adler.obj', opts=OPTS, input='check_adler.cxx')
|
||||
TargetAdd('check_adler.exe', input=['check_adler_check_adler.obj'])
|
||||
TargetAdd('check_adler.exe', input=COMMON_PANDA_LIBS_PYSTUB)
|
||||
TargetAdd('check_adler.exe', opts=OPTS)
|
||||
|
||||
TargetAdd('check_crc_check_crc.obj', opts=OPTS, input='check_crc.cxx')
|
||||
TargetAdd('check_crc.exe', input=['check_crc_check_crc.obj'])
|
||||
TargetAdd('check_crc.exe', input=COMMON_PANDA_LIBS_PYSTUB)
|
||||
TargetAdd('check_crc.exe', opts=OPTS)
|
||||
TargetAdd('check_crc_check_crc.obj', opts=OPTS, input='check_crc.cxx')
|
||||
TargetAdd('check_crc.exe', input=['check_crc_check_crc.obj'])
|
||||
TargetAdd('check_crc.exe', input=COMMON_PANDA_LIBS_PYSTUB)
|
||||
TargetAdd('check_crc.exe', opts=OPTS)
|
||||
|
||||
TargetAdd('check_md5_check_md5.obj', opts=OPTS, input='check_md5.cxx')
|
||||
TargetAdd('check_md5.exe', input=['check_md5_check_md5.obj'])
|
||||
|
|
@ -4470,7 +4479,7 @@ if (PkgSkip("DIRECT")==0):
|
|||
TargetAdd('packpanda.obj', opts=OPTS+['BUILDING:PACKPANDA'], input='ppython.cxx')
|
||||
TargetAdd('packpanda.exe', input='packpanda.obj')
|
||||
TargetAdd('packpanda.exe', opts=['PYTHON'])
|
||||
|
||||
|
||||
DefSymbol("BUILDING:EGGCACHER", "IMPORT_MODULE", "direct.directscripts.eggcacher")
|
||||
TargetAdd('eggcacher.obj', opts=OPTS+['BUILDING:EGGCACHER'], input='ppython.cxx')
|
||||
TargetAdd('eggcacher.exe', input='eggcacher.obj')
|
||||
|
|
@ -4738,7 +4747,7 @@ if (RUNTIME and PkgSkip("NPAPI")==0):
|
|||
# DIRECTORY: direct/src/plugin_activex/
|
||||
#
|
||||
|
||||
if (RUNTIME and GetTarget() == 'windows'):
|
||||
if (RUNTIME and GetTarget() == 'windows' and PkgSkip("MFC")==0):
|
||||
OPTS=['DIR:direct/src/plugin_activex', 'RUNTIME', 'ACTIVEX', 'MFC']
|
||||
DefSymbol('ACTIVEX', '_USRDLL', '')
|
||||
DefSymbol('ACTIVEX', '_WINDLL', '')
|
||||
|
|
@ -5805,7 +5814,7 @@ if (PkgSkip("PYTHON")==0 and not RUNTIME):
|
|||
TargetAdd('PandaModules.py', input='fx.pyd')
|
||||
if (PkgSkip("DIRECT")==0):
|
||||
TargetAdd('PandaModules.py', input='direct.pyd')
|
||||
if (PkgSkip("VISION")==0):
|
||||
if (PkgSkip("VISION")==0):
|
||||
TargetAdd('PandaModules.py', input='vision.pyd')
|
||||
if (PkgSkip("SKEL")==0):
|
||||
TargetAdd('PandaModules.py', input='skel.pyd')
|
||||
|
|
@ -6042,11 +6051,25 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
|||
elif (os.path.isdir(file)):
|
||||
shutil.rmtree(file)
|
||||
|
||||
if GetTargetArch() == 'x64':
|
||||
regview = '64'
|
||||
else:
|
||||
regview = '32'
|
||||
|
||||
if (RUNTIME):
|
||||
# Invoke the make_installer script.
|
||||
AddToPathEnv("PATH", GetOutputDir() + "\\bin")
|
||||
AddToPathEnv("PATH", GetOutputDir() + "\\plugins")
|
||||
oscmd(sys.executable + " -B direct\\src\\plugin_installer\\make_installer.py --version %s" % VERSION)
|
||||
|
||||
cmd = sys.executable + " -B -u direct\\src\\plugin_installer\\make_installer.py"
|
||||
cmd += " --version %s --regview %s" % (VERSION, regview)
|
||||
|
||||
if GetTargetArch() == 'x64':
|
||||
cmd += " --install \"$PROGRAMFILES64\\Panda3D\" "
|
||||
else:
|
||||
cmd += " --install \"$PROGRAMFILES32\\Panda3D\" "
|
||||
|
||||
oscmd(cmd)
|
||||
shutil.move("direct\\src\\plugin_installer\\p3d-setup.exe", file)
|
||||
return
|
||||
|
||||
|
|
@ -6059,11 +6082,6 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
|||
psource = os.path.abspath(".")
|
||||
panda = os.path.abspath(GetOutputDir())
|
||||
|
||||
if GetTargetArch() == 'x64':
|
||||
regview = '64'
|
||||
else:
|
||||
regview = '32'
|
||||
|
||||
nsis_defs = {
|
||||
'COMPRESSOR' : COMPRESSOR,
|
||||
'NAME' : fullname,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ HAS_TARGET_ARCH = False
|
|||
TOOLCHAIN_PREFIX = ""
|
||||
ANDROID_ABI = None
|
||||
SYS_LIB_DIRS = []
|
||||
DEBUG_DEPENDENCIES = False
|
||||
|
||||
# Is the current Python a 32-bit or 64-bit build? There doesn't
|
||||
# appear to be a universal test for this.
|
||||
|
|
@ -220,7 +221,7 @@ def ProgressOutput(progress, msg, target = None):
|
|||
prefix = "%s[%s %d%%%s] " % (GetColor("yellow"), GetColor("cyan"), progress, GetColor("yellow"))
|
||||
else:
|
||||
global THREADS
|
||||
|
||||
|
||||
ident = thread.get_ident()
|
||||
if (ident not in THREADS):
|
||||
THREADS[ident] = len(THREADS) + 1
|
||||
|
|
@ -468,7 +469,7 @@ def LocateBinary(binary):
|
|||
p = os.environ["PATH"]
|
||||
|
||||
pathList = p.split(os.pathsep)
|
||||
|
||||
|
||||
if GetHost() == 'windows':
|
||||
if not binary.endswith('.exe'):
|
||||
# Append .exe if necessary
|
||||
|
|
@ -652,7 +653,10 @@ def NeedsBuild(files, others):
|
|||
for file in files:
|
||||
dates[file] = GetTimestamp(file)
|
||||
if not os.path.exists(file):
|
||||
if DEBUG_DEPENDENCIES:
|
||||
print("rebuilding %s because it does not exist" % (file))
|
||||
return True
|
||||
|
||||
for file in others:
|
||||
dates[file] = GetTimestamp(file)
|
||||
|
||||
|
|
@ -661,6 +665,16 @@ def NeedsBuild(files, others):
|
|||
cached = BUILTFROMCACHE[key]
|
||||
if cached == dates:
|
||||
return False
|
||||
elif DEBUG_DEPENDENCIES:
|
||||
print("rebuilding %s because:" % (key))
|
||||
for key in frozenset(cached.keys()) | frozenset(dates.keys()):
|
||||
if key not in cached:
|
||||
print(" new dependency: %s" % (key))
|
||||
elif key not in dates:
|
||||
print(" removed dependency: %s" % (key))
|
||||
elif cached[key] != dates[key]:
|
||||
print(" dependency changed: %s" % (key))
|
||||
|
||||
if VERBOSE and frozenset(cached) != frozenset(dates):
|
||||
print("%sWARNING:%s file dependencies changed: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), files, GetColor()))
|
||||
|
||||
|
|
@ -857,7 +871,7 @@ def CxxCalcDependencies(srcfile, ipath, ignore):
|
|||
########################################################################
|
||||
|
||||
if sys.platform == "win32":
|
||||
# Note: not supported on cygwin.
|
||||
# Note: not supported on cygwin.
|
||||
if sys.version_info >= (3, 0):
|
||||
import winreg
|
||||
else:
|
||||
|
|
@ -1118,7 +1132,7 @@ def GetThirdpartyBase():
|
|||
THIRDPARTYBASE = "thirdparty"
|
||||
if "MAKEPANDA_THIRDPARTY" in os.environ:
|
||||
THIRDPARTYBASE = os.environ["MAKEPANDA_THIRDPARTY"]
|
||||
|
||||
|
||||
return THIRDPARTYBASE
|
||||
|
||||
def GetThirdpartyDir():
|
||||
|
|
@ -1181,40 +1195,44 @@ def GetThirdpartyDir():
|
|||
########################################################################
|
||||
|
||||
def GetOutputDir():
|
||||
return OUTPUTDIR
|
||||
return OUTPUTDIR
|
||||
|
||||
def IsCustomOutputDir():
|
||||
return CUSTOM_OUTPUTDIR
|
||||
return CUSTOM_OUTPUTDIR
|
||||
|
||||
def SetOutputDir(outputdir):
|
||||
global OUTPUTDIR, CUSTOM_OUTPUTDIR
|
||||
OUTPUTDIR=outputdir
|
||||
CUSTOM_OUTPUTDIR=True
|
||||
global OUTPUTDIR, CUSTOM_OUTPUTDIR
|
||||
OUTPUTDIR = outputdir
|
||||
CUSTOM_OUTPUTDIR = True
|
||||
|
||||
def GetOptimize():
|
||||
return int(OPTIMIZE)
|
||||
return int(OPTIMIZE)
|
||||
|
||||
def SetOptimize(optimize):
|
||||
global OPTIMIZE
|
||||
OPTIMIZE=optimize
|
||||
global OPTIMIZE
|
||||
OPTIMIZE = optimize
|
||||
|
||||
def GetVerbose():
|
||||
return VERBOSE
|
||||
return VERBOSE
|
||||
|
||||
def SetVerbose(verbose):
|
||||
global VERBOSE
|
||||
VERBOSE=verbose
|
||||
global VERBOSE
|
||||
VERBOSE = verbose
|
||||
|
||||
def SetDebugDependencies(dd = True):
|
||||
global DEBUG_DEPENDENCIES
|
||||
DEBUG_DEPENDENCIES = dd
|
||||
|
||||
def GetLinkAllStatic():
|
||||
return LINK_ALL_STATIC
|
||||
return LINK_ALL_STATIC
|
||||
|
||||
def SetLinkAllStatic(val = True):
|
||||
global LINK_ALL_STATIC
|
||||
LINK_ALL_STATIC = val
|
||||
global LINK_ALL_STATIC
|
||||
LINK_ALL_STATIC = val
|
||||
|
||||
def UnsetLinkAllStatic():
|
||||
global LINK_ALL_STATIC
|
||||
LINK_ALL_STATIC = False
|
||||
global LINK_ALL_STATIC
|
||||
LINK_ALL_STATIC = False
|
||||
|
||||
########################################################################
|
||||
##
|
||||
|
|
@ -1292,7 +1310,7 @@ def OverrideValue(parameter, value):
|
|||
def PkgConfigHavePkg(pkgname, tool = "pkg-config"):
|
||||
"""Returns a bool whether the pkg-config package is installed."""
|
||||
|
||||
if (sys.platform == "win32" or not LocateBinary(tool)):
|
||||
if (sys.platform == "win32" or CrossCompiling() or not LocateBinary(tool)):
|
||||
return False
|
||||
if (tool == "pkg-config"):
|
||||
handle = os.popen(LocateBinary("pkg-config") + " --silence-errors --modversion " + pkgname)
|
||||
|
|
@ -1307,7 +1325,7 @@ def PkgConfigHavePkg(pkgname, tool = "pkg-config"):
|
|||
def PkgConfigGetLibs(pkgname, tool = "pkg-config"):
|
||||
"""Returns a list of libs for the package, prefixed by -l."""
|
||||
|
||||
if (sys.platform == "win32" or not LocateBinary(tool)):
|
||||
if (sys.platform == "win32" or CrossCompiling() or not LocateBinary(tool)):
|
||||
return []
|
||||
if (tool == "pkg-config"):
|
||||
handle = os.popen(LocateBinary("pkg-config") + " --silence-errors --libs-only-l " + pkgname)
|
||||
|
|
@ -1338,7 +1356,7 @@ def PkgConfigGetLibs(pkgname, tool = "pkg-config"):
|
|||
def PkgConfigGetIncDirs(pkgname, tool = "pkg-config"):
|
||||
"""Returns a list of includes for the package, NOT prefixed by -I."""
|
||||
|
||||
if (sys.platform == "win32" or not LocateBinary(tool)):
|
||||
if (sys.platform == "win32" or CrossCompiling() or not LocateBinary(tool)):
|
||||
return []
|
||||
if (tool == "pkg-config"):
|
||||
handle = os.popen(LocateBinary("pkg-config") + " --silence-errors --cflags-only-I " + pkgname)
|
||||
|
|
@ -1359,7 +1377,7 @@ def PkgConfigGetIncDirs(pkgname, tool = "pkg-config"):
|
|||
def PkgConfigGetLibDirs(pkgname, tool = "pkg-config"):
|
||||
"""Returns a list of library paths for the package, NOT prefixed by -L."""
|
||||
|
||||
if (sys.platform == "win32" or not LocateBinary(tool)):
|
||||
if (sys.platform == "win32" or CrossCompiling() or not LocateBinary(tool)):
|
||||
return []
|
||||
if (tool == "pkg-config"):
|
||||
handle = os.popen(LocateBinary("pkg-config") + " --silence-errors --libs-only-L " + pkgname)
|
||||
|
|
@ -1379,7 +1397,7 @@ def PkgConfigGetLibDirs(pkgname, tool = "pkg-config"):
|
|||
def PkgConfigGetDefSymbols(pkgname, tool = "pkg-config"):
|
||||
"""Returns a dictionary of preprocessor definitions."""
|
||||
|
||||
if (sys.platform == "win32" or not LocateBinary(tool)):
|
||||
if (sys.platform == "win32" or CrossCompiling() or not LocateBinary(tool)):
|
||||
return []
|
||||
if (tool == "pkg-config"):
|
||||
handle = os.popen(LocateBinary("pkg-config") + " --silence-errors --cflags " + pkgname)
|
||||
|
|
@ -1411,7 +1429,6 @@ def PkgConfigEnable(opt, pkgname, tool = "pkg-config"):
|
|||
|
||||
def LibraryExists(lib, lpath=[]):
|
||||
""" Returns True if this library was found in the given search path, False otherwise. """
|
||||
|
||||
target = GetTarget()
|
||||
|
||||
for dir in lpath:
|
||||
|
|
@ -1517,6 +1534,7 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
|
|||
for d, v in defs.values():
|
||||
DefSymbol(target_pkg, d, v)
|
||||
return
|
||||
|
||||
elif (GetHost() == "darwin" and framework != None):
|
||||
if (os.path.isdir("/Library/Frameworks/%s.framework" % framework) or
|
||||
os.path.isdir("/System/Library/Frameworks/%s.framework" % framework) or
|
||||
|
|
@ -1532,6 +1550,7 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
|
|||
print("%sERROR:%s Could not locate framework %s, aborting build" % (GetColor("red"), GetColor(), framework))
|
||||
exit()
|
||||
return
|
||||
|
||||
elif (LocateBinary(tool) != None and (tool != "pkg-config" or pkgconfig != None)):
|
||||
if (isinstance(pkgconfig, str) or tool != "pkg-config"):
|
||||
if (PkgConfigHavePkg(pkgconfig, tool)):
|
||||
|
|
@ -1553,6 +1572,7 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
|
|||
else:
|
||||
print("%sERROR:%s Could not locate pkg-config package %s, aborting build" % (GetColor("red"), GetColor(), pkgconfig))
|
||||
exit()
|
||||
|
||||
else:
|
||||
# Okay, our pkg-config attempts failed. Let's try locating the libs by ourselves.
|
||||
have_pkg = True
|
||||
|
|
@ -1825,56 +1845,84 @@ def SdkLocateMax():
|
|||
SDK[version+"CS"] = top + subdir
|
||||
|
||||
def SdkLocatePython(force_use_sys_executable = False):
|
||||
if (PkgSkip("PYTHON")==0):
|
||||
if GetTarget() != GetHost():
|
||||
exit('Use --no-python when cross-compiling until support has been added')
|
||||
if PkgSkip("PYTHON"):
|
||||
SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
|
||||
return
|
||||
|
||||
if (GetTarget() == 'windows' and not force_use_sys_executable):
|
||||
SDK["PYTHON"] = GetThirdpartyBase()+"/win-python"
|
||||
if (GetOptimize() <= 2):
|
||||
SDK["PYTHON"] += "-dbg"
|
||||
if (GetTargetArch() == 'x64' and os.path.isdir(SDK["PYTHON"] + "-x64")):
|
||||
SDK["PYTHON"] += "-x64"
|
||||
if CrossCompiling():
|
||||
force_use_sys_executable = False
|
||||
|
||||
SDK["PYTHONEXEC"] = SDK["PYTHON"].replace('/', '\\') + "\\python"
|
||||
if (GetOptimize() <= 2):
|
||||
SDK["PYTHONEXEC"] += "_d.exe"
|
||||
else:
|
||||
SDK["PYTHONEXEC"] += ".exe"
|
||||
|
||||
if (not os.path.isfile(SDK["PYTHONEXEC"])):
|
||||
exit("Could not find %s!" % SDK["PYTHONEXEC"])
|
||||
|
||||
# Determine which version it is by checking which dll is in the directory.
|
||||
if (GetOptimize() <= 2):
|
||||
py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]_d.dll")
|
||||
else:
|
||||
py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9].dll")
|
||||
|
||||
if len(py_dlls) == 0:
|
||||
exit("Could not find the Python dll in %s." % (SDK["PYTHON"]))
|
||||
elif len(py_dlls) > 1:
|
||||
exit("Found multiple Python dlls in %s." % (SDK["PYTHON"]))
|
||||
|
||||
py_dll = os.path.basename(py_dlls[0])
|
||||
SDK["PYTHONVERSION"] = "python" + py_dll[6] + "." + py_dll[7]
|
||||
|
||||
elif (GetTarget() == 'windows'):
|
||||
SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
|
||||
SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
|
||||
SDK["PYTHONEXEC"] = sys.executable
|
||||
if (GetTarget() == 'windows' and not force_use_sys_executable):
|
||||
SDK["PYTHON"] = GetThirdpartyBase() + "/win-python"
|
||||
if (GetOptimize() <= 2):
|
||||
SDK["PYTHON"] += "-dbg"
|
||||
if (GetTargetArch() == 'x64' and os.path.isdir(SDK["PYTHON"] + "-x64")):
|
||||
SDK["PYTHON"] += "-x64"
|
||||
|
||||
SDK["PYTHONEXEC"] = SDK["PYTHON"].replace('/', '\\') + "\\python"
|
||||
if (GetOptimize() <= 2):
|
||||
SDK["PYTHONEXEC"] += "_d.exe"
|
||||
else:
|
||||
SDK["PYTHON"] = sysconfig.get_python_inc()
|
||||
SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
|
||||
SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
|
||||
SDK["PYTHONEXEC"] += ".exe"
|
||||
|
||||
if GetVerbose():
|
||||
print("Using Python %s build located at %s" % (SDK["PYTHONVERSION"][6:9], SDK["PYTHON"]))
|
||||
if (not os.path.isfile(SDK["PYTHONEXEC"])):
|
||||
exit("Could not find %s!" % SDK["PYTHONEXEC"])
|
||||
|
||||
# Determine which version it is by checking which dll is in the directory.
|
||||
if (GetOptimize() <= 2):
|
||||
py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]_d.dll")
|
||||
else:
|
||||
py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9].dll")
|
||||
|
||||
if len(py_dlls) == 0:
|
||||
exit("Could not find the Python dll in %s." % (SDK["PYTHON"]))
|
||||
elif len(py_dlls) > 1:
|
||||
exit("Found multiple Python dlls in %s." % (SDK["PYTHON"]))
|
||||
|
||||
py_dll = os.path.basename(py_dlls[0])
|
||||
SDK["PYTHONVERSION"] = "python" + py_dll[6] + "." + py_dll[7]
|
||||
|
||||
os.environ["PYTHONHOME"] = SDK["PYTHON"]
|
||||
|
||||
elif CrossCompiling():
|
||||
tp_python = os.path.join(GetThirdpartyDir(), "python")
|
||||
SDK["PYTHON"] = tp_python + "/include"
|
||||
|
||||
if GetTarget() == 'darwin':
|
||||
py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].dylib")
|
||||
else:
|
||||
py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].so")
|
||||
|
||||
if len(py_libs) == 0:
|
||||
py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].a")
|
||||
|
||||
if len(py_libs) == 0:
|
||||
exit("Could not find the Python library in %s." % (tp_python))
|
||||
elif len(py_libs) > 1:
|
||||
exit("Found multiple Python libraries in %s." % (tp_python))
|
||||
|
||||
py_lib = os.path.basename(py_libs[0])
|
||||
SDK["PYTHONVERSION"] = "python" + py_lib[9] + "." + py_lib[11]
|
||||
|
||||
elif (GetTarget() == 'windows'):
|
||||
SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
|
||||
SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
|
||||
SDK["PYTHONEXEC"] = sys.executable
|
||||
|
||||
else:
|
||||
SDK["PYTHON"] = sysconfig.get_python_inc()
|
||||
SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
|
||||
SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
|
||||
|
||||
if CrossCompiling():
|
||||
SDK["PYTHONEXEC"] = sys.executable
|
||||
host_version = "python" + sysconfig.get_python_version()
|
||||
if SDK["PYTHONVERSION"] != host_version:
|
||||
exit("Host Python version (%s) must be the same as target Python version (%s)!" % (host_version, SDK["PYTHONVERSION"]))
|
||||
|
||||
if GetVerbose():
|
||||
print("Using Python %s build located at %s" % (SDK["PYTHONVERSION"][6:9], SDK["PYTHON"]))
|
||||
|
||||
def SdkLocateVisualStudio():
|
||||
if (GetHost() != "windows"): return
|
||||
vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7", "10.0")
|
||||
|
|
@ -2025,9 +2073,9 @@ def SdkLocateAndroid():
|
|||
SDK["ANDROID_NDK"] = ndk_root
|
||||
|
||||
# Determine the toolchain location.
|
||||
gcc_ver = '4.7'
|
||||
gcc_ver = '4.8'
|
||||
arch = GetTargetArch()
|
||||
if arch == 'armv7' or arch == 'arm':
|
||||
if arch == 'armv7a' or arch == 'arm':
|
||||
arch = 'arm'
|
||||
toolchain = 'arm-linux-androideabi-' + gcc_ver
|
||||
elif arch == 'x86':
|
||||
|
|
@ -2045,8 +2093,10 @@ def SdkLocateAndroid():
|
|||
#IncDirectory("ALWAYS", os.path.join(SDK["SYSROOT"], 'usr', 'include'))
|
||||
|
||||
stdlibc = os.path.join(ndk_root, 'sources', 'cxx-stl', 'gnu-libstdc++', gcc_ver)
|
||||
IncDirectory("ALWAYS", os.path.join(stdlibc, 'include'))
|
||||
IncDirectory("ALWAYS", os.path.join(stdlibc, 'libs', abi, 'include'))
|
||||
SDK["ANDROID_STL"] = stdlibc
|
||||
|
||||
#IncDirectory("ALWAYS", os.path.join(stdlibc, 'include'))
|
||||
#IncDirectory("ALWAYS", os.path.join(stdlibc, 'libs', abi, 'include'))
|
||||
|
||||
stl_lib = os.path.join(stdlibc, 'libs', abi, 'libgnustl_shared.so')
|
||||
LibName("ALWAYS", stl_lib)
|
||||
|
|
@ -2231,7 +2281,9 @@ def SetupBuildEnvironment(compiler):
|
|||
global SYS_LIB_DIRS
|
||||
|
||||
# gcc doesn't add this one, but we do want it:
|
||||
SYS_LIB_DIRS.append('/usr/local/lib')
|
||||
local_lib = SDK.get("SYSROOT", "") + "/usr/local/lib"
|
||||
if os.path.isdir(local_lib):
|
||||
SYS_LIB_DIRS.append(local_lib)
|
||||
|
||||
cmd = GetCXX() + " -print-search-dirs"
|
||||
|
||||
|
|
@ -2253,7 +2305,8 @@ def SetupBuildEnvironment(compiler):
|
|||
returnval = handle.close()
|
||||
if returnval != None and returnval != 0:
|
||||
print("%sWARNING:%s %s failed" % (GetColor("red"), GetColor(), cmd))
|
||||
SYS_LIB_DIRS += ['/usr/lib']
|
||||
SYS_LIB_DIRS += [SDK.get("SYSROOT", "") + "/usr/lib"]
|
||||
|
||||
elif GetVerbose():
|
||||
print("System library search path: %s" % ':'.join(SYS_LIB_DIRS))
|
||||
|
||||
|
|
@ -2753,4 +2806,4 @@ def TargetAdd(target, dummy=0, opts=0, input=0, dep=0, ipath=0, winrc=0):
|
|||
t.deps[FindLocation("dtool_have_python.dat", [])] = 1
|
||||
|
||||
if target.endswith(".pz") and not CrossCompiling():
|
||||
t.deps[FindLocation("pzip.exe", [])] = 1
|
||||
t.deps[FindLocation("pzip.exe", [])] = 1
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "config_util.h"
|
||||
#include "virtualFileMountAndroidAsset.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "filename.h"
|
||||
|
||||
#include "config_display.h"
|
||||
//#define OPENGLES_1
|
||||
|
|
@ -45,9 +46,36 @@ void android_main(struct android_app* app) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Fetch the data directory.
|
||||
jclass activity_class = env->GetObjectClass(activity->clazz);
|
||||
jmethodID get_appinfo = env->GetMethodID(activity_class, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
|
||||
|
||||
jobject appinfo = env->CallObjectMethod(activity->clazz, get_appinfo);
|
||||
jclass appinfo_class = env->GetObjectClass(appinfo);
|
||||
|
||||
// Fetch the path to the data directory.
|
||||
jfieldID datadir_field = env->GetFieldID(appinfo_class, "dataDir", "Ljava/lang/String;");
|
||||
jstring datadir = (jstring) env->GetObjectField(appinfo, datadir_field);
|
||||
const char *data_path = env->GetStringUTFChars(datadir, NULL);
|
||||
|
||||
Filename::_internal_data_dir = data_path;
|
||||
android_cat.info() << "Path to data: " << data_path << "\n";
|
||||
|
||||
env->ReleaseStringUTFChars(datadir, data_path);
|
||||
|
||||
// Fetch the path to the library directory.
|
||||
jfieldID libdir_field = env->GetFieldID(appinfo_class, "nativeLibraryDir", "Ljava/lang/String;");
|
||||
jstring libdir = (jstring) env->GetObjectField(appinfo, libdir_field);
|
||||
const char *lib_path = env->GetStringUTFChars(libdir, NULL);
|
||||
|
||||
string dtool_name = string(lib_path) + "/libp3dtool.so";
|
||||
ExecutionEnvironment::set_dtool_name(dtool_name);
|
||||
android_cat.info() << "Path to dtool: " << dtool_name << "\n";
|
||||
|
||||
env->ReleaseStringUTFChars(libdir, lib_path);
|
||||
|
||||
// Get the path to the APK.
|
||||
jclass clazz = env->GetObjectClass(activity->clazz);
|
||||
jmethodID methodID = env->GetMethodID(clazz, "getPackageCodePath", "()Ljava/lang/String;");
|
||||
jmethodID methodID = env->GetMethodID(activity_class, "getPackageCodePath", "()Ljava/lang/String;");
|
||||
jstring code_path = (jstring) env->CallObjectMethod(activity->clazz, methodID);
|
||||
|
||||
const char* apk_path;
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ open_window() {
|
|||
return false;
|
||||
}
|
||||
|
||||
//_fb_properties = androidgsg->get_fb_properties();
|
||||
_fb_properties = androidgsg->get_fb_properties();
|
||||
|
||||
androiddisplay_cat.error() << "open_window done\n";
|
||||
|
||||
|
|
@ -434,7 +434,7 @@ handle_command(struct android_app *app, int32_t command) {
|
|||
void AndroidGraphicsWindow::
|
||||
ns_handle_command(int32_t command) {
|
||||
WindowProperties properties;
|
||||
|
||||
|
||||
switch (command) {
|
||||
case APP_CMD_SAVE_STATE:
|
||||
// The system has asked us to save our current state. Do so.
|
||||
|
|
@ -446,16 +446,25 @@ ns_handle_command(int32_t command) {
|
|||
// The window is being shown, get it ready.
|
||||
if (_app->window != NULL) {
|
||||
create_surface();
|
||||
properties.set_size(ANativeWindow_getWidth(_app->window),
|
||||
ANativeWindow_getHeight(_app->window));
|
||||
properties.set_minimized(false);
|
||||
system_changed_properties(properties);
|
||||
}
|
||||
break;
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
properties.set_size(ANativeWindow_getWidth(_app->window),
|
||||
ANativeWindow_getHeight(_app->window));
|
||||
system_changed_properties(properties);
|
||||
break;
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
destroy_surface();
|
||||
properties.set_minimized(true);
|
||||
system_changed_properties(properties);
|
||||
break;
|
||||
case APP_CMD_WINDOW_RESIZED:
|
||||
properties.set_size(ANativeWindow_getWidth(_app->window),
|
||||
ANativeWindow_getHeight(_app->window));
|
||||
break;
|
||||
case APP_CMD_WINDOW_REDRAW_NEEDED:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
lru.h \
|
||||
nativeWindowHandle.I nativeWindowHandle.h \
|
||||
parasiteBuffer.I parasiteBuffer.h \
|
||||
pStatGPUTimer.I pStatGPUTimer.h \
|
||||
windowHandle.I windowHandle.h \
|
||||
windowProperties.I windowProperties.h \
|
||||
renderBuffer.h \
|
||||
|
|
@ -112,6 +113,7 @@
|
|||
lru.h \
|
||||
nativeWindowHandle.I nativeWindowHandle.h \
|
||||
parasiteBuffer.I parasiteBuffer.h \
|
||||
pStatGPUTimer.I pStatGPUTimer.h \
|
||||
windowHandle.I windowHandle.h \
|
||||
windowProperties.I windowProperties.h \
|
||||
renderBuffer.h \
|
||||
|
|
|
|||
|
|
@ -580,9 +580,9 @@ get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
|
|||
CDReader cdata(_cycler);
|
||||
const Region ®ion = cdata->_regions[i];
|
||||
xo = region._pixels_i[0];
|
||||
yo = region._pixels_i[2];
|
||||
yo = region._pixels_i[3];
|
||||
w = region._pixels_i[1] - xo;
|
||||
h = region._pixels_i[3] - yo;
|
||||
h = region._pixels_i[2] - yo;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1068,9 +1068,9 @@ INLINE void DisplayRegionPipelineReader::
|
|||
get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
|
||||
const DisplayRegion::Region ®ion = _cdata->_regions[i];
|
||||
xo = region._pixels_i[0];
|
||||
yo = region._pixels_i[2];
|
||||
yo = region._pixels_i[3];
|
||||
w = region._pixels_i[1] - xo;
|
||||
h = region._pixels_i[3] - yo;
|
||||
h = region._pixels_i[2] - yo;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "cullTraverser.h"
|
||||
#include "clockObject.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "pStatGPUTimer.h"
|
||||
#include "pStatClient.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "mutexHolder.h"
|
||||
|
|
@ -52,7 +53,7 @@
|
|||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <WinSock2.h>
|
||||
#include <wtypes.h>
|
||||
#undef WINDOWS_LEAN_AND_MEAN
|
||||
#undef WINDOWS_LEAN_AND_MEAN
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
|
@ -140,7 +141,7 @@ GraphicsEngine(Pipeline *pipeline) :
|
|||
_windows_sorted = true;
|
||||
_window_sort_index = 0;
|
||||
_needs_open_windows = false;
|
||||
|
||||
|
||||
set_threading_model(GraphicsThreadingModel(threading_model));
|
||||
if (!_threading_model.is_default()) {
|
||||
display_cat.info()
|
||||
|
|
@ -188,7 +189,7 @@ set_threading_model(const GraphicsThreadingModel &threading_model) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef THREADED_PIPELINE
|
||||
if (!threading_model.is_single_threaded()) {
|
||||
display_cat.warning()
|
||||
|
|
@ -238,7 +239,7 @@ get_threading_model() const {
|
|||
//
|
||||
// If a null pointer is supplied for the gsg, then this
|
||||
// routine will create a new gsg.
|
||||
//
|
||||
//
|
||||
// This routine is only called from the app thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -283,7 +284,7 @@ make_output(GraphicsPipe *pipe,
|
|||
// already-initialized gsg.
|
||||
|
||||
// Simplify the input parameters.
|
||||
|
||||
|
||||
int x_size = 0, y_size = 0;
|
||||
if (win_prop.has_size()) {
|
||||
x_size = win_prop.get_x_size();
|
||||
|
|
@ -359,7 +360,7 @@ make_output(GraphicsPipe *pipe,
|
|||
// an unencumbered GSG.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Determine if a parasite buffer meets the user's specs.
|
||||
|
||||
bool can_use_parasite = false;
|
||||
|
|
@ -381,7 +382,7 @@ make_output(GraphicsPipe *pipe,
|
|||
// Even if prefer-parasite-buffer is set, parasites are not preferred
|
||||
// if the host window is too small, or if the host window does not
|
||||
// have the requested properties.
|
||||
|
||||
|
||||
if ((prefer_parasite_buffer) &&
|
||||
(can_use_parasite) &&
|
||||
(x_size <= host->get_x_size())&&
|
||||
|
|
@ -408,10 +409,10 @@ make_output(GraphicsPipe *pipe,
|
|||
}
|
||||
|
||||
// Ask the pipe to create a window.
|
||||
|
||||
|
||||
for (int retry=0; retry<10; retry++) {
|
||||
bool precertify = false;
|
||||
PT(GraphicsOutput) window =
|
||||
PT(GraphicsOutput) window =
|
||||
pipe->make_output(name, fb_prop, win_prop, flags, this, gsg, host, retry, precertify);
|
||||
if (window != (GraphicsOutput *)NULL) {
|
||||
window->_sort = sort;
|
||||
|
|
@ -455,11 +456,11 @@ make_output(GraphicsPipe *pipe,
|
|||
nassertr(removed, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parasite buffers were not preferred, but the pipe could not
|
||||
// create a window to the user's specs. Try a parasite as a
|
||||
// last hope.
|
||||
|
||||
|
||||
if (can_use_parasite) {
|
||||
ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size, flags);
|
||||
buffer->_sort = sort;
|
||||
|
|
@ -613,7 +614,7 @@ remove_all_windows() {
|
|||
// Access: Published
|
||||
// Description: Resets the framebuffer of the current window. This
|
||||
// is currently used by DirectX 8 only. It calls a
|
||||
// reset_window function on each active window to
|
||||
// reset_window function on each active window to
|
||||
// release/create old/new framebuffer
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::
|
||||
|
|
@ -712,11 +713,11 @@ render_frame() {
|
|||
if (!_windows_sorted) {
|
||||
do_resort_windows();
|
||||
}
|
||||
|
||||
|
||||
if (sync_flip && _flip_state != FS_flip) {
|
||||
do_flip_frame(current_thread);
|
||||
}
|
||||
|
||||
|
||||
// Are any of the windows ready to be deleted?
|
||||
Windows new_windows;
|
||||
new_windows.reserve(_windows.size());
|
||||
|
|
@ -726,10 +727,10 @@ render_frame() {
|
|||
nassertv(win != NULL);
|
||||
if (win->get_delete_flag()) {
|
||||
do_remove_window(win, current_thread);
|
||||
|
||||
|
||||
} else {
|
||||
new_windows.push_back(win);
|
||||
|
||||
|
||||
// Let's calculate each scene's bounding volume here in App,
|
||||
// before we cycle the pipeline. The cull traversal will
|
||||
// calculate it anyway, but if we calculate it in App first
|
||||
|
|
@ -770,11 +771,11 @@ render_frame() {
|
|||
}
|
||||
_loaded_textures.clear();
|
||||
}
|
||||
|
||||
|
||||
// Now it's time to do any drawing from the main frame--after all of
|
||||
// the App code has executed, but before we begin the next frame.
|
||||
_app.do_frame(this, current_thread);
|
||||
|
||||
|
||||
// Grab each thread's mutex again after all windows have flipped,
|
||||
// and wait for the thread to finish.
|
||||
{
|
||||
|
|
@ -783,32 +784,32 @@ render_frame() {
|
|||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
thread->_cv_mutex.acquire();
|
||||
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(THREADED_PIPELINE) && defined(DO_PSTATS)
|
||||
_cyclers_pcollector.set_level(_pipeline->get_num_cyclers());
|
||||
_dirty_cyclers_pcollector.set_level(_pipeline->get_num_dirty_cyclers());
|
||||
|
||||
|
||||
#ifdef DEBUG_THREADS
|
||||
if (PStatClient::is_connected()) {
|
||||
_pipeline->iterate_all_cycler_types(pstats_count_cycler_type, this);
|
||||
_pipeline->iterate_dirty_cycler_types(pstats_count_dirty_cycler_type, this);
|
||||
}
|
||||
#endif // DEBUG_THREADS
|
||||
|
||||
|
||||
#endif // THREADED_PIPELINE && DO_PSTATS
|
||||
|
||||
|
||||
GeomCacheManager::flush_level();
|
||||
CullTraverser::flush_level();
|
||||
RenderState::flush_level();
|
||||
TransformState::flush_level();
|
||||
CullableObject::flush_level();
|
||||
|
||||
|
||||
// Now cycle the pipeline and officially begin the next frame.
|
||||
#ifdef THREADED_PIPELINE
|
||||
{
|
||||
|
|
@ -816,15 +817,15 @@ render_frame() {
|
|||
_pipeline->cycle();
|
||||
}
|
||||
#endif // THREADED_PIPELINE
|
||||
|
||||
|
||||
global_clock->tick(current_thread);
|
||||
if (global_clock->check_errors(current_thread)) {
|
||||
throw_event("clock_error");
|
||||
}
|
||||
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
PStatClient::main_tick();
|
||||
|
||||
|
||||
// Reset our pcollectors that track data across the frame.
|
||||
CullTraverser::_nodes_pcollector.clear_level();
|
||||
CullTraverser::_geom_nodes_pcollector.clear_level();
|
||||
|
|
@ -833,18 +834,18 @@ render_frame() {
|
|||
GeomCacheManager::_geom_cache_record_pcollector.clear_level();
|
||||
GeomCacheManager::_geom_cache_erase_pcollector.clear_level();
|
||||
GeomCacheManager::_geom_cache_evict_pcollector.clear_level();
|
||||
|
||||
|
||||
GraphicsStateGuardian::init_frame_pstats();
|
||||
|
||||
|
||||
_transform_states_pcollector.set_level(TransformState::get_num_states());
|
||||
_render_states_pcollector.set_level(RenderState::get_num_states());
|
||||
if (pstats_unused_states) {
|
||||
_transform_states_unused_pcollector.set_level(TransformState::get_num_unused_states());
|
||||
_render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
|
||||
}
|
||||
|
||||
|
||||
_sw_sprites_pcollector.clear_level();
|
||||
|
||||
|
||||
_cnode_volume_pcollector.clear_level();
|
||||
_gnode_volume_pcollector.clear_level();
|
||||
_geom_volume_pcollector.clear_level();
|
||||
|
|
@ -869,18 +870,18 @@ render_frame() {
|
|||
_occlusion_passed_pcollector.clear_level();
|
||||
_occlusion_failed_pcollector.clear_level();
|
||||
_occlusion_tests_pcollector.clear_level();
|
||||
|
||||
|
||||
if (PStatClient::is_connected()) {
|
||||
size_t small_buf = GeomVertexArrayData::get_small_lru()->get_total_size();
|
||||
size_t independent = GeomVertexArrayData::get_independent_lru()->get_total_size();
|
||||
size_t resident = VertexDataPage::get_global_lru(VertexDataPage::RC_resident)->get_total_size();
|
||||
size_t compressed = VertexDataPage::get_global_lru(VertexDataPage::RC_compressed)->get_total_size();
|
||||
size_t pending = VertexDataPage::get_pending_lru()->get_total_size();
|
||||
|
||||
|
||||
VertexDataSaveFile *save_file = VertexDataPage::get_save_file();
|
||||
size_t total_disk = save_file->get_total_file_size();
|
||||
size_t used_disk = save_file->get_used_file_size();
|
||||
|
||||
|
||||
_vertex_data_small_pcollector.set_level(small_buf);
|
||||
_vertex_data_independent_pcollector.set_level(independent);
|
||||
_vertex_data_pending_pcollector.set_level(pending);
|
||||
|
|
@ -889,11 +890,11 @@ render_frame() {
|
|||
_vertex_data_unused_disk_pcollector.set_level(total_disk - used_disk);
|
||||
_vertex_data_used_disk_pcollector.set_level(used_disk);
|
||||
}
|
||||
|
||||
|
||||
#endif // DO_PSTATS
|
||||
|
||||
|
||||
GeomVertexArrayData::lru_epoch();
|
||||
|
||||
|
||||
// Now signal all of our threads to begin their next frame.
|
||||
Threads::const_iterator ti;
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
|
|
@ -904,24 +905,24 @@ render_frame() {
|
|||
}
|
||||
thread->_cv_mutex.release();
|
||||
}
|
||||
|
||||
|
||||
// Some threads may still be drawing, so indicate that we have to
|
||||
// wait for those threads before we can flip.
|
||||
_flip_state = _auto_flip ? FS_flip : FS_draw;
|
||||
}
|
||||
|
||||
// Now the lock is released.
|
||||
|
||||
|
||||
if (yield_timeslice) {
|
||||
// Nap for a moment to yield the timeslice, to be polite to other
|
||||
// running applications.
|
||||
PStatTimer timer(_yield_pcollector, current_thread);
|
||||
Thread::force_yield();
|
||||
} else if (!Thread::is_true_threads()) {
|
||||
} else if (!Thread::is_true_threads()) {
|
||||
PStatTimer timer(_yield_pcollector, current_thread);
|
||||
Thread::consider_yield();
|
||||
}
|
||||
|
||||
|
||||
// Anything that happens outside of GraphicsEngine::render_frame()
|
||||
// is deemed to be App.
|
||||
_app_pcollector.start();
|
||||
|
|
@ -961,11 +962,11 @@ open_windows() {
|
|||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
thread->_cv_mutex.acquire();
|
||||
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
|
||||
|
||||
thread->_thread_state = TS_do_windows;
|
||||
thread->_cv_start.notify();
|
||||
thread->_cv_mutex.release();
|
||||
|
|
@ -1004,7 +1005,7 @@ sync_frame() {
|
|||
// we seems to return once all draw calls have been submitted.
|
||||
// Calling 'flip_frame' after this function should immediately
|
||||
// cause a buffer flip. This function will only work in
|
||||
// opengl right now, for all other graphics pipelines it will
|
||||
// opengl right now, for all other graphics pipelines it will
|
||||
// simply return immediately. In opengl it's a bit of a hack:
|
||||
// it will attempt to read a single pixel from the frame buffer to
|
||||
// force the graphics card to finish drawing before it returns
|
||||
|
|
@ -1082,7 +1083,7 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
|
|||
WindowRenderer *wr = get_window_renderer(draw_name, 0);
|
||||
RenderThread *thread = (RenderThread *)wr;
|
||||
MutexHolder holder2(thread->_cv_mutex);
|
||||
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
|
|
@ -1131,7 +1132,7 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
|
|||
WindowRenderer *wr = get_window_renderer(draw_name, 0);
|
||||
RenderThread *thread = (RenderThread *)wr;
|
||||
MutexHolder holder2(thread->_cv_mutex);
|
||||
|
||||
|
||||
while (thread->_thread_state != TS_wait) {
|
||||
thread->_cv_done.wait();
|
||||
}
|
||||
|
|
@ -1149,7 +1150,7 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::get_global_ptr
|
||||
// Access: Published, Static
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsEngine *GraphicsEngine::
|
||||
get_global_ptr() {
|
||||
|
|
@ -1217,7 +1218,7 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
|
|||
local_frustum = DCAST(GeometricBoundingVolume, bv->make_copy());
|
||||
|
||||
NodePath scene_parent = scene_setup->get_scene_root().get_parent(current_thread);
|
||||
CPT(TransformState) cull_center_transform =
|
||||
CPT(TransformState) cull_center_transform =
|
||||
scene_setup->get_cull_center().get_transform(scene_parent, current_thread);
|
||||
local_frustum->xform(cull_center_transform->get_mat());
|
||||
|
||||
|
|
@ -1338,7 +1339,7 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist,
|
|||
|
||||
if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) {
|
||||
win->clear(current_thread);
|
||||
|
||||
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; i++) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
|
|
@ -1377,7 +1378,7 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
nassertv(gsg != (GraphicsStateGuardian *)NULL);
|
||||
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
|
||||
win->change_scenes(dr_reader);
|
||||
|
|
@ -1410,9 +1411,9 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||
// Issue the cull callback on this DisplayRegion.
|
||||
DisplayRegionCullCallbackData cbdata(&cull_handler, scene_setup);
|
||||
cbobj->do_callback(&cbdata);
|
||||
|
||||
|
||||
// The callback has taken care of the culling.
|
||||
|
||||
|
||||
} else {
|
||||
// Perform the cull normally.
|
||||
dr->do_cull(&cull_handler, scene_setup, gsg, current_thread);
|
||||
|
|
@ -1456,7 +1457,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
NodePath camera = dr_reader->get_camera();
|
||||
AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(camera, (DisplayRegion *)NULL)).first;
|
||||
|
|
@ -1467,7 +1468,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
dr_reader = NULL;
|
||||
(*aci).second = dr;
|
||||
cull_to_bins(win, dr, current_thread);
|
||||
|
||||
|
||||
} else {
|
||||
// We have already culled a scene using this camera in
|
||||
// this thread, and now we're being asked to cull another
|
||||
|
|
@ -1481,7 +1482,7 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
setup_scene(win->get_gsg(), dr_reader),
|
||||
current_thread);
|
||||
}
|
||||
|
||||
|
||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
||||
delete dr_reader;
|
||||
}
|
||||
|
|
@ -1539,7 +1540,7 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
|||
PStatTimer timer(_cull_sort_pcollector, current_thread);
|
||||
cull_result->finish_cull(scene_setup, current_thread);
|
||||
}
|
||||
|
||||
|
||||
// Save the results for next frame.
|
||||
dr->set_cull_result(cull_result, scene_setup, current_thread);
|
||||
}
|
||||
|
|
@ -1560,53 +1561,73 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
size_t wlist_size = wlist.size();
|
||||
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||
GraphicsOutput *win = wlist[wi];
|
||||
|
||||
if (win->is_active()) {
|
||||
if (win->flip_ready()) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
|
||||
GraphicsOutput *host = win->get_host();
|
||||
if (host->flip_ready()) {
|
||||
{
|
||||
// We can't use a PStatGPUTimer before begin_frame, so when using GPU
|
||||
// timing, it is advisable to set auto-flip to #t.
|
||||
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread);
|
||||
win->begin_flip();
|
||||
host->begin_flip();
|
||||
}
|
||||
{
|
||||
PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread);
|
||||
win->end_flip();
|
||||
host->end_flip();
|
||||
}
|
||||
}
|
||||
|
||||
PStatTimer timer(win->get_draw_window_pcollector(), current_thread);
|
||||
if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) {
|
||||
win->clear(current_thread);
|
||||
// We have to place this collector inside begin_frame, because
|
||||
// we need a current context for PStatGPUTimer to work.
|
||||
{
|
||||
PStatGPUTimer timer(win->get_gsg(), win->get_draw_window_pcollector(), current_thread);
|
||||
win->clear(current_thread);
|
||||
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
<< "Drawing window " << win->get_name() << "\n";
|
||||
}
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
draw_bins(win, dr, current_thread);
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
<< "Drawing window " << win->get_name() << "\n";
|
||||
}
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
draw_bins(win, dr, current_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
win->end_frame(GraphicsOutput::FM_render, current_thread);
|
||||
|
||||
if (_auto_flip) {
|
||||
#ifdef DO_PSTATS
|
||||
// This is a good time to perform a latency query.
|
||||
if (win->get_gsg()->get_timer_queries_active()) {
|
||||
win->get_gsg()->issue_timer_query(GraphicsStateGuardian::_command_latency_pcollector.get_index());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (win->flip_ready()) {
|
||||
{
|
||||
// begin_flip doesn't do anything interesting, let's not waste two timer queries on that.
|
||||
PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread);
|
||||
win->begin_flip();
|
||||
}
|
||||
{
|
||||
PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread);
|
||||
PStatGPUTimer timer(win->get_gsg(), GraphicsEngine::_flip_end_pcollector, current_thread);
|
||||
win->end_flip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
<< "Not drawing window " << win->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
|
|
@ -1723,8 +1744,6 @@ ready_flip_windows(const GraphicsEngine::Windows &wlist, Thread *current_thread)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::do_sync_frame
|
||||
// Access: Private
|
||||
|
|
@ -1752,7 +1771,6 @@ do_sync_frame(Thread *current_thread) {
|
|||
_flip_state = FS_sync;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::do_ready_flip
|
||||
// Access: Private
|
||||
|
|
@ -1778,8 +1796,6 @@ do_ready_flip(Thread *current_thread) {
|
|||
}
|
||||
_app.do_ready_flip(this,current_thread);
|
||||
_flip_state = FS_sync;
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1812,7 +1828,7 @@ do_flip_frame(Thread *current_thread) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now signal all of our threads to flip the windows.
|
||||
_app.do_flip(this, current_thread);
|
||||
|
||||
|
|
@ -1896,7 +1912,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
|||
// There must be a singular transform over the scene.
|
||||
if (!_singular_warning_last_frame) {
|
||||
display_cat.warning()
|
||||
<< "Scene " << scene_root << " has net scale ("
|
||||
<< "Scene " << scene_root << " has net scale ("
|
||||
<< scene_root.get_scale(NodePath()) << "); cannot render.\n";
|
||||
_singular_warning_this_frame = true;
|
||||
}
|
||||
|
|
@ -1907,7 +1923,7 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
|||
// There must be a singular transform over the camera.
|
||||
if (!_singular_warning_last_frame) {
|
||||
display_cat.warning()
|
||||
<< "Camera " << camera << " has net scale ("
|
||||
<< "Camera " << camera << " has net scale ("
|
||||
<< camera.get_scale(NodePath()) << "); cannot render.\n";
|
||||
}
|
||||
_singular_warning_this_frame = true;
|
||||
|
|
@ -1951,11 +1967,12 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
|||
void GraphicsEngine::
|
||||
do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
// Statistics
|
||||
PStatTimer timer(dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
CallbackObject *cbobj;
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
|
||||
// Statistics
|
||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
{
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
|
|
@ -2034,20 +2051,20 @@ do_add_window(GraphicsOutput *window,
|
|||
_windows_sorted = false;
|
||||
_windows.push_back(window);
|
||||
|
||||
WindowRenderer *cull =
|
||||
WindowRenderer *cull =
|
||||
get_window_renderer(threading_model.get_cull_name(),
|
||||
threading_model.get_cull_stage());
|
||||
WindowRenderer *draw =
|
||||
WindowRenderer *draw =
|
||||
get_window_renderer(threading_model.get_draw_name(),
|
||||
threading_model.get_draw_stage());
|
||||
|
||||
|
||||
if (threading_model.get_cull_sorting()) {
|
||||
cull->add_window(cull->_cull, window);
|
||||
draw->add_window(draw->_draw, window);
|
||||
} else {
|
||||
cull->add_window(cull->_cdraw, window);
|
||||
}
|
||||
|
||||
|
||||
// Ask the pipe which thread it prefers to run its windowing
|
||||
// commands in (the "window thread"). This is the thread that
|
||||
// handles the commands to open, resize, etc. the window. X
|
||||
|
|
@ -2057,7 +2074,7 @@ do_add_window(GraphicsOutput *window,
|
|||
// has been bound in a given thread, it cannot subsequently be bound
|
||||
// in any other thread, and we have to bind a context in
|
||||
// open_window()).
|
||||
|
||||
|
||||
switch (window->get_pipe()->get_preferred_window_thread()) {
|
||||
case GraphicsPipe::PWT_app:
|
||||
_app.add_window(_app._window, window);
|
||||
|
|
@ -2096,8 +2113,8 @@ do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe,
|
|||
}
|
||||
|
||||
auto_adjust_capabilities(gsg);
|
||||
|
||||
WindowRenderer *draw =
|
||||
|
||||
WindowRenderer *draw =
|
||||
get_window_renderer(threading_model.get_draw_name(),
|
||||
threading_model.get_draw_stage());
|
||||
|
||||
|
|
@ -2228,7 +2245,7 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
<< "textures_power_2 to 'up' or 'down'.\n";
|
||||
textures_power_2 = ATS_down; // Not a fix. Just suppresses further error messages.
|
||||
}
|
||||
|
||||
|
||||
if (textures_auto_power_2 && !Texture::has_textures_power_2()) {
|
||||
if (gsg->get_supports_tex_non_pow2()) {
|
||||
Texture::set_textures_power_2(ATS_none);
|
||||
|
|
@ -2236,13 +2253,13 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
Texture::set_textures_power_2(textures_power_2);
|
||||
}
|
||||
}
|
||||
|
||||
if ((Texture::get_textures_power_2() == ATS_none) &&
|
||||
|
||||
if ((Texture::get_textures_power_2() == ATS_none) &&
|
||||
(!gsg->get_supports_tex_non_pow2())) {
|
||||
|
||||
|
||||
// Overaggressive configuration detected
|
||||
|
||||
display_cat.error()
|
||||
|
||||
display_cat.error()
|
||||
<< "The 'textures_power_2' configuration is set to 'none', meaning \n"
|
||||
<< "that non-power-of-two texture support is required, but the video \n"
|
||||
<< "driver I'm trying to use does not support non-power-of-two textures.\n";
|
||||
|
|
@ -2251,7 +2268,7 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
display_cat.error()
|
||||
<< "The 'none' did not come from the config file. In other words,\n"
|
||||
<< "the variable 'textures_power_2' was altered procedurally.\n";
|
||||
|
||||
|
||||
if (textures_auto_power_2) {
|
||||
display_cat.error()
|
||||
<< "It is possible that it was set by panda's automatic mechanisms,\n"
|
||||
|
|
@ -2264,7 +2281,7 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (shader_auto_utilization && (shader_utilization != SUT_none)) {
|
||||
display_cat.error()
|
||||
<< "Invalid panda config file: if you set the config-variable\n"
|
||||
|
|
@ -2272,7 +2289,7 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
<< "shader_utilization to 'none'.\n";
|
||||
shader_utilization = SUT_none; // Not a fix. Just suppresses further error messages.
|
||||
}
|
||||
|
||||
|
||||
if (shader_auto_utilization && !Shader::have_shader_utilization()) {
|
||||
if (gsg->get_supports_basic_shaders()) {
|
||||
Shader::set_shader_utilization(SUT_basic);
|
||||
|
|
@ -2280,13 +2297,13 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
Shader::set_shader_utilization(SUT_none);
|
||||
}
|
||||
}
|
||||
|
||||
if ((Shader::get_shader_utilization() != SUT_none) &&
|
||||
|
||||
if ((Shader::get_shader_utilization() != SUT_none) &&
|
||||
(!gsg->get_supports_basic_shaders())) {
|
||||
|
||||
|
||||
// Overaggressive configuration detected
|
||||
|
||||
display_cat.error()
|
||||
|
||||
display_cat.error()
|
||||
<< "The 'shader_utilization' config variable is set, meaning\n"
|
||||
<< "that panda may try to generate shaders. However, the video \n"
|
||||
<< "driver I'm trying to use does not support shaders.\n";
|
||||
|
|
@ -2295,7 +2312,7 @@ auto_adjust_capabilities(GraphicsStateGuardian *gsg) {
|
|||
display_cat.error()
|
||||
<< "The 'shader_utilization' setting did not come from the config\n"
|
||||
<< "file. In other words, it was altered procedurally.\n";
|
||||
|
||||
|
||||
if (shader_auto_utilization) {
|
||||
display_cat.error()
|
||||
<< "It is possible that it was set by panda's automatic mechanisms,\n"
|
||||
|
|
@ -2323,7 +2340,7 @@ terminate_threads(Thread *current_thread) {
|
|||
// We spend almost our entire time in this method just waiting for
|
||||
// threads. Time it appropriately.
|
||||
PStatTimer timer(_wait_pcollector, current_thread);
|
||||
|
||||
|
||||
// First, wait for all the threads to finish their current frame.
|
||||
// Grabbing the mutex should achieve that.
|
||||
Threads::const_iterator ti;
|
||||
|
|
@ -2331,7 +2348,7 @@ terminate_threads(Thread *current_thread) {
|
|||
RenderThread *thread = (*ti).second;
|
||||
thread->_cv_mutex.acquire();
|
||||
}
|
||||
|
||||
|
||||
// Now tell them to close their windows and terminate.
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
|
|
@ -2345,7 +2362,7 @@ terminate_threads(Thread *current_thread) {
|
|||
RenderThread *thread = (*ti).second;
|
||||
thread->join();
|
||||
}
|
||||
|
||||
|
||||
_threads.clear();
|
||||
}
|
||||
|
||||
|
|
@ -2451,7 +2468,7 @@ get_window_renderer(const string &name, int pipeline_stage) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::WindowRenderer::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsEngine::WindowRenderer::
|
||||
WindowRenderer(const string &name) :
|
||||
|
|
@ -2589,7 +2606,7 @@ do_frame(GraphicsEngine *engine, Thread *current_thread) {
|
|||
// This one has no outstanding pointers; clean it up.
|
||||
GraphicsPipe *pipe = gsg->get_pipe();
|
||||
engine->close_gsg(pipe, gsg);
|
||||
} else {
|
||||
} else {
|
||||
// This one is ok; preserve it.
|
||||
new_gsgs.insert(gsg);
|
||||
}
|
||||
|
|
@ -2668,12 +2685,12 @@ do_close(GraphicsEngine *engine, Thread *current_thread) {
|
|||
// This one has no outstanding pointers; clean it up.
|
||||
GraphicsPipe *pipe = gsg->get_pipe();
|
||||
engine->close_gsg(pipe, gsg);
|
||||
} else {
|
||||
} else {
|
||||
// This one is ok; preserve it.
|
||||
new_gsgs.insert(gsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_gsgs.swap(new_gsgs);
|
||||
}
|
||||
|
||||
|
|
@ -2729,10 +2746,10 @@ any_done_gsgs() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::RenderThread::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GraphicsEngine::RenderThread::
|
||||
RenderThread(const string &name, GraphicsEngine *engine) :
|
||||
RenderThread(const string &name, GraphicsEngine *engine) :
|
||||
Thread(name, "Main"),
|
||||
WindowRenderer(name),
|
||||
_engine(engine),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Filename: graphicsStateGuardian.I
|
||||
// Created by: drose (24Sep99)
|
||||
// Updated by: fperazzi, PandaSE (29Apr10) (added
|
||||
// Updated by: fperazzi, PandaSE (29Apr10) (added
|
||||
// get_max_2d_texture_array_layers and related)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -334,10 +334,10 @@ get_max_3d_texture_dimension() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_2d_texture_array_layers
|
||||
// Access: Published
|
||||
// Description: Returns the largest possible number of pages, or -1
|
||||
// Description: Returns the largest possible number of pages, or -1
|
||||
// if there is no particular limit. Returns 0 if 2-d
|
||||
// texture arrays not supported.
|
||||
//
|
||||
//
|
||||
// The value returned may not be meaningful until after
|
||||
// the graphics context has been fully created (e.g. the
|
||||
// window has been opened).
|
||||
|
|
@ -447,6 +447,16 @@ get_supports_tex_non_pow2() const {
|
|||
return _supports_tex_non_pow2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_texture_srgb
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can handle sRGB textures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_texture_srgb() const {
|
||||
return _supports_texture_srgb;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_compressed_texture
|
||||
// Access: Published
|
||||
|
|
@ -713,6 +723,45 @@ get_supports_geometry_instancing() const {
|
|||
return _supports_geometry_instancing;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_occlusion_query
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG supports an occlusion query.
|
||||
// If this is true, then begin_occlusion_query() and
|
||||
// end_occlusion_query() may be called to bracket a
|
||||
// sequence of draw_triangles() (or whatever) calls to
|
||||
// measure pixels that pass the depth test.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
get_supports_occlusion_query() const {
|
||||
return _supports_occlusion_query;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_timer_query
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG supports a timer query.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
get_supports_timer_query() const {
|
||||
return _supports_timer_query;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_timer_queries_active
|
||||
// Access: Published
|
||||
// Description: Returns true if timer queries are currently
|
||||
// enabled on this GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
get_timer_queries_active() const {
|
||||
#ifdef DO_PSTATS
|
||||
return _timer_queries_active;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_color_targets
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "throw_event.h"
|
||||
#include "clockObject.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "pStatGPUTimer.h"
|
||||
#include "geomTristrips.h"
|
||||
#include "geomTrifans.h"
|
||||
#include "geomLinestrips.h"
|
||||
|
|
@ -55,6 +56,7 @@
|
|||
#include "colorScaleAttrib.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "config_pstats.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
|
@ -87,9 +89,19 @@ PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive
|
|||
PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector("Draw:Set State");
|
||||
PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
|
||||
PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
|
||||
PStatCollector GraphicsStateGuardian::_compute_dispatch_pcollector("Draw:Compute dispatch");
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector("Wait:Occlusion");
|
||||
PStatCollector GraphicsStateGuardian::_wait_timer_pcollector("Wait:Timer Queries");
|
||||
PStatCollector GraphicsStateGuardian::_timer_queries_pcollector("Timer queries");
|
||||
PStatCollector GraphicsStateGuardian::_command_latency_pcollector("Command latency");
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_prepare_pcollector("Draw:Prepare");
|
||||
PStatCollector GraphicsStateGuardian::_prepare_texture_pcollector("Draw:Prepare:Texture");
|
||||
PStatCollector GraphicsStateGuardian::_prepare_geom_pcollector("Draw:Prepare:Geom");
|
||||
PStatCollector GraphicsStateGuardian::_prepare_shader_pcollector("Draw:Prepare:Shader");
|
||||
PStatCollector GraphicsStateGuardian::_prepare_vertex_buffer_pcollector("Draw:Prepare:Vertex buffer");
|
||||
PStatCollector GraphicsStateGuardian::_prepare_index_buffer_pcollector("Draw:Prepare:Index buffer");
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector("Draw:Set State:Transform");
|
||||
PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector("Draw:Set State:Alpha test");
|
||||
|
|
@ -115,7 +127,6 @@ PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector("Draw:S
|
|||
PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector("Draw:Set State:Fog");
|
||||
PStatCollector GraphicsStateGuardian::_draw_set_state_scissor_pcollector("Draw:Set State:Scissor");
|
||||
|
||||
|
||||
PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
|
||||
|
||||
TypeHandle GraphicsStateGuardian::_type_handle;
|
||||
|
|
@ -184,6 +195,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||
_supports_2d_texture_array = false;
|
||||
_supports_cube_map = false;
|
||||
_supports_tex_non_pow2 = false;
|
||||
_supports_texture_srgb = false;
|
||||
_supports_compressed_texture = false;
|
||||
_compressed_texture_formats.clear();
|
||||
_compressed_texture_formats.set_bit(Texture::CM_off);
|
||||
|
|
@ -197,6 +209,16 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||
_max_vertex_transform_indices = 0;
|
||||
|
||||
_supports_occlusion_query = false;
|
||||
_supports_timer_query = false;
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
_timer_queries_active = false;
|
||||
_last_query_frame = 0;
|
||||
_last_num_queried = 0;
|
||||
//_timer_delta = 0.0;
|
||||
|
||||
_pstats_gpu_thread = -1;
|
||||
#endif
|
||||
|
||||
// Initially, we set this to false; a GSG that knows it has this
|
||||
// property should set it to true.
|
||||
|
|
@ -261,7 +283,7 @@ GraphicsStateGuardian::
|
|||
delete _stencil_render_states;
|
||||
_stencil_render_states = 0;
|
||||
}
|
||||
|
||||
|
||||
if (_shader_generator) {
|
||||
delete _shader_generator;
|
||||
_shader_generator = 0;
|
||||
|
|
@ -322,7 +344,7 @@ get_supported_geom_rendering() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_cg_profile
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns true if this particular GSG supports the
|
||||
// Description: Returns true if this particular GSG supports the
|
||||
// specified Cg Shader Profile.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
|
|
@ -405,7 +427,7 @@ get_prepared_objects() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
set_gamma(PN_stdfloat gamma) {
|
||||
_gamma = gamma;
|
||||
_gamma = gamma;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -437,7 +459,7 @@ restore_gamma() {
|
|||
// function returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
traverse_prepared_textures(GraphicsStateGuardian::TextureCallback *func,
|
||||
traverse_prepared_textures(GraphicsStateGuardian::TextureCallback *func,
|
||||
void *callback_arg) {
|
||||
ReMutexHolder holder(_prepared_objects->_lock);
|
||||
PreparedGraphicsObjects::Textures::const_iterator ti;
|
||||
|
|
@ -702,20 +724,6 @@ void GraphicsStateGuardian::
|
|||
release_index_buffer(IndexBufferContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_occlusion_query
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this GSG supports an occlusion query.
|
||||
// If this is true, then begin_occlusion_query() and
|
||||
// end_occlusion_query() may be called to bracket a
|
||||
// sequence of draw_triangles() (or whatever) calls to
|
||||
// measure pixels that pass the depth test.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
get_supports_occlusion_query() const {
|
||||
return _supports_occlusion_query;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::begin_occlusion_query
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -754,6 +762,17 @@ end_occlusion_query() {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::issue_timer_query
|
||||
// Access: Public, Virtual
|
||||
// Description: Adds a timer query to the command stream, associated
|
||||
// with the given PStats collector index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(TimerQueryContext) GraphicsStateGuardian::
|
||||
issue_timer_query(int pstats_index) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::dispatch_compute
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -888,7 +907,7 @@ compute_distance_to(const LPoint3 &point) const {
|
|||
// the need for a separate routine to fetch these values.
|
||||
//
|
||||
// The "altered" bits indicate what parts of the
|
||||
// state_and_transform have changed since the last
|
||||
// state_and_transform have changed since the last
|
||||
// time this particular ShaderMatSpec was evaluated.
|
||||
// This may allow data to be cached and not reevaluated.
|
||||
//
|
||||
|
|
@ -896,7 +915,7 @@ compute_distance_to(const LPoint3 &point) const {
|
|||
const LMatrix4 *GraphicsStateGuardian::
|
||||
fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
|
||||
LVecBase3 v;
|
||||
|
||||
|
||||
if (altered & spec._dep[0]) {
|
||||
const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0]);
|
||||
if (t != &spec._cache[0]) {
|
||||
|
|
@ -909,7 +928,7 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
|
|||
spec._cache[1] = *t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch(spec._func) {
|
||||
case Shader::SMF_compose:
|
||||
spec._value.multiply(spec._cache[0], spec._cache[1]);
|
||||
|
|
@ -1470,6 +1489,29 @@ begin_frame(Thread *current_thread) {
|
|||
_state_rs = RenderState::make_empty();
|
||||
_state_mask.clear();
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
// We have to do this here instead of in GraphicsEngine because
|
||||
// we need a current context to issue timer queries.
|
||||
int frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (_last_query_frame < frame) {
|
||||
_last_query_frame = frame;
|
||||
_timer_queries_pcollector.clear_level();
|
||||
|
||||
// Now is a good time to flush previous frame's queries. We
|
||||
// may not actually have all of the previous frame's results
|
||||
// in yet, but that's okay; the GPU data is allowed to lag a
|
||||
// few frames behind.
|
||||
flush_timer_queries();
|
||||
|
||||
if (_timer_queries_active) {
|
||||
// Issue a stop and start event for collector 0, marking the
|
||||
// beginning of the new frame.
|
||||
issue_timer_query(0x8000);
|
||||
issue_timer_query(0x0000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return !_needs_reset;
|
||||
}
|
||||
|
||||
|
|
@ -1566,6 +1608,138 @@ end_frame(Thread *current_thread) {
|
|||
_prepared_objects->_graphics_memory_lru.begin_epoch();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::flush_timer_queries
|
||||
// Access: Public
|
||||
// Description: Called by the graphics engine on the draw thread
|
||||
// to check the status of the running timer queries
|
||||
// and submit their results to the PStats server.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
flush_timer_queries() {
|
||||
#ifdef DO_PSTATS
|
||||
// This uses the lower-level PStats interfaces for now because
|
||||
// of all the unnecessary overhead that would otherwise be incurred
|
||||
// when adding such a large amount of data at once.
|
||||
|
||||
PStatClient *client = PStatClient::get_global_pstats();
|
||||
|
||||
if (!client->client_is_connected()) {
|
||||
_timer_queries_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_timer_queries_active) {
|
||||
if (pstats_gpu_timing && _supports_timer_query) {
|
||||
// Check if timer queries should be enabled.
|
||||
_timer_queries_active = true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Currently, we use one thread per GSG, for convenience. In the
|
||||
// future, we may want to try and use one thread per graphics card.
|
||||
if (_pstats_gpu_thread == -1) {
|
||||
_pstats_gpu_thread = client->make_gpu_thread(get_driver_renderer()).get_index();
|
||||
}
|
||||
PStatThread gpu_thread(client, _pstats_gpu_thread);
|
||||
|
||||
// Get the results of all the timer queries.
|
||||
int first = 0;
|
||||
if (!_pending_timer_queries.empty()) {
|
||||
int count = _pending_timer_queries.size();
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PStatGPUTimer timer(this, _wait_timer_pcollector);
|
||||
|
||||
if (_last_num_queried > 0) {
|
||||
// We know how many queries were available last frame, and this
|
||||
// usually stays fairly constant, so use this as a starting point.
|
||||
int i = min(_last_num_queried, count) - 1;
|
||||
|
||||
if (_pending_timer_queries[i]->is_answer_ready()) {
|
||||
first = count;
|
||||
while (i < count) {
|
||||
if (!_pending_timer_queries[++i]->is_answer_ready()) {
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
first = 0;
|
||||
while (i > 0) {
|
||||
if (_pending_timer_queries[--i]->is_answer_ready()) {
|
||||
first = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We figure out which tasks the GPU has already finished by doing
|
||||
// a binary search for the first query that does not have an answer
|
||||
// ready. We know then that everything before that must be ready.
|
||||
while (count > 0) {
|
||||
int step = count / 2;
|
||||
int i = first + step;
|
||||
if (_pending_timer_queries[i]->is_answer_ready()) {
|
||||
first += step + 1;
|
||||
count -= step + 1;
|
||||
} else {
|
||||
count = step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
_last_num_queried = first;
|
||||
|
||||
int frame_index = ClockObject::get_global_clock()->get_frame_count();
|
||||
|
||||
for (int i = 0; i < first; ++i) {
|
||||
CPT(TimerQueryContext) query = _pending_timer_queries[i];
|
||||
|
||||
double time_data = query->get_timestamp(); // + _timer_delta;
|
||||
|
||||
if (query->_pstats_index == _command_latency_pcollector.get_index()) {
|
||||
// Special case for the latency pcollector.
|
||||
PStatCollectorDef *cdef;
|
||||
cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
|
||||
_pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
|
||||
|
||||
} else if (query->_pstats_index & 0x8000) {
|
||||
_pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
|
||||
|
||||
} else {
|
||||
_pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
|
||||
}
|
||||
|
||||
// We found an end-frame marker (a stop event for collector 0).
|
||||
// This means that the GPU actually caught up with that frame,
|
||||
// and we can flush the GPU thread's frame data to the pstats server.
|
||||
if (query->_pstats_index == 0x8000) {
|
||||
gpu_thread.add_frame(_pstats_gpu_data);
|
||||
_pstats_gpu_data.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first > 0) {
|
||||
// Do this out of the scope of _wait_timer_pcollector.
|
||||
_pending_timer_queries.erase(
|
||||
_pending_timer_queries.begin(),
|
||||
_pending_timer_queries.begin() + first
|
||||
);
|
||||
_timer_queries_pcollector.add_level_now(first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::depth_offset_decals
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -1819,7 +1993,7 @@ reset() {
|
|||
delete _stencil_render_states;
|
||||
_stencil_render_states = 0;
|
||||
}
|
||||
_stencil_render_states = new StencilRenderStates (this);
|
||||
_stencil_render_states = new StencilRenderStates(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1935,12 +2109,12 @@ do_issue_clip_plane() {
|
|||
enable_clip_planes(true);
|
||||
_clip_planes_enabled = true;
|
||||
}
|
||||
|
||||
|
||||
enable_clip_plane(num_enabled, true);
|
||||
if (num_enabled == 0) {
|
||||
begin_bind_clip_planes();
|
||||
}
|
||||
|
||||
|
||||
bind_clip_plane(plane, num_enabled);
|
||||
num_enabled++;
|
||||
}
|
||||
|
|
@ -2123,7 +2297,7 @@ do_issue_light() {
|
|||
if (num_enabled == 0) {
|
||||
begin_bind_lights();
|
||||
}
|
||||
|
||||
|
||||
light_obj->bind(this, light, num_enabled);
|
||||
num_enabled++;
|
||||
}
|
||||
|
|
@ -2278,24 +2452,24 @@ create_gamma_table (PN_stdfloat gamma, unsigned short *red_table, unsigned short
|
|||
// avoid divide by zero and negative exponents
|
||||
gamma = 1.0;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
double g;
|
||||
double x;
|
||||
PN_stdfloat gamma_correction;
|
||||
|
||||
|
||||
x = ((double) i / 255.0);
|
||||
gamma_correction = 1.0 / gamma;
|
||||
gamma_correction = 1.0 / gamma;
|
||||
x = pow (x, (double) gamma_correction);
|
||||
if (x > 1.00) {
|
||||
x = 1.0;
|
||||
}
|
||||
|
||||
g = x * 65535.0;
|
||||
g = x * 65535.0;
|
||||
red_table [i] = (int)g;
|
||||
green_table [i] = (int)g;
|
||||
blue_table [i] = (int)g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2638,7 +2812,7 @@ async_reload_texture(TextureContext *tc) {
|
|||
|
||||
string task_name = string("reload:") + tc->get_texture()->get_name();
|
||||
PT(AsyncTaskManager) task_mgr = _loader->get_task_manager();
|
||||
|
||||
|
||||
// See if we are already loading this task.
|
||||
AsyncTaskCollection orig_tasks = task_mgr->find_tasks(task_name);
|
||||
int num_tasks = orig_tasks.get_num_tasks();
|
||||
|
|
@ -2655,7 +2829,7 @@ async_reload_texture(TextureContext *tc) {
|
|||
|
||||
// This texture has not yet been queued to be reloaded. Queue it up
|
||||
// now.
|
||||
PT(AsyncTask) request =
|
||||
PT(AsyncTask) request =
|
||||
new TextureReloadRequest(task_name,
|
||||
_prepared_objects, tc->get_texture(),
|
||||
_supports_compressed_texture);
|
||||
|
|
@ -2762,20 +2936,20 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_vendor
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the vendor of the video card driver
|
||||
// Description: Returns the vendor of the video card driver
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string GraphicsStateGuardian::
|
||||
get_driver_vendor() {
|
||||
return string("0");
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_vendor
|
||||
// Function: GraphicsStateGuardian::get_driver_renderer
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns GL_Renderer
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string GraphicsStateGuardian::get_driver_renderer() {
|
||||
return string("0");
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2783,12 +2957,12 @@ string GraphicsStateGuardian::get_driver_renderer() {
|
|||
// Access: Public, Virtual
|
||||
// Description: Returns driver version
|
||||
// This has an implementation-defined meaning, and may
|
||||
// be "0" if the particular graphics implementation
|
||||
// be "" if the particular graphics implementation
|
||||
// does not provide a way to query this information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string GraphicsStateGuardian::
|
||||
get_driver_version() {
|
||||
return string("0");
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "bitMask.h"
|
||||
#include "texture.h"
|
||||
#include "occlusionQueryContext.h"
|
||||
#include "timerQueryContext.h"
|
||||
#include "stencilRenderStates.h"
|
||||
#include "loader.h"
|
||||
#include "shaderAttrib.h"
|
||||
|
|
@ -126,6 +127,7 @@ PUBLISHED:
|
|||
INLINE bool get_supports_2d_texture_array() const;
|
||||
INLINE bool get_supports_cube_map() const;
|
||||
INLINE bool get_supports_tex_non_pow2() const;
|
||||
INLINE bool get_supports_texture_srgb() const;
|
||||
|
||||
INLINE bool get_supports_compressed_texture() const;
|
||||
virtual INLINE bool get_supports_compressed_texture_format(int compression_mode) const;
|
||||
|
|
@ -151,6 +153,10 @@ PUBLISHED:
|
|||
INLINE bool get_supports_two_sided_stencil() const;
|
||||
INLINE bool get_supports_geometry_instancing() const;
|
||||
|
||||
INLINE bool get_supports_occlusion_query() const;
|
||||
INLINE bool get_supports_timer_query() const;
|
||||
INLINE bool get_timer_queries_active() const;
|
||||
|
||||
INLINE int get_max_color_targets() const;
|
||||
INLINE int get_maximum_simultaneous_render_targets() const;
|
||||
|
||||
|
|
@ -200,7 +206,7 @@ PUBLISHED:
|
|||
virtual int get_driver_version_minor();
|
||||
virtual int get_driver_shader_version_major();
|
||||
virtual int get_driver_shader_version_minor();
|
||||
|
||||
|
||||
bool set_scene(SceneSetup *scene_setup);
|
||||
virtual SceneSetup *get_scene() const;
|
||||
|
||||
|
|
@ -222,10 +228,11 @@ public:
|
|||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
|
||||
virtual bool get_supports_occlusion_query() const;
|
||||
virtual void begin_occlusion_query();
|
||||
virtual PT(OcclusionQueryContext) end_occlusion_query();
|
||||
|
||||
virtual PT(TimerQueryContext) issue_timer_query(int pstats_index);
|
||||
|
||||
virtual void dispatch_compute(int size_x, int size_y, int size_z);
|
||||
|
||||
virtual PT(GeomMunger) get_geom_munger(const RenderState *state,
|
||||
|
|
@ -239,7 +246,7 @@ public:
|
|||
virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const;
|
||||
|
||||
virtual void clear(DrawableRegion *clearable);
|
||||
|
||||
|
||||
const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered);
|
||||
const LMatrix4 *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4 &t);
|
||||
const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
|
||||
|
|
@ -260,6 +267,8 @@ PUBLISHED:
|
|||
public:
|
||||
virtual void end_frame(Thread *current_thread);
|
||||
|
||||
void flush_timer_queries();
|
||||
|
||||
void set_current_properties(const FrameBufferProperties *properties);
|
||||
|
||||
virtual bool depth_offset_decals();
|
||||
|
|
@ -375,7 +384,7 @@ protected:
|
|||
// This bitmask contains a 1 bit everywhere that _state_rs has a
|
||||
// known value. If a bit is 0, the corresponding state must be
|
||||
// re-sent.
|
||||
//
|
||||
//
|
||||
// Derived GSGs should initialize _inv_state_mask in reset() as a mask of
|
||||
// 1's where they don't care, and 0's where they do care, about the state.
|
||||
RenderState::SlotMask _state_mask;
|
||||
|
|
@ -406,7 +415,7 @@ protected:
|
|||
|
||||
unsigned int _color_write_mask;
|
||||
|
||||
CPT(DisplayRegion) _current_display_region;
|
||||
PT(DisplayRegion) _current_display_region;
|
||||
Lens::StereoChannel _current_stereo_channel;
|
||||
int _current_tex_view_offset;
|
||||
CPT(Lens) _current_lens;
|
||||
|
|
@ -468,6 +477,7 @@ protected:
|
|||
bool _supports_2d_texture_array;
|
||||
bool _supports_cube_map;
|
||||
bool _supports_tex_non_pow2;
|
||||
bool _supports_texture_srgb;
|
||||
|
||||
bool _supports_compressed_texture;
|
||||
BitMask32 _compressed_texture_formats;
|
||||
|
|
@ -481,6 +491,19 @@ protected:
|
|||
bool _supports_occlusion_query;
|
||||
PT(OcclusionQueryContext) _current_occlusion_query;
|
||||
|
||||
bool _supports_timer_query;
|
||||
#ifdef DO_PSTATS
|
||||
int _pstats_gpu_thread;
|
||||
bool _timer_queries_active;
|
||||
PStatFrameData _pstats_gpu_data;
|
||||
|
||||
int _last_query_frame;
|
||||
int _last_num_queried;
|
||||
//double _timer_delta;
|
||||
typedef pdeque<PT(TimerQueryContext)> TimerQueryQueue;
|
||||
TimerQueryQueue _pending_timer_queries;
|
||||
#endif
|
||||
|
||||
bool _copy_texture_inverted;
|
||||
bool _supports_multisample;
|
||||
bool _supports_generate_mipmap;
|
||||
|
|
@ -520,13 +543,13 @@ protected:
|
|||
|
||||
PN_stdfloat _gamma;
|
||||
Texture::QualityLevel _texture_quality_override;
|
||||
|
||||
|
||||
ShaderGenerator* _shader_generator;
|
||||
|
||||
#ifndef NDEBUG
|
||||
PT(Texture) _flash_texture;
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
// Statistics
|
||||
static PStatCollector _vertex_buffer_switch_pcollector;
|
||||
|
|
@ -558,7 +581,18 @@ public:
|
|||
static PStatCollector _draw_set_state_pcollector;
|
||||
static PStatCollector _clear_pcollector;
|
||||
static PStatCollector _flush_pcollector;
|
||||
static PStatCollector _compute_dispatch_pcollector;
|
||||
static PStatCollector _wait_occlusion_pcollector;
|
||||
static PStatCollector _wait_timer_pcollector;
|
||||
static PStatCollector _timer_queries_pcollector;
|
||||
static PStatCollector _command_latency_pcollector;
|
||||
|
||||
static PStatCollector _prepare_pcollector;
|
||||
static PStatCollector _prepare_texture_pcollector;
|
||||
static PStatCollector _prepare_geom_pcollector;
|
||||
static PStatCollector _prepare_shader_pcollector;
|
||||
static PStatCollector _prepare_vertex_buffer_pcollector;
|
||||
static PStatCollector _prepare_index_buffer_pcollector;
|
||||
|
||||
// A whole slew of collectors to measure the cost of individual
|
||||
// state changes. These are disabled by default.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// Filename: pStatGPUTimer.I
|
||||
// Created by: rdb (21Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatGPUTimer::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PStatGPUTimer::
|
||||
PStatGPUTimer(GraphicsStateGuardian *gsg, PStatCollector &collector) :
|
||||
PStatTimer(collector),
|
||||
_gsg(gsg)
|
||||
{
|
||||
if (gsg->get_timer_queries_active()) {
|
||||
gsg->issue_timer_query(collector.get_index());
|
||||
//cerr << "issuing " << collector << " active " << collector.is_active() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatGPUTimer::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PStatGPUTimer::
|
||||
PStatGPUTimer(GraphicsStateGuardian *gsg, PStatCollector &collector, Thread *current_thread) :
|
||||
PStatTimer(collector, current_thread),
|
||||
_gsg(gsg)
|
||||
{
|
||||
if (gsg->get_timer_queries_active()) {
|
||||
gsg->issue_timer_query(collector.get_index());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatGPUTimer::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PStatGPUTimer::
|
||||
~PStatGPUTimer() {
|
||||
if (_gsg->get_timer_queries_active()) {
|
||||
_gsg->issue_timer_query(_collector.get_index() | 0x8000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// Filename: pStatGPUTimer.h
|
||||
// Created by: rdb (21Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PSTATGPUTIMER_H
|
||||
#define PSTATGPUTIMER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "config_pstats.h"
|
||||
#include "timerQueryContext.h"
|
||||
|
||||
class Thread;
|
||||
class GraphicsStateGuardian;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PStatGPUTimer
|
||||
// Description : This is a special type of PStatTimer that also
|
||||
// uses a timer query on the GSG to measure how long
|
||||
// a task actually takes to execute on the GPU, rather
|
||||
// than how long it took for the API commands to be
|
||||
// queued up.
|
||||
//
|
||||
// This class may only be used on the draw thread.
|
||||
//
|
||||
// At present, it tracks both the CPU time (like a
|
||||
// regular PStatTimer does) and the GPU time, which
|
||||
// is recorded using a special PStatThread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DISPLAY PStatGPUTimer : public PStatTimer {
|
||||
public:
|
||||
#ifdef DO_PSTATS
|
||||
INLINE PStatGPUTimer(GraphicsStateGuardian *gsg,
|
||||
PStatCollector &collector);
|
||||
INLINE PStatGPUTimer(GraphicsStateGuardian *gsg,
|
||||
PStatCollector &collector,
|
||||
Thread *current_thread);
|
||||
INLINE ~PStatGPUTimer();
|
||||
|
||||
GraphicsStateGuardian *_gsg;
|
||||
|
||||
private:
|
||||
#else // DO_PSTATS
|
||||
|
||||
INLINE PStatGPUTimer(GraphicsStateGuardian *, PStatCollector &col)
|
||||
: PStatTimer(col) { }
|
||||
INLINE PStatGPUTimer(GraphicsStateGuardian *, PStatCollector &col, Thread *)
|
||||
: PStatTimer(col) { }
|
||||
INLINE ~PStatGPUTimer() { }
|
||||
|
||||
#endif // DO_PSTATS
|
||||
};
|
||||
|
||||
#include "pStatGPUTimer.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -178,7 +178,10 @@ munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
|
|||
// Even beyond munging the vertex format, we have to convert the
|
||||
// Geom itself into a new primitive type the GSG can render
|
||||
// directly.
|
||||
if ((unsupported_bits & Geom::GR_composite_bits) != 0) {
|
||||
// If we don't support a strip cut index, it might be faster to
|
||||
// just decompose it rather than draw them one by one.
|
||||
if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
|
||||
(unsupported_bits & Geom::GR_strip_cut_index) != 0) {
|
||||
// This decomposes everything in the primitive, so that if (for
|
||||
// instance) the primitive contained both strips and fans, but
|
||||
// the GSG didn't support fans, it would decompose the strips
|
||||
|
|
@ -224,7 +227,10 @@ premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data) {
|
|||
// Even beyond munging the vertex format, we have to convert the
|
||||
// Geom itself into a new primitive type the GSG can render
|
||||
// directly.
|
||||
if ((unsupported_bits & Geom::GR_composite_bits) != 0) {
|
||||
// If we don't support a strip cut index, it might be faster to
|
||||
// just decompose it rather than draw them one by one.
|
||||
if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
|
||||
(unsupported_bits & Geom::GR_strip_cut_index) != 0) {
|
||||
// This decomposes everything in the primitive, so that if (for
|
||||
// instance) the primitive contained both strips and fans, but
|
||||
// the GSG didn't support fans, it would decompose the strips
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
wdxGraphicsPipe8.I wdxGraphicsPipe8.h \
|
||||
wdxGraphicsWindow8.I wdxGraphicsWindow8.h \
|
||||
dxgsg8base.h config_dxgsg8.h dxGraphicsStateGuardian8.I dxGraphicsStateGuardian8.h \
|
||||
dxVertexBufferContext8.h dxVertexbufferContext8.I \
|
||||
dxVertexBufferContext8.h dxVertexBufferContext8.I \
|
||||
dxIndexBufferContext8.h dxIndexBufferContext8.I \
|
||||
dxTextureContext8.h dxTextureContext8.I \
|
||||
dxGeomMunger8.h dxGeomMunger8.I \
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ handle_reshape() {
|
|||
GdiFlush();
|
||||
WinGraphicsWindow::handle_reshape();
|
||||
|
||||
if (_dxgsg != NULL) {
|
||||
if (_dxgsg != NULL && _dxgsg->_d3d_device != NULL) {
|
||||
// create the new resized rendertargets
|
||||
WindowProperties props = get_properties();
|
||||
int x_size = props.get_x_size();
|
||||
|
|
@ -422,7 +422,7 @@ handle_reshape() {
|
|||
if (_wcontext._presentation_params.BackBufferWidth != x_size ||
|
||||
_wcontext._presentation_params.BackBufferHeight != y_size) {
|
||||
bool resize_succeeded = reset_device_resize_window(x_size, y_size);
|
||||
|
||||
|
||||
if (wdxdisplay8_cat.is_debug()) {
|
||||
if (!resize_succeeded) {
|
||||
wdxdisplay8_cat.debug()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
wdxGraphicsPipe9.I wdxGraphicsPipe9.h \
|
||||
wdxGraphicsWindow9.I wdxGraphicsWindow9.h \
|
||||
dxgsg9base.h config_dxgsg9.h dxGraphicsStateGuardian9.I dxGraphicsStateGuardian9.h \
|
||||
dxVertexBufferContext9.h dxVertexbufferContext9.I \
|
||||
dxVertexBufferContext9.h dxVertexBufferContext9.I \
|
||||
dxIndexBufferContext9.h dxIndexBufferContext9.I \
|
||||
dxTextureContext9.h dxTextureContext9.I \
|
||||
dxGeomMunger9.h dxGeomMunger9.I \
|
||||
|
|
|
|||
|
|
@ -224,6 +224,13 @@ apply_texture(int i, TextureContext *tc) {
|
|||
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||
Texture *tex = tc->get_texture();
|
||||
|
||||
//if (tex->get_color_space() == CS_srgb) {
|
||||
if (Texture::is_srgb(tex->get_format())) {
|
||||
set_sampler_state(i, D3DSAMP_SRGBTEXTURE, TRUE);
|
||||
} else {
|
||||
set_sampler_state(i, D3DSAMP_SRGBTEXTURE, FALSE);
|
||||
}
|
||||
|
||||
Texture::WrapMode wrap_u, wrap_v, wrap_w;
|
||||
|
||||
DWORD address_u;
|
||||
|
|
@ -256,7 +263,7 @@ apply_texture(int i, TextureContext *tc) {
|
|||
|
||||
int supports_anisotropic_mag_filter;
|
||||
D3DTEXTUREFILTERTYPE new_mag_filter;
|
||||
|
||||
|
||||
supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
|
||||
if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
|
||||
new_mag_filter = ((ft != Texture::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
|
||||
|
|
@ -268,8 +275,8 @@ apply_texture(int i, TextureContext *tc) {
|
|||
hr = set_sampler_state(i, D3DSAMP_MAGFILTER, new_mag_filter);
|
||||
if (hr != D3D_OK) {
|
||||
dxgsg9_cat.error()
|
||||
<< "ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
|
||||
<< new_mag_filter << ") failed for texture:" << tex -> get_name() << endl;
|
||||
<< "ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
|
||||
<< new_mag_filter << ") failed for texture:" << tex -> get_name() << endl;
|
||||
}
|
||||
|
||||
// map Panda composite min+mip filter types to d3d's separate min & mip filter types
|
||||
|
|
@ -353,7 +360,7 @@ upload_texture(DXTextureContext9 *dtc, bool force) {
|
|||
dtc->delete_texture();
|
||||
dtc->update_data_size_bytes(0);
|
||||
dtc->mark_unloaded();
|
||||
|
||||
|
||||
if (_effective_incomplete_render && !force) {
|
||||
bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
|
||||
if (!has_image && tex->might_have_ram_image() &&
|
||||
|
|
@ -371,7 +378,7 @@ upload_texture(DXTextureContext9 *dtc, bool force) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dtc->create_texture(*_screen);
|
||||
}
|
||||
|
||||
|
|
@ -746,7 +753,7 @@ begin_occlusion_query() {
|
|||
<< "Occlusion query failed.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PT(DXOcclusionQueryContext9) queryobj = new DXOcclusionQueryContext9(query);
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
|
|
@ -776,7 +783,7 @@ end_occlusion_query() {
|
|||
PT(OcclusionQueryContext) result = _current_occlusion_query;
|
||||
|
||||
IDirect3DQuery9 *query = DCAST(DXOcclusionQueryContext9, result)->_query;
|
||||
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug()
|
||||
<< "ending occlusion query " << query << "\n";
|
||||
|
|
@ -857,7 +864,7 @@ clear(DrawableRegion *clearable) {
|
|||
aux_flags |= D3DCLEAR_ZBUFFER;
|
||||
HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value,
|
||||
depth_clear_value, stencil_clear_value);
|
||||
if (FAILED(hr2)) {
|
||||
if (FAILED(hr2)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to clear depth buffer; removing.\n";
|
||||
// This is really hacky code.
|
||||
|
|
@ -1040,6 +1047,12 @@ begin_frame(Thread *current_thread) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_current_properties->get_srgb_color()) {
|
||||
set_render_state(D3DRS_SRGBWRITEENABLE, TRUE);
|
||||
} else {
|
||||
set_render_state(D3DRS_SRGBWRITEENABLE, FALSE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1343,14 +1356,14 @@ update_standard_vertex_arrays(bool force) {
|
|||
dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Get the vertex buffer for this array.
|
||||
CLP(VertexBufferContext)* dvbc;
|
||||
if (!setup_array_data(dvbc, array_reader, force)) {
|
||||
dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Bind this array as the data source for the corresponding stream.
|
||||
const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
|
||||
hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
|
||||
|
|
@ -2315,7 +2328,7 @@ reset() {
|
|||
// want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
|
||||
|
||||
nassertv(_screen->_d3d9 != NULL);
|
||||
|
||||
|
||||
if (_d3d_device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -2379,27 +2392,27 @@ reset() {
|
|||
_shader_caps._ultimate_fprofile = (int)CG_PROFILE_PS_2_0;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
|
||||
|
||||
CGprofile vertex_profile;
|
||||
CGprofile pixel_profile;
|
||||
|
||||
|
||||
vertex_profile = cgD3D9GetLatestVertexProfile();
|
||||
pixel_profile = cgD3D9GetLatestPixelProfile();
|
||||
|
||||
|
||||
const char *vertex_profile_str =
|
||||
cgGetProfileString(vertex_profile);
|
||||
const char *pixel_profile_str =
|
||||
cgGetProfileString(pixel_profile);
|
||||
|
||||
|
||||
if (vertex_profile_str == NULL) {
|
||||
vertex_profile_str = "(null)";
|
||||
}
|
||||
if (pixel_profile_str == NULL) {
|
||||
pixel_profile_str = "(null)";
|
||||
}
|
||||
|
||||
|
||||
dxgsg9_cat.debug()
|
||||
<< "\nCg vertex profile = " << vertex_profile_str << " id = " << vertex_profile
|
||||
<< "\nCg pixel profile = " << pixel_profile_str << " id = " << pixel_profile
|
||||
|
|
@ -2495,7 +2508,7 @@ reset() {
|
|||
<< "\nDirectX SDK version " DIRECTX_SDK_VERSION
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
||||
// OVERRIDE SUPPORT SINCE IT DOES NOT WORK WELL
|
||||
_screen->_supports_automatic_mipmap_generation = false;
|
||||
|
||||
|
|
@ -2618,12 +2631,19 @@ reset() {
|
|||
|
||||
_last_testcooplevel_result = D3D_OK;
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug() << "Supported texture formats:\n";
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_POSSIBLE_TEXFMTS; i++) {
|
||||
// look for all possible DX9 texture fmts
|
||||
D3DFORMAT_FLAG fmtflag = D3DFORMAT_FLAG(1 << i);
|
||||
hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format,
|
||||
0x0, D3DRTYPE_TEXTURE, g_D3DFORMATmap[fmtflag]);
|
||||
if (SUCCEEDED(hr)){
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug() << " " << D3DFormatStr(g_D3DFORMATmap[fmtflag]) << "\n";
|
||||
}
|
||||
_screen->_supported_tex_formats_mask |= fmtflag;
|
||||
}
|
||||
}
|
||||
|
|
@ -2632,7 +2652,7 @@ reset() {
|
|||
#define CHECK_FOR_DXTVERSION(num) \
|
||||
if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\
|
||||
if (dxgsg9_cat.is_debug()) {\
|
||||
dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported \n";\
|
||||
dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported\n";\
|
||||
}\
|
||||
_supports_compressed_texture = true;\
|
||||
_compressed_texture_formats.set_bit(Texture::CM_dxt##num);\
|
||||
|
|
@ -2641,9 +2661,9 @@ reset() {
|
|||
if (_screen->_intel_compressed_texture_bug) {
|
||||
dxgsg9_cat.info()
|
||||
<< "Buggy Intel driver detected; disabling compressed textures.\n";
|
||||
_screen->_supported_tex_formats_mask &=
|
||||
_screen->_supported_tex_formats_mask &=
|
||||
~(DXT1_FLAG | DXT2_FLAG | DXT3_FLAG | DXT4_FLAG | DXT5_FLAG);
|
||||
|
||||
|
||||
} else {
|
||||
// Check for available compressed formats normally.
|
||||
CHECK_FOR_DXTVERSION(1);
|
||||
|
|
@ -2652,7 +2672,7 @@ reset() {
|
|||
CHECK_FOR_DXTVERSION(4);
|
||||
CHECK_FOR_DXTVERSION(5);
|
||||
}
|
||||
|
||||
|
||||
#undef CHECK_FOR_DXTVERSION
|
||||
|
||||
_screen->_supports_rgba16f_texture_format = false;
|
||||
|
|
@ -3292,7 +3312,7 @@ set_state_and_transform(const RenderState *target,
|
|||
!_state_mask.get_bit(transparency_slot) ||
|
||||
!_state_mask.get_bit(color_write_slot) ||
|
||||
!_state_mask.get_bit(color_blend_slot) ||
|
||||
(_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
|
||||
(_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
|
||||
_state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
|
||||
//PStatTimer timer(_draw_set_state_blending_pcollector);
|
||||
do_issue_blending();
|
||||
|
|
@ -3353,7 +3373,7 @@ set_state_and_transform(const RenderState *target,
|
|||
do_issue_stencil();
|
||||
_state_mask.set_bit(stencil_slot);
|
||||
}
|
||||
|
||||
|
||||
int fog_slot = FogAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
|
||||
!_state_mask.get_bit(fog_slot)) {
|
||||
|
|
@ -3446,22 +3466,22 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
|||
const LMatrix4 &light_mat = transform->get_mat();
|
||||
LMatrix4 rel_mat = light_mat * LMatrix4::convert_mat(CS_yup_left, CS_default);
|
||||
LVector3f dir = LCAST(float, light_obj->get_direction() * rel_mat);
|
||||
|
||||
|
||||
D3DCOLORVALUE black;
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
|
||||
|
||||
ZeroMemory(&fdata, sizeof(D3DLIGHT9));
|
||||
|
||||
|
||||
fdata.Type = D3DLIGHT_DIRECTIONAL;
|
||||
fdata.Ambient = black ;
|
||||
LColorf color = LCAST(float, light_obj->get_specular_color());
|
||||
fdata.Specular = *(D3DCOLORVALUE *)(color.get_data());
|
||||
|
||||
|
||||
fdata.Direction = *(D3DVECTOR *)dir.get_data();
|
||||
|
||||
|
||||
fdata.Range = __D3DLIGHT_RANGE_MAX;
|
||||
fdata.Falloff = 1.0f;
|
||||
|
||||
|
||||
fdata.Attenuation0 = 1.0f; // constant
|
||||
fdata.Attenuation1 = 0.0f; // linear
|
||||
fdata.Attenuation2 = 0.0f; // quadratic
|
||||
|
|
@ -4125,7 +4145,7 @@ close_gsg() {
|
|||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug()
|
||||
<< "Closing GSG, prepared_objects count = "
|
||||
<< "Closing GSG, prepared_objects count = "
|
||||
<< _prepared_objects->get_ref_count() << "\n";
|
||||
}
|
||||
|
||||
|
|
@ -4210,9 +4230,9 @@ set_read_buffer(const RenderBuffer &rb) {
|
|||
if (rb._buffer_type & RenderBuffer::T_front) {
|
||||
_cur_read_pixel_buffer = RenderBuffer::T_front;
|
||||
} else if (rb._buffer_type & RenderBuffer::T_back) {
|
||||
_cur_read_pixel_buffer = RenderBuffer::T_back;
|
||||
_cur_read_pixel_buffer = RenderBuffer::T_back;
|
||||
} else if (rb._buffer_type & RenderBuffer::T_aux_rgba_ALL) {
|
||||
_cur_read_pixel_buffer = RenderBuffer::T_back;
|
||||
_cur_read_pixel_buffer = RenderBuffer::T_back;
|
||||
} else {
|
||||
dxgsg9_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n";
|
||||
}
|
||||
|
|
@ -4816,7 +4836,7 @@ check_cooperative_level() {
|
|||
case D3DERR_DEVICELOST:
|
||||
// sleep while the device is lost to free up the CPU
|
||||
Sleep (10);
|
||||
|
||||
|
||||
if (SUCCEEDED(_last_testcooplevel_result)) {
|
||||
if (_dx_is_ready) {
|
||||
_dx_is_ready = false;
|
||||
|
|
@ -4847,7 +4867,7 @@ show_frame() {
|
|||
if (_swap_chain) {
|
||||
DWORD flags;
|
||||
flags = 0;
|
||||
|
||||
|
||||
hr = _swap_chain->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL, flags);
|
||||
} else {
|
||||
hr = _d3d_device->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL);
|
||||
|
|
@ -5220,7 +5240,7 @@ check_dx_allocation (HRESULT result, int allocation_size, int attempts)
|
|||
// increase the page out size as the number of attempts increases
|
||||
{
|
||||
size_t current_size = _prepared_objects->_graphics_memory_lru.get_total_size();
|
||||
size_t target_size = max(current_size - allocation_size * attempts, 0);
|
||||
size_t target_size = max(current_size - allocation_size * attempts, (size_t) 0);
|
||||
_prepared_objects->_graphics_memory_lru.evict_to(target_size);
|
||||
dxgsg9_cat.info()
|
||||
<< "Evicted " << current_size - _prepared_objects->_graphics_memory_lru.get_total_size() << " bytes of texture memory to make room for more.\n";
|
||||
|
|
@ -5435,7 +5455,7 @@ do_issue_stencil() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: dxGraphicsStateGuardian9::do_issue_scissor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
do_issue_scissor() {
|
||||
|
|
@ -5522,8 +5542,8 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
|
|||
// avoid divide by zero and negative exponents
|
||||
gamma = 1.0;
|
||||
}
|
||||
gamma_correction = 1.0 / (double) gamma;
|
||||
|
||||
gamma_correction = 1.0 / (double) gamma;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
double r;
|
||||
double g;
|
||||
|
|
@ -5534,11 +5554,11 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
|
|||
g = (double) original_green_table [i] / GAMMA_1;
|
||||
b = (double) original_blue_table [i] / GAMMA_1;
|
||||
}
|
||||
else {
|
||||
else {
|
||||
r = ((double) i / 255.0);
|
||||
g = r;
|
||||
b = r;
|
||||
}
|
||||
}
|
||||
|
||||
r = pow (r, gamma_correction);
|
||||
g = pow (g, gamma_correction);
|
||||
|
|
@ -5554,14 +5574,14 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
|
|||
b = 1.0;
|
||||
}
|
||||
|
||||
r = r * GAMMA_1;
|
||||
g = g * GAMMA_1;
|
||||
b = b * GAMMA_1;
|
||||
r = r * GAMMA_1;
|
||||
g = g * GAMMA_1;
|
||||
b = b * GAMMA_1;
|
||||
|
||||
red_table [i] = r;
|
||||
green_table [i] = g;
|
||||
blue_table [i] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -5571,13 +5591,13 @@ void _create_gamma_table (PN_stdfloat gamma, unsigned short *original_red_table,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
get_gamma_table(void) {
|
||||
bool get;
|
||||
bool get;
|
||||
|
||||
get = false;
|
||||
if (_gamma_table_initialized == false) {
|
||||
HDC hdc = GetDC(NULL);
|
||||
|
||||
if (hdc) {
|
||||
if (hdc) {
|
||||
if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
|
||||
_gamma_table_initialized = true;
|
||||
get = true;
|
||||
|
|
@ -5586,26 +5606,26 @@ get_gamma_table(void) {
|
|||
ReleaseDC (NULL, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return get;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian9::static_set_gamma
|
||||
// Access: Public, Static
|
||||
// Description: Static function for setting gamma which is needed
|
||||
// Description: Static function for setting gamma which is needed
|
||||
// for atexit.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
static_set_gamma(bool restore, PN_stdfloat gamma) {
|
||||
bool set;
|
||||
bool set;
|
||||
HDC hdc = GetDC(NULL);
|
||||
|
||||
set = false;
|
||||
if (hdc) {
|
||||
if (hdc) {
|
||||
unsigned short ramp [256 * 3];
|
||||
|
||||
if (restore && _gamma_table_initialized) {
|
||||
if (restore && _gamma_table_initialized) {
|
||||
_create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
|
||||
}
|
||||
else {
|
||||
|
|
@ -5615,7 +5635,7 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
|
|||
if (SetDeviceGammaRamp (hdc, ramp)) {
|
||||
set = true;
|
||||
}
|
||||
|
||||
|
||||
ReleaseDC (NULL, hdc);
|
||||
}
|
||||
|
||||
|
|
@ -5634,7 +5654,7 @@ set_gamma(PN_stdfloat gamma) {
|
|||
|
||||
set = static_set_gamma(false, gamma);
|
||||
if (set) {
|
||||
_gamma = gamma;
|
||||
_gamma = gamma;
|
||||
}
|
||||
|
||||
return set;
|
||||
|
|
@ -5664,7 +5684,7 @@ atexit_function(void) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian9::get_supports_cg_profile
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if this particular GSG supports the
|
||||
// Description: Returns true if this particular GSG supports the
|
||||
// specified Cg Shader Profile.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
|
|
@ -5673,7 +5693,7 @@ get_supports_cg_profile(const string &name) const {
|
|||
return false;
|
||||
#else
|
||||
CGprofile profile = cgGetProfile(name.c_str());
|
||||
|
||||
|
||||
if (profile == CG_PROFILE_UNKNOWN) {
|
||||
dxgsg9_cat.error() << name <<", unknown Cg-profile\n";
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@
|
|||
#include "vertexElementArray.h"
|
||||
#include "dxShaderContext9.h"
|
||||
|
||||
|
||||
enum GsgPageType
|
||||
{
|
||||
enum GsgPageType {
|
||||
GPT_Texture,
|
||||
GPT_VertexBuffer,
|
||||
GPT_IndexBuffer,
|
||||
|
|
@ -52,6 +50,8 @@ class DXTextureContext9;
|
|||
class DXVertexBufferContext9;
|
||||
class DXIndexBufferContext9;
|
||||
|
||||
class wdxGraphicsBuffer9;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DXGraphicsStateGuardian9
|
||||
// Description : A GraphicsStateGuardian for rendering into DirectX9
|
||||
|
|
@ -265,7 +265,7 @@ protected:
|
|||
|
||||
public:
|
||||
DXScreenData *_screen;
|
||||
|
||||
|
||||
protected:
|
||||
LPDIRECT3DDEVICE9 _d3d_device; // same as _screen->_d3d_device, cached for spd
|
||||
IDirect3DSwapChain9 *_swap_chain;
|
||||
|
|
@ -374,7 +374,7 @@ protected:
|
|||
|
||||
list <wdxGraphicsBuffer9 **> _graphics_buffer_list;
|
||||
|
||||
int _supports_gamma_calibration;
|
||||
int _supports_gamma_calibration;
|
||||
|
||||
static LPDIRECT3DDEVICE9 _cg_device;
|
||||
|
||||
|
|
|
|||
|
|
@ -135,13 +135,13 @@ create_texture(DXScreenData &scrn) {
|
|||
bool texture_wants_compressed = false;
|
||||
Texture::CompressionMode compression_mode = tex->get_ram_image_compression();
|
||||
bool texture_stored_compressed = compression_mode != Texture::CM_off;
|
||||
|
||||
|
||||
if (texture_stored_compressed) {
|
||||
texture_wants_compressed = true;
|
||||
texture_wants_compressed = true;
|
||||
} else {
|
||||
if (tex->get_compression() == Texture::CM_off) {
|
||||
// no compression
|
||||
} else {
|
||||
} else {
|
||||
if (tex->get_compression() == Texture::CM_default) {
|
||||
// default = use "compressed-textures" config setting
|
||||
if (compressed_textures) {
|
||||
|
|
@ -150,9 +150,9 @@ create_texture(DXScreenData &scrn) {
|
|||
} else {
|
||||
texture_wants_compressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (tex->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
|
|
@ -197,7 +197,9 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if ((tex->get_format() == Texture::F_luminance_alpha)||
|
||||
(tex->get_format() == Texture::F_luminance_alphamask) ||
|
||||
(tex->get_format() == Texture::F_luminance)) {
|
||||
(tex->get_format() == Texture::F_luminance) ||
|
||||
(tex->get_format() == Texture::F_sluminance_alpha) ||
|
||||
(tex->get_format() == Texture::F_sluminance)) {
|
||||
needs_luminance = true;
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +234,7 @@ create_texture(DXScreenData &scrn) {
|
|||
_d3d_format = D3DFMT_A8R8G8B8;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// make sure we handled all the possible cases
|
||||
nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
|
||||
|
||||
|
|
@ -398,9 +400,9 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (compress_texture) {
|
||||
if (num_alpha_bits <= 1) {
|
||||
CHECK_FOR_FMT(DXT1);
|
||||
CHECK_FOR_FMT(DXT1);
|
||||
} else if (num_alpha_bits <= 4) {
|
||||
CHECK_FOR_FMT(DXT3);
|
||||
CHECK_FOR_FMT(DXT3);
|
||||
} else {
|
||||
CHECK_FOR_FMT(DXT5);
|
||||
}
|
||||
|
|
@ -425,7 +427,7 @@ create_texture(DXScreenData &scrn) {
|
|||
// array (the texture array contains num_color_channels*8bits)
|
||||
|
||||
case 128:
|
||||
// check if format is supported
|
||||
// check if format is supported
|
||||
if (scrn._supports_rgba32_texture_format) {
|
||||
target_pixel_format = D3DFMT_A32B32G32R32F;
|
||||
}
|
||||
|
|
@ -435,7 +437,7 @@ create_texture(DXScreenData &scrn) {
|
|||
goto found_matching_format;
|
||||
|
||||
case 64:
|
||||
// check if format is supported
|
||||
// check if format is supported
|
||||
if (scrn._supports_rgba16f_texture_format) {
|
||||
target_pixel_format = D3DFMT_A16B16G16R16F;
|
||||
}
|
||||
|
|
@ -443,7 +445,7 @@ create_texture(DXScreenData &scrn) {
|
|||
target_pixel_format = scrn._render_to_texture_d3d_format;
|
||||
}
|
||||
goto found_matching_format;
|
||||
|
||||
|
||||
case 32:
|
||||
if (!((num_color_channels == 3) || (num_color_channels == 4)))
|
||||
break; //bail
|
||||
|
|
@ -502,7 +504,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
CHECK_FOR_FMT(X8R8G8B8);
|
||||
CHECK_FOR_FMT(A8R8G8B8);
|
||||
|
||||
|
||||
// no 24-bit or 32 fmt. look for 16 bit fmt (higher res 565 1st)
|
||||
CHECK_FOR_FMT(R5G6B5);
|
||||
CHECK_FOR_FMT(X1R5G5B5);
|
||||
|
|
@ -782,13 +784,13 @@ create_texture(DXScreenData &scrn) {
|
|||
// REQUIRED PARAMETERS
|
||||
_managed = false;
|
||||
_is_render_target = true;
|
||||
|
||||
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
usage = D3DUSAGE_RENDERTARGET;
|
||||
if (target_bpp <= 32 ) {
|
||||
target_pixel_format = scrn._render_to_texture_d3d_format;
|
||||
}
|
||||
|
||||
|
||||
dxgsg9_cat.debug ()
|
||||
<< "*** RENDER TO TEXTURE ***: format "
|
||||
<< D3DFormatStr(target_pixel_format)
|
||||
|
|
@ -848,7 +850,7 @@ create_texture(DXScreenData &scrn) {
|
|||
data_size *= 6;
|
||||
}
|
||||
update_data_size_bytes(data_size);
|
||||
|
||||
|
||||
int attempts;
|
||||
|
||||
if (dxgsg9_cat.is_debug()) {
|
||||
|
|
@ -882,7 +884,7 @@ create_texture(DXScreenData &scrn) {
|
|||
hr = scrn._d3d_device->CreateTexture
|
||||
(target_width, target_height, mip_level_count, usage,
|
||||
target_pixel_format, pool, &_d3d_2d_texture, NULL);
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
break;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
|
|
@ -952,7 +954,7 @@ create_texture(DXScreenData &scrn) {
|
|||
scrn._dxgsg9->get_engine()->texture_uploaded(tex);
|
||||
}
|
||||
mark_loaded();
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
error_exit:
|
||||
|
|
@ -967,7 +969,7 @@ create_texture(DXScreenData &scrn) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext9::create_simple_texture
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXTextureContext9::
|
||||
create_simple_texture(DXScreenData &scrn) {
|
||||
|
|
@ -993,7 +995,7 @@ create_simple_texture(DXScreenData &scrn) {
|
|||
hr = scrn._d3d_device->CreateTexture
|
||||
(target_width, target_height, mip_level_count, usage,
|
||||
target_pixel_format, pool, &_d3d_2d_texture, NULL);
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
|
||||
|
|
@ -1032,13 +1034,13 @@ create_simple_texture(DXScreenData &scrn) {
|
|||
|
||||
RELEASE(surface, dxgsg9, "create_simple_texture Surface", RELEASE_ONCE);
|
||||
}
|
||||
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.debug ()
|
||||
<< "*** fill_d3d_texture_pixels failed ***: format "
|
||||
<< target_pixel_format
|
||||
<< "\n";
|
||||
|
||||
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
|
|
@ -1084,7 +1086,7 @@ bool DXTextureContext9::
|
|||
extract_texture_data(DXScreenData &screen) {
|
||||
bool state;
|
||||
HRESULT hr;
|
||||
|
||||
|
||||
state = false;
|
||||
Texture *tex = get_texture();
|
||||
if (tex->get_texture_type() != Texture::TT_2d_texture) {
|
||||
|
|
@ -1147,7 +1149,7 @@ extract_texture_data(DXScreenData &screen) {
|
|||
|
||||
default:
|
||||
dxgsg9_cat.error()
|
||||
<< "Cannot extract texture data: unhandled surface format "
|
||||
<< "Cannot extract texture data: unhandled surface format "
|
||||
<< desc.Format << "\n";
|
||||
return state;
|
||||
}
|
||||
|
|
@ -1164,13 +1166,13 @@ extract_texture_data(DXScreenData &screen) {
|
|||
if (_is_render_target) {
|
||||
IDirect3DSurface9* source_surface;
|
||||
IDirect3DSurface9* destination_surface;
|
||||
|
||||
|
||||
source_surface = 0;
|
||||
destination_surface = 0;
|
||||
|
||||
|
||||
hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface);
|
||||
if (hr == D3D_OK) {
|
||||
|
||||
if (hr == D3D_OK) {
|
||||
|
||||
D3DPOOL pool;
|
||||
D3DSURFACE_DESC surface_description;
|
||||
|
||||
|
|
@ -1186,7 +1188,7 @@ extract_texture_data(DXScreenData &screen) {
|
|||
NULL);
|
||||
if (hr == D3D_OK) {
|
||||
if (source_surface && destination_surface) {
|
||||
hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
|
||||
hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
|
||||
if (hr == D3D_OK) {
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
|
|
@ -1200,13 +1202,13 @@ extract_texture_data(DXScreenData &screen) {
|
|||
|
||||
int surface_bytes_per_line;
|
||||
unsigned char *surface_pointer;
|
||||
|
||||
|
||||
bytes_per_line = surface_description.Width * this -> d3d_format_to_bytes_per_pixel (surface_description.Format);
|
||||
size = bytes_per_line * surface_description.Height;
|
||||
|
||||
surface_bytes_per_line = rect.Pitch;
|
||||
surface_pointer = (unsigned char *) rect.pBits;
|
||||
|
||||
|
||||
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||
|
||||
int offset;
|
||||
|
|
@ -1217,29 +1219,29 @@ extract_texture_data(DXScreenData &screen) {
|
|||
memcpy (&image [offset], surface_pointer, bytes_per_line);
|
||||
|
||||
offset += bytes_per_line;
|
||||
surface_pointer += surface_bytes_per_line;
|
||||
surface_pointer += surface_bytes_per_line;
|
||||
}
|
||||
|
||||
tex->set_ram_image(image, Texture::CM_off);
|
||||
|
||||
state = true;
|
||||
|
||||
|
||||
destination_surface -> UnlockRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
destination_surface -> Release ( );
|
||||
}
|
||||
else {
|
||||
dxgsg9_cat.error()
|
||||
<< "CreateImageSurface failed in extract_texture_data()"
|
||||
<< D3DERRORSTRING(hr);
|
||||
}
|
||||
<< D3DERRORSTRING(hr);
|
||||
}
|
||||
source_surface -> Release ( );
|
||||
}
|
||||
}
|
||||
else {
|
||||
else {
|
||||
for (int n = 0; n < num_levels; ++n) {
|
||||
D3DLOCKED_RECT rect;
|
||||
hr = _d3d_2d_texture->LockRect(n, &rect, NULL, D3DLOCK_READONLY);
|
||||
|
|
@ -1248,11 +1250,11 @@ extract_texture_data(DXScreenData &screen) {
|
|||
<< "Texture::LockRect() failed! level = " << n << " " << D3DERRORSTRING(hr);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
int x_size = tex->get_expected_mipmap_x_size(n);
|
||||
int y_size = tex->get_expected_mipmap_y_size(n);
|
||||
PTA_uchar image;
|
||||
|
||||
|
||||
if (compression == Texture::CM_off) {
|
||||
// Uncompressed, but we have to respect the pitch.
|
||||
int pitch = x_size * tex->get_num_components() * tex->get_component_width();
|
||||
|
|
@ -1273,7 +1275,7 @@ extract_texture_data(DXScreenData &screen) {
|
|||
source += rect.Pitch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// Compressed; just copy the data verbatim.
|
||||
int size = rect.Pitch * (y_size / div);
|
||||
|
|
@ -1288,10 +1290,10 @@ extract_texture_data(DXScreenData &screen) {
|
|||
tex->set_ram_mipmap_image(n, image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
state = true;
|
||||
}
|
||||
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
@ -1560,7 +1562,7 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: calculate_row_byte_length
|
||||
// Access: Private, hidden
|
||||
// Description: local helper function, which calculates the
|
||||
// Description: local helper function, which calculates the
|
||||
// 'row_byte_length' or 'pitch' needed for calling
|
||||
// D3DXLoadSurfaceFromMemory.
|
||||
// Takes compressed formats (DXTn) into account.
|
||||
|
|
@ -1596,12 +1598,12 @@ static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFOR
|
|||
// Access: Private
|
||||
// Description: Called from fill_d3d_texture_pixels, this function
|
||||
// fills a single mipmap with texture data.
|
||||
// Takes care of all necessery conversions and error
|
||||
// Takes care of all necessary conversions and error
|
||||
// handling.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format)
|
||||
{
|
||||
// This whole function was refactored out of fill_d3d_texture_pixels to make the code
|
||||
// This whole function was refactored out of fill_d3d_texture_pixels to make the code
|
||||
// more readable and to avoid code duplication.
|
||||
IDirect3DSurface9 *mip_surface = NULL;
|
||||
bool using_temp_buffer = false;
|
||||
|
|
@ -1617,7 +1619,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||
pixels += view_size * get_view();
|
||||
size_t page_size = get_texture()->get_expected_ram_mipmap_page_size(mip_level);
|
||||
pixels += page_size * depth_index;
|
||||
|
||||
|
||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
||||
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
||||
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface);
|
||||
|
|
@ -1645,6 +1647,10 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||
// dithering)??)
|
||||
mip_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
||||
|
||||
if (Texture::is_srgb(get_texture()->get_format())) {
|
||||
mip_filter |= D3DX_FILTER_SRGB;
|
||||
}
|
||||
|
||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
||||
// full white, so convert to explicit luminance-alpha format
|
||||
if (_d3d_format == D3DFMT_A8) {
|
||||
|
|
@ -1671,7 +1677,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||
source_format = D3DFMT_A8L8;
|
||||
source_row_byte_length = width * sizeof(USHORT);
|
||||
pixels = (BYTE*)temp_buffer;
|
||||
}
|
||||
}
|
||||
else if (component_width != 1) {
|
||||
// Convert from 16-bit per channel (or larger) format down to
|
||||
// 8-bit per channel. This throws away precision in the
|
||||
|
|
@ -1756,7 +1762,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
// operations or something.
|
||||
if (tex->get_render_to_texture()) {
|
||||
if (tex->get_render_to_texture()) {
|
||||
HRESULT result;
|
||||
|
||||
if (_d3d_2d_texture) {
|
||||
|
|
@ -1777,7 +1783,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
depth_stencil_surface = 0;
|
||||
if (device -> GetDepthStencilSurface (&depth_stencil_surface) == D3D_OK) {
|
||||
if (device -> SetDepthStencilSurface (NULL) == D3D_OK) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1791,7 +1797,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
}
|
||||
}
|
||||
|
||||
// restore depth stencil
|
||||
// restore depth stencil
|
||||
if (depth_stencil_surface) {
|
||||
device -> SetDepthStencilSurface (depth_stencil_surface);
|
||||
depth_stencil_surface -> Release();
|
||||
|
|
@ -1806,7 +1812,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
surface -> Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
return E_FAIL;
|
||||
|
|
@ -1842,7 +1848,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
}
|
||||
|
||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||
|
||||
|
||||
// fill top level mipmap
|
||||
hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -1861,8 +1867,8 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
if (FAILED(hr)) {
|
||||
return hr; // error message was already output in fill_d3d_texture_mipmap_pixels
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// mipmaps need to be generated, either use autogen or d3dx functions
|
||||
|
||||
|
|
@ -1888,6 +1894,10 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
|
|||
mip_filter_flags = D3DX_FILTER_TRIANGLE;
|
||||
}
|
||||
|
||||
if (Texture::is_srgb(tex->get_format())) {
|
||||
mip_filter_flags |= D3DX_FILTER_SRGB;
|
||||
}
|
||||
|
||||
// mip_filter_flags |= D3DX_FILTER_DITHER;
|
||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
||||
mip_filter_flags);
|
||||
|
|
@ -1934,7 +1944,7 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
|
|||
if (!scrn._dxgsg9->get_supports_compressed_texture_format(image_compression)) {
|
||||
image = tex->get_uncompressed_ram_image();
|
||||
image_compression = Texture::CM_off;
|
||||
}
|
||||
}
|
||||
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
|
|
@ -1991,6 +2001,10 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
|
|||
// dithering)??)
|
||||
level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
||||
|
||||
if (Texture::is_srgb(tex->get_format())) {
|
||||
level_0_filter |= D3DX_FILTER_SRGB;
|
||||
}
|
||||
|
||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
||||
// full white, so convert to explicit luminance-alpha format
|
||||
if (_d3d_format == D3DFMT_A8) {
|
||||
|
|
@ -2070,6 +2084,10 @@ fill_d3d_volume_texture_pixels(DXScreenData &scrn) {
|
|||
mip_filter_flags = D3DX_FILTER_TRIANGLE;
|
||||
}
|
||||
|
||||
if (Texture::is_srgb(tex->get_format())) {
|
||||
mip_filter_flags |= D3DX_FILTER_SRGB;
|
||||
}
|
||||
|
||||
// mip_filter_flags| = D3DX_FILTER_DITHER;
|
||||
|
||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
||||
|
|
@ -2167,6 +2185,17 @@ get_bits_per_pixel(Texture::Format format, int *alphbits) {
|
|||
case Texture::F_rgba32:
|
||||
*alphbits = 32;
|
||||
return 128;
|
||||
|
||||
case Texture::F_srgb:
|
||||
return 24;
|
||||
case Texture::F_srgb_alpha:
|
||||
*alphbits = 8;
|
||||
return 32;
|
||||
case Texture::F_sluminance:
|
||||
return 8;
|
||||
case Texture::F_sluminance_alpha:
|
||||
*alphbits = 8;
|
||||
return 16;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
|
@ -2180,7 +2209,7 @@ PN_stdfloat DXTextureContext9::
|
|||
d3d_format_to_bytes_per_pixel (D3DFORMAT format)
|
||||
{
|
||||
PN_stdfloat bytes_per_pixel;
|
||||
|
||||
|
||||
bytes_per_pixel = 0.0f;
|
||||
switch (format)
|
||||
{
|
||||
|
|
@ -2246,6 +2275,6 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
|
|||
bytes_per_pixel = 1.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return bytes_per_pixel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ make_output(const string &name,
|
|||
// Early failure - if we are sure that this buffer WONT
|
||||
// meet specs, we can bail out early.
|
||||
if ((flags & BF_fb_props_optional) == 0) {
|
||||
if ((fb_prop.get_indexed_color() > 0)||
|
||||
if (fb_prop.get_indexed_color() ||
|
||||
(fb_prop.get_back_buffers() > 0)||
|
||||
(fb_prop.get_accum_bits() > 0)||
|
||||
(fb_prop.get_multisamples() > 0)) {
|
||||
|
|
@ -649,7 +649,7 @@ search_for_valid_displaymode(DXScreenData &scrn,
|
|||
continue;
|
||||
}
|
||||
|
||||
// disable refresh rate checking since SLI video cards may use
|
||||
// disable refresh rate checking since SLI video cards may use
|
||||
// refresh rates less than 60
|
||||
if (0) {
|
||||
if ((dispmode.RefreshRate<60) && (dispmode.RefreshRate>1)) {
|
||||
|
|
@ -663,7 +663,7 @@ search_for_valid_displaymode(DXScreenData &scrn,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Note no attempt is made to verify if format will work at
|
||||
// requested size, so even if this call succeeds, could still get
|
||||
// an out-of-video-mem error
|
||||
|
|
@ -956,7 +956,7 @@ const char *D3DFormatStr(D3DFORMAT fmt) {
|
|||
CASESTR(D3DFMT_D24X4S4);
|
||||
CASESTR(D3DFMT_VERTEXDATA);
|
||||
CASESTR(D3DFMT_INDEX16);
|
||||
CASESTR(D3DFMT_INDEX32);
|
||||
CASESTR(D3DFMT_INDEX32);
|
||||
CASESTR(D3DFMT_A16B16G16R16F);
|
||||
CASESTR(D3DFMT_A32B32G32R32F);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ verify_window_sizes(int numsizes, int *dimen) {
|
|||
void wdxGraphicsWindow9::
|
||||
close_window() {
|
||||
if (wdxdisplay9_cat.is_debug()) {
|
||||
wdxdisplay9_cat.debug()
|
||||
wdxdisplay9_cat.debug()
|
||||
<< "wdxGraphicsWindow9::close_window() " << this << "\n";
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ open_window() {
|
|||
// window.
|
||||
{
|
||||
WindowProperties resized_props;
|
||||
resized_props.set_size(_wcontext._display_mode.Width,
|
||||
resized_props.set_size(_wcontext._display_mode.Width,
|
||||
_wcontext._display_mode.Height);
|
||||
_properties.add_properties(resized_props);
|
||||
}
|
||||
|
|
@ -420,17 +420,17 @@ void wdxGraphicsWindow9::
|
|||
handle_reshape() {
|
||||
GdiFlush();
|
||||
WinGraphicsWindow::handle_reshape();
|
||||
|
||||
if (_dxgsg != NULL) {
|
||||
|
||||
if (_dxgsg != NULL && _dxgsg->_d3d_device != NULL) {
|
||||
// create the new resized rendertargets
|
||||
WindowProperties props = get_properties();
|
||||
int x_size = props.get_x_size();
|
||||
int y_size = props.get_y_size();
|
||||
|
||||
|
||||
if (_wcontext._presentation_params.BackBufferWidth != x_size ||
|
||||
_wcontext._presentation_params.BackBufferHeight != y_size) {
|
||||
bool resize_succeeded = reset_device_resize_window(x_size, y_size);
|
||||
|
||||
|
||||
if (wdxdisplay9_cat.is_debug()) {
|
||||
if (!resize_succeeded) {
|
||||
wdxdisplay9_cat.debug()
|
||||
|
|
@ -708,7 +708,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
|
|||
if (dx_disable_driver_management_ex) {
|
||||
dwBehaviorFlags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX;
|
||||
}
|
||||
|
||||
|
||||
if (is_fullscreen()) {
|
||||
// CREATE FULLSCREEN BUFFERS
|
||||
|
||||
|
|
@ -751,11 +751,11 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
|
|||
}
|
||||
|
||||
//From d3d8caps.h
|
||||
//D3DPRESENT_INTERVAL_DEFAULT = 0x00000000L
|
||||
//D3DPRESENT_INTERVAL_DEFAULT = 0x00000000L
|
||||
//#define D3DPRESENT_INTERVAL_ONE 0x00000001L
|
||||
//Next line is really sloppy, should either be D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_ONE
|
||||
//not a direct number! but I'm not going to touch it because it's working as is. Zhao 12/15/2011
|
||||
presentation_params->PresentationInterval = 0;
|
||||
presentation_params->PresentationInterval = 0;
|
||||
|
||||
//ATI 5450 doesn't like D3DSWAPEFFECT_FLIP
|
||||
presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
|
|
@ -803,7 +803,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
|
|||
|
||||
PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
|
||||
|
||||
if (presentation_params->EnableAutoDepthStencil) {
|
||||
if (presentation_params->EnableAutoDepthStencil) {
|
||||
int depth_bits;
|
||||
int stencil_bits;
|
||||
|
||||
|
|
@ -846,7 +846,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
|
|||
wdxdisplay9_cat.error() << "unknown depth stencil format " << presentation_params->AutoDepthStencilFormat;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
_fb_properties.set_stencil_bits(stencil_bits);
|
||||
_fb_properties.set_depth_bits(depth_bits);
|
||||
} else {
|
||||
|
|
@ -1118,16 +1118,16 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
|
|||
|
||||
if (is_fullscreen()) {
|
||||
bool bCouldntFindValidZBuf;
|
||||
|
||||
|
||||
dxpipe->search_for_valid_displaymode(_wcontext, dwRenderWidth, dwRenderHeight,
|
||||
bNeedZBuffer, bWantStencil,
|
||||
&_wcontext._supported_screen_depths_mask,
|
||||
&bCouldntFindValidZBuf,
|
||||
&pixFmt, dx_force_16bpp_zbuffer, true);
|
||||
|
||||
|
||||
// note I'm not saving refresh rate, will just use adapter
|
||||
// default at given res for now
|
||||
|
||||
|
||||
if (pixFmt == D3DFMT_UNKNOWN) {
|
||||
wdxdisplay9_cat.error()
|
||||
<< (bCouldntFindValidZBuf ? "Couldnt find valid zbuffer format to go with FullScreen mode" : "No supported FullScreen modes")
|
||||
|
|
|
|||
|
|
@ -31,5 +31,5 @@ VirtualFileMountAndroidAsset(AAssetManager *mgr, const string &apk_path) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE VirtualFileMountAndroidAsset::AssetStream::
|
||||
AssetStream(AAsset *asset) :
|
||||
istream(new AssetStreamBuf(asset)) {
|
||||
istream(new VirtualFileMountAndroidAsset::AssetStreamBuf(asset)) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ get_fd(const Filename &file, off_t *start, off_t *length) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool VirtualFileMountAndroidAsset::
|
||||
has_file(const Filename &file) const {
|
||||
return (file.empty() || is_directory(file) || is_regular_file(file));
|
||||
return (file.empty() || /*is_directory(file) ||*/ is_regular_file(file));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
#define GL_DEPTH_STENCIL_EXT GL_DEPTH_STENCIL_OES
|
||||
#define GL_UNSIGNED_INT_24_8_EXT GL_UNSIGNED_INT_24_8_OES
|
||||
#define GL_DEPTH24_STENCIL8_EXT GL_DEPTH24_STENCIL8_OES
|
||||
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
|
||||
#define GL_DEPTH_COMPONENT16 GL_DEPTH_COMPONENT16_OES
|
||||
#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
|
||||
#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "Cg/cgGL.h"
|
||||
|
||||
#include "pStatTimer.h"
|
||||
#include "pStatGPUTimer.h"
|
||||
|
||||
TypeHandle CLP(CgShaderContext)::_type_handle;
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
|||
|
||||
nassertv(s->get_language() == Shader::SL_Cg);
|
||||
|
||||
// Ask the shader to compile itself for us and
|
||||
// Ask the shader to compile itself for us and
|
||||
// to give us the resulting Cg program objects.
|
||||
if (!s->cg_compile_for(_glgsg->_shader_caps,
|
||||
_cg_context,
|
||||
|
|
@ -223,7 +223,7 @@ unbind() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
issue_parameters(int altered) {
|
||||
PStatTimer timer(_glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
//PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
|
|
@ -233,9 +233,9 @@ issue_parameters(int altered) {
|
|||
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
|
||||
if (altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
|
||||
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
|
||||
Shader::ShaderPtrData* ptr_data =
|
||||
Shader::ShaderPtrData* ptr_data =
|
||||
const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
|
||||
|
||||
|
||||
if (ptr_data == NULL){ //the input is not contained in ShaderPtrData
|
||||
release_resources();
|
||||
return;
|
||||
|
|
@ -249,14 +249,14 @@ issue_parameters(int altered) {
|
|||
int input_size = _ptr._dim[0] * _ptr._dim[1] * _ptr._dim[2];
|
||||
|
||||
// dimension is negative only if the parameter had the (deprecated)k_ prefix.
|
||||
if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) {
|
||||
GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected "
|
||||
if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) {
|
||||
GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected "
|
||||
<< input_size <<" got " << ptr_data->_size << "\n";
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
|
||||
|
||||
|
||||
switch (ptr_data->_type) {
|
||||
case Shader::SPT_float:
|
||||
switch(_ptr._info._class) {
|
||||
|
|
@ -271,7 +271,7 @@ issue_parameters(int altered) {
|
|||
case Shader::SAC_matrix: cgGLSetMatrixParameterfc(p,(float*)ptr_data->_ptr); continue;
|
||||
case Shader::SAC_array: {
|
||||
switch(_ptr._info._subclass) {
|
||||
case Shader::SAC_scalar:
|
||||
case Shader::SAC_scalar:
|
||||
cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||
case Shader::SAC_vector:
|
||||
switch(_ptr._dim[2]) {
|
||||
|
|
@ -298,7 +298,7 @@ issue_parameters(int altered) {
|
|||
case Shader::SAC_matrix: cgGLSetMatrixParameterdc(p,(double*)ptr_data->_ptr); continue;
|
||||
case Shader::SAC_array: {
|
||||
switch(_ptr._info._subclass) {
|
||||
case Shader::SAC_scalar:
|
||||
case Shader::SAC_scalar:
|
||||
cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||
case Shader::SAC_vector:
|
||||
switch(_ptr._dim[2]) {
|
||||
|
|
@ -323,8 +323,8 @@ issue_parameters(int altered) {
|
|||
case Shader::SAT_vec4: cgSetParameter4iv(p,(int*)ptr_data->_ptr); continue;
|
||||
}
|
||||
}
|
||||
default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
|
||||
release_resources();
|
||||
default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) :
|
||||
GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||
GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host),
|
||||
_bind_texture_pcollector(_draw_window_pcollector, "Bind textures"),
|
||||
_generate_mipmap_pcollector(_draw_window_pcollector, "Generate mipmaps"),
|
||||
_resolve_multisample_pcollector(_draw_window_pcollector, "Resolve multisamples")
|
||||
{
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
|
||||
|
|
@ -171,11 +174,12 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
|
||||
// In case of multisample rendering, we don't need to issue
|
||||
// the barrier until we call glBlitFramebuffer.
|
||||
#ifndef OPENGLES
|
||||
if (gl_enable_memory_barriers && _fbo_multisample == 0) {
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_R(glgsg, _gsg, false);
|
||||
|
||||
pvector<CLP(TextureContext)*>::iterator it;
|
||||
TextureContexts::iterator it;
|
||||
for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) {
|
||||
CLP(TextureContext) *gtc = *it;
|
||||
|
||||
|
|
@ -186,6 +190,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
|
|
@ -274,6 +279,8 @@ rebuild_bitplanes() {
|
|||
return;
|
||||
}
|
||||
|
||||
PStatGPUTimer timer(glgsg, _bind_texture_pcollector);
|
||||
|
||||
// Calculate bitplane size. This can be larger than the buffer.
|
||||
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
|
||||
if (_host->get_size() != _size) {
|
||||
|
|
@ -437,6 +444,19 @@ rebuild_bitplanes() {
|
|||
// Bind the FBO
|
||||
if (_fbo[layer] == 0) {
|
||||
glgsg->_glGenFramebuffers(1, &_fbo[layer]);
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (glgsg->_use_object_labels) {
|
||||
if (num_fbos > 1) {
|
||||
GLchar name[128];
|
||||
GLsizei len = snprintf(name, 128, "%s[%d]", _name.c_str(), layer);
|
||||
glgsg->_glObjectLabel(GL_FRAMEBUFFER, _fbo[layer], len, name);
|
||||
} else {
|
||||
glgsg->_glObjectLabel(GL_FRAMEBUFFER, _fbo[layer], _name.size(), _name.data());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_fbo[layer] == 0) {
|
||||
report_my_gl_errors();
|
||||
return;
|
||||
|
|
@ -469,7 +489,7 @@ rebuild_bitplanes() {
|
|||
_have_any_color = true;
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
#ifndef OPENGLES_1
|
||||
for (int i=0; i<_fb_properties.get_aux_rgba(); i++) {
|
||||
bind_slot(layer, rb_resize, attach, (RenderTexturePlane)(RTP_aux_rgba_0+i), next++);
|
||||
_have_any_color = true;
|
||||
|
|
@ -1131,6 +1151,8 @@ generate_mipmaps() {
|
|||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_V(glgsg, _gsg);
|
||||
|
||||
//PStatGPUTimer timer(glgsg, _generate_mipmap_pcollector);
|
||||
|
||||
pvector<CLP(TextureContext)*>::iterator it;
|
||||
for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) {
|
||||
CLP(TextureContext) *gtc = *it;
|
||||
|
|
@ -1168,7 +1190,8 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
|||
copy_to_textures();
|
||||
}
|
||||
|
||||
// Unbind the FBO
|
||||
// Unbind the FBO. TODO: calling bind_fbo is slow, so we should
|
||||
// probably move this to begin_frame to prevent unnecessary calls.
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_V(glgsg, _gsg);
|
||||
glgsg->bind_fbo(0);
|
||||
|
|
@ -1604,11 +1627,14 @@ check_host_valid() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsBuffer)::
|
||||
resolve_multisamples() {
|
||||
nassertv(_fbo.size() > 0);
|
||||
|
||||
CLP(GraphicsStateGuardian) *glgsg;
|
||||
DCAST_INTO_V(glgsg, _gsg);
|
||||
|
||||
nassertv(_fbo.size() > 0);
|
||||
PStatGPUTimer timer(glgsg, _resolve_multisample_pcollector);
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (gl_enable_memory_barriers) {
|
||||
// Issue memory barriers as necessary to make sure that the
|
||||
// texture memory is synchronized before we blit to it.
|
||||
|
|
@ -1623,6 +1649,7 @@ resolve_multisamples() {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glgsg->report_my_gl_errors();
|
||||
GLuint fbo = _fbo[0];
|
||||
|
|
@ -1631,7 +1658,7 @@ resolve_multisamples() {
|
|||
}
|
||||
glgsg->_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo);
|
||||
glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample);
|
||||
|
||||
|
||||
// If the depth buffer is shared, resolve it only on the last to render FBO.
|
||||
bool do_depth_blit = false;
|
||||
if (_rbm[RTP_depth_stencil] != 0 || _rbm[RTP_depth] != 0) {
|
||||
|
|
@ -1671,6 +1698,7 @@ resolve_multisamples() {
|
|||
GL_NEAREST);
|
||||
}
|
||||
// Now handle the other color buffers.
|
||||
#ifndef OPENGLES_1
|
||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||
if (_fb_properties.is_stereo()) {
|
||||
glReadBuffer(next);
|
||||
|
|
@ -1679,7 +1707,6 @@ resolve_multisamples() {
|
|||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
next += 1;
|
||||
}
|
||||
#ifndef OPENGLES
|
||||
for (int i = 0; i < _fb_properties.get_aux_rgba(); ++i) {
|
||||
glReadBuffer(next);
|
||||
glDrawBuffer(next);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
// * Can render onto a texture without clearing it first.
|
||||
// * Supports multisample antialiased rendering.
|
||||
//
|
||||
// Some of these deserve a little explanation.
|
||||
// Some of these deserve a little explanation.
|
||||
// Auxiliary bitplanes are additional bitplanes above
|
||||
// and beyond the normal depth,stencil,color. One can
|
||||
// use them to render out multiple textures in a single
|
||||
|
|
@ -43,14 +43,14 @@
|
|||
// buffer will be equal to the texture's previous
|
||||
// contents. This alo means you can meaningfully
|
||||
// share a bitplane between two buffers by binding
|
||||
// the same texture to both buffers.
|
||||
// the same texture to both buffers.
|
||||
//
|
||||
// If either of the necessary OpenGL extensions is not
|
||||
// available, then the glGraphicsBuffer will not be
|
||||
// available (although it may still be possible to
|
||||
// create a wglGraphicsBuffer or glxGraphicsBuffer).
|
||||
//
|
||||
// This class now also uses the extensions
|
||||
// This class now also uses the extensions
|
||||
// EXT_framebuffer_multisample and EXT_framebuffer_blit
|
||||
// to allow for multisample antialiasing these offscreen
|
||||
// render targets. If these extensions are unavailable
|
||||
|
|
@ -87,13 +87,13 @@ public:
|
|||
protected:
|
||||
virtual void close_buffer();
|
||||
virtual bool open_buffer();
|
||||
|
||||
|
||||
void check_host_valid();
|
||||
|
||||
|
||||
void report_my_errors(int line, const char *file);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void bind_slot(int layer, bool rb_resize, Texture **attach,
|
||||
RenderTexturePlane plane, GLenum attachpoint);
|
||||
void bind_slot_multisample(bool rb_resize, Texture **attach,
|
||||
|
|
@ -127,7 +127,8 @@ private:
|
|||
|
||||
// List of textures for which we might have to generate mipmaps
|
||||
// after rendering one frame.
|
||||
pvector<CLP(TextureContext)*> _texture_contexts;
|
||||
typedef pvector<CLP(TextureContext)*> TextureContexts;
|
||||
TextureContexts _texture_contexts;
|
||||
|
||||
// The cube map face we are currently drawing to or have just
|
||||
// finished drawing to, or -1 if we are not drawing to a cube map.
|
||||
|
|
@ -136,10 +137,14 @@ private:
|
|||
bool _initial_clear;
|
||||
bool _needs_rebuild;
|
||||
UpdateSeq _last_textures_seq;
|
||||
|
||||
|
||||
CLP(GraphicsBuffer) *_shared_depth_buffer;
|
||||
list <CLP(GraphicsBuffer) *> _shared_depth_buffer_list;
|
||||
|
||||
|
||||
PStatCollector _bind_texture_pcollector;
|
||||
PStatCollector _generate_mipmap_pcollector;
|
||||
PStatCollector _resolve_multisample_pcollector;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
report_errors(int line, const char *source_file) {
|
||||
#ifndef NDEBUG
|
||||
PStatTimer timer(_check_error_pcollector);
|
||||
GLenum error_code = glGetError();
|
||||
if (error_code != GL_NO_ERROR) {
|
||||
int error_count = 0;
|
||||
|
|
@ -46,6 +47,7 @@ INLINE void CLP(GraphicsStateGuardian)::
|
|||
report_my_errors(int line, const char *source_file) {
|
||||
#ifndef NDEBUG
|
||||
if (_check_errors) {
|
||||
PStatTimer timer(_check_error_pcollector);
|
||||
GLenum error_code = glGetError();
|
||||
if (error_code != GL_NO_ERROR) {
|
||||
if (!report_errors_loop(line, source_file, error_code, _error_count)) {
|
||||
|
|
@ -69,6 +71,7 @@ report_my_errors(int line, const char *source_file) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
clear_errors(int line, const char *source_file) {
|
||||
PStatTimer timer(_check_error_pcollector);
|
||||
GLenum error_code = glGetError();
|
||||
if (error_code != GL_NO_ERROR) {
|
||||
int error_count = 0;
|
||||
|
|
@ -92,6 +95,7 @@ clear_errors(int line, const char *source_file) {
|
|||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
clear_my_errors(int line, const char *source_file) {
|
||||
if (_check_errors) {
|
||||
PStatTimer timer(_check_error_pcollector);
|
||||
GLenum error_code = glGetError();
|
||||
if (error_code != GL_NO_ERROR) {
|
||||
int error_count = 0;
|
||||
|
|
@ -743,7 +747,7 @@ get_clip_plane_id(int index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_supports_framebuffer_multisample
|
||||
// Access: Public
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// antialiasing for framebuffer objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
|
|
@ -754,7 +758,7 @@ get_supports_framebuffer_multisample() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_supports_framebuffer_multisample
|
||||
// Access: Public
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// antialiasing for framebuffer objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
|
|
@ -766,7 +770,7 @@ get_supports_framebuffer_multisample_coverage_nv() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_supports_framebuffer_blit
|
||||
// Access: Public
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// Description: Returns if this glGsg supports multisample
|
||||
// antialiasing for framebuffer objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
|
|
@ -778,7 +782,7 @@ get_supports_framebuffer_blit() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::UsageTextureKey::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(GraphicsStateGuardian)::UsageTextureKey::
|
||||
UsageTextureKey(int x_size, int y_size) :
|
||||
|
|
@ -792,7 +796,7 @@ UsageTextureKey(int x_size, int y_size) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::UsageTextureKey::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(GraphicsStateGuardian)::UsageTextureKey::
|
||||
operator < (const CLP(GraphicsStateGuardian)::UsageTextureKey &other) const {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
// Filename: glGraphicsStateGuardian_src.h
|
||||
// Created by: drose (02Feb99)
|
||||
// Updated by: fperazzi, PandaSE (05May10) (added
|
||||
// Updated by: fperazzi, PandaSE (05May10) (added
|
||||
// get_supports_cg_profile)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include "pmap.h"
|
||||
#include "geomVertexArrayData.h"
|
||||
#include "lightMutex.h"
|
||||
#include "pStatGPUTimer.h"
|
||||
|
||||
class PlaneNode;
|
||||
class Light;
|
||||
|
|
@ -58,6 +59,7 @@ typedef double GLdouble;
|
|||
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
|
||||
typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
|
||||
typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
|
||||
typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
|
||||
|
|
@ -65,6 +67,8 @@ typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
|
|||
typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
|
||||
typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
|
||||
typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
|
||||
typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
|
||||
typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
// There is some trivial disagreement between different gl.h headers about this one, so we use our own typename.
|
||||
|
|
@ -98,32 +102,32 @@ typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint
|
|||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
|
||||
typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
|
||||
typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
|
||||
typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
|
||||
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
|
||||
typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
|
||||
typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
|
||||
typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
|
||||
typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
|
||||
typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
|
||||
typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
|
||||
typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
|
||||
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
|
||||
typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
|
||||
typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
|
||||
typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
|
||||
typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
#ifdef OPENGLES_2
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
|
||||
#else
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
|
||||
#endif
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
|
||||
typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
|
||||
typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
|
||||
|
|
@ -189,7 +193,7 @@ typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count
|
|||
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
|
||||
typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEPROC) (GLuint texture);
|
||||
typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEPROC) (GLuint texture, GLuint sampler);
|
||||
typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTPROC) (GLuint64 handle);
|
||||
|
|
@ -228,7 +232,7 @@ public:
|
|||
virtual int get_driver_version_minor();
|
||||
virtual int get_driver_shader_version_major();
|
||||
virtual int get_driver_shader_version_minor();
|
||||
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
static void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
|
||||
#endif
|
||||
|
|
@ -302,13 +306,15 @@ public:
|
|||
virtual void begin_occlusion_query();
|
||||
virtual PT(OcclusionQueryContext) end_occlusion_query();
|
||||
|
||||
virtual PT(TimerQueryContext) issue_timer_query(int pstats_index);
|
||||
|
||||
virtual void dispatch_compute(int size_x, int size_y, int size_z);
|
||||
|
||||
virtual PT(GeomMunger) make_geom_munger(const RenderState *state,
|
||||
Thread *current_thread);
|
||||
|
||||
virtual void clear(DrawableRegion *region);
|
||||
|
||||
|
||||
virtual bool framebuffer_copy_to_texture
|
||||
(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
virtual bool framebuffer_copy_to_ram
|
||||
|
|
@ -332,9 +338,9 @@ public:
|
|||
void draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
|
||||
INLINE static bool report_errors(int line, const char *source_file);
|
||||
INLINE bool report_errors(int line, const char *source_file);
|
||||
INLINE void report_my_errors(int line, const char *source_file);
|
||||
INLINE static bool clear_errors(int line, const char *source_file);
|
||||
INLINE bool clear_errors(int line, const char *source_file);
|
||||
INLINE void clear_my_errors(int line, const char *source_file);
|
||||
|
||||
INLINE const string &get_gl_vendor() const;
|
||||
|
|
@ -475,8 +481,8 @@ protected:
|
|||
bool upload_texture(CLP(TextureContext) *gtc, bool force);
|
||||
bool upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
bool uses_mipmaps, int mipmap_bias,
|
||||
GLenum texture_target, GLenum page_target,
|
||||
GLint internal_format, GLint external_format,
|
||||
GLenum texture_target, GLenum page_target,
|
||||
GLint internal_format, GLint external_format,
|
||||
GLenum component_type,
|
||||
bool one_page_only, int z,
|
||||
Texture::CompressionMode image_compression);
|
||||
|
|
@ -590,9 +596,12 @@ protected:
|
|||
public:
|
||||
bool _supports_point_parameters;
|
||||
PFNGLPOINTPARAMETERFVPROC _glPointParameterfv;
|
||||
|
||||
bool _supports_point_sprite;
|
||||
|
||||
#ifndef OPENGLES
|
||||
PFNGLPRIMITIVERESTARTINDEXPROC _glPrimitiveRestartIndex;
|
||||
#endif
|
||||
|
||||
bool _supports_vertex_blend;
|
||||
PFNGLWEIGHTPOINTERARBPROC _glWeightPointer;
|
||||
PFNGLVERTEXBLENDARBPROC _glVertexBlend;
|
||||
|
|
@ -703,6 +712,14 @@ public:
|
|||
PFNGLGETQUERYIVPROC _glGetQueryiv;
|
||||
PFNGLGETQUERYOBJECTUIVPROC _glGetQueryObjectuiv;
|
||||
|
||||
#ifndef OPENGLES
|
||||
PFNGLQUERYCOUNTERPROC _glQueryCounter;
|
||||
PFNGLGETQUERYOBJECTI64VPROC _glGetQueryObjecti64v;
|
||||
PFNGLGETQUERYOBJECTUI64VPROC _glGetQueryObjectui64v;
|
||||
|
||||
PFNGLGETINTEGER64VPROC _glGetInteger64v;
|
||||
#endif
|
||||
|
||||
PFNGLACTIVESTENCILFACEEXTPROC _glActiveStencilFaceEXT;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -778,9 +795,9 @@ public:
|
|||
#endif
|
||||
|
||||
LightMutex _lock;
|
||||
typedef pvector<GLuint> DeletedDisplayLists;
|
||||
DeletedDisplayLists _deleted_display_lists;
|
||||
DeletedDisplayLists _deleted_queries;
|
||||
typedef pvector<GLuint> DeletedNames;
|
||||
DeletedNames _deleted_display_lists;
|
||||
DeletedNames _deleted_queries;
|
||||
|
||||
#ifndef OPENGLES
|
||||
// Stores textures for which memory bariers should be issued.
|
||||
|
|
@ -797,6 +814,9 @@ public:
|
|||
bool _force_flush;
|
||||
bool _supports_debug;
|
||||
|
||||
bool _use_object_labels;
|
||||
PFNGLOBJECTLABELPROC _glObjectLabel;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool _show_texture_usage;
|
||||
int _show_texture_usage_max_size;
|
||||
|
|
@ -818,7 +838,11 @@ public:
|
|||
static PStatCollector _primitive_batches_display_list_pcollector;
|
||||
static PStatCollector _vertices_display_list_pcollector;
|
||||
static PStatCollector _vertices_immediate_pcollector;
|
||||
static PStatCollector _compute_dispatch_pcollector;
|
||||
static PStatCollector _memory_barrier_pcollector;
|
||||
static PStatCollector _vertex_array_update_pcollector;
|
||||
static PStatCollector _texture_update_pcollector;
|
||||
static PStatCollector _fbo_bind_pcollector;
|
||||
static PStatCollector _check_error_pcollector;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
|
|
@ -846,6 +870,7 @@ private:
|
|||
friend class CLP(CgShaderContext);
|
||||
friend class CLP(GraphicsBuffer);
|
||||
friend class CLP(OcclusionQueryContext);
|
||||
friend class CLP(TimerQueryContext);
|
||||
};
|
||||
|
||||
#include "glGraphicsStateGuardian_src.I"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
// Filename: glLatencyQueryContext_src.I
|
||||
// Created by: rdb (24Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// Filename: glLatencyQueryContext_src.cxx
|
||||
// Created by: rdb (24Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef OPENGLES // Timer queries not supported by OpenGL ES.
|
||||
|
||||
TypeHandle CLP(LatencyQueryContext)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(LatencyQueryContext)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLP(LatencyQueryContext)::
|
||||
CLP(LatencyQueryContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
int pstats_index) :
|
||||
CLP(TimerQueryContext)(glgsg, pstats_index),
|
||||
_timestamp(0)
|
||||
{
|
||||
glgsg->_glGetInteger64v(GL_TIMESTAMP, &_timestamp);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LatencyQueryContext::get_timestamp
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the timestamp that is the result of this
|
||||
// timer query. There's no guarantee about which
|
||||
// clock this uses, the only guarantee is that
|
||||
// subtracting a start time from an end time should
|
||||
// yield a time in seconds.
|
||||
// If is_answer_ready() did not return true, this
|
||||
// function may block before it returns.
|
||||
//
|
||||
// It is only valid to call this from the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double CLP(LatencyQueryContext)::
|
||||
get_timestamp() const {
|
||||
GLint64 time_ns;
|
||||
_glgsg->_glGetQueryObjecti64v(_index, GL_QUERY_RESULT, &time_ns);
|
||||
|
||||
return (time_ns - _timestamp) * 0.000000001;
|
||||
}
|
||||
|
||||
#endif // OPENGLES
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Filename: glLatencyQueryContext_src.h
|
||||
// Created by: rdb (24Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
|
||||
#ifndef OPENGLES // Timer queries not supported by OpenGL ES.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLLatencyQueryContext
|
||||
// Description : This is a special variant of GLTimerQueryContext
|
||||
// that measures the command latency, ie. the time
|
||||
// it takes for the GPU to actually get to the commands
|
||||
// we are issuing right now.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(LatencyQueryContext) : public CLP(TimerQueryContext) {
|
||||
public:
|
||||
CLP(LatencyQueryContext)(CLP(GraphicsStateGuardian) *glgsg, int pstats_index);
|
||||
|
||||
ALLOC_DELETED_CHAIN(CLP(LatencyQueryContext));
|
||||
|
||||
virtual double get_timestamp() const;
|
||||
|
||||
GLint64 _timestamp;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CLP(TimerQueryContext)::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "LatencyQueryContext",
|
||||
CLP(TimerQueryContext)::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "glLatencyQueryContext_src.I"
|
||||
|
||||
#endif // OPENGLES
|
||||
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#ifndef OPENGLES_1
|
||||
|
||||
#include "pStatTimer.h"
|
||||
#include "pStatGPUTimer.h"
|
||||
|
||||
TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
|
||||
|
|
@ -35,19 +35,19 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
|||
// Access: Public
|
||||
// Description: The Panda CG shader syntax defines a useful set of shorthand notations for setting nodepath
|
||||
// properties as shaderinputs. For example, float4 mspos_XXX refers to nodepath XXX's position
|
||||
// in model space. This function is a rough attempt to reimplement some of the shorthand
|
||||
// in model space. This function is a rough attempt to reimplement some of the shorthand
|
||||
// notations for GLSL. The code is ~99% composed of excerpts dealing with matrix shaderinputs
|
||||
// from Shader::compile_parameter.
|
||||
//
|
||||
// Given a uniform variable name queried from the compiled shader passed in via arg_id,
|
||||
// from Shader::compile_parameter.
|
||||
//
|
||||
// Given a uniform variable name queried from the compiled shader passed in via arg_id,
|
||||
// 1) parse the name
|
||||
// 2a) if the name refers to a Panda shorthand notation
|
||||
// push the appropriate matrix into shader._mat_spec
|
||||
// returns True
|
||||
// 2b) If the name doesn't refer to a Panda shorthand notation
|
||||
// returns False
|
||||
//
|
||||
// The boolean return is used to notify down-river processing whether the shader var/parm was
|
||||
//
|
||||
// The boolean return is used to notify down-river processing whether the shader var/parm was
|
||||
// actually picked up and the appropriate ShaderMatSpec pushed onto _mat_spec.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
|
|
@ -700,7 +700,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now we've processed the uniforms, we'll process the attribs.
|
||||
_glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTES, ¶m_count);
|
||||
_glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, ¶m_maxlength);
|
||||
|
|
@ -836,7 +836,7 @@ release_resources() {
|
|||
}
|
||||
|
||||
_glsl_shaders.clear();
|
||||
|
||||
|
||||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
|
@ -890,7 +890,7 @@ unbind() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
issue_parameters(int altered) {
|
||||
PStatTimer timer(_glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
//PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
|
|
@ -1374,12 +1374,11 @@ glsl_report_shader_errors(GLuint shader) {
|
|||
_glgsg->_glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
if (length > 1) {
|
||||
info_log = (char *) malloc(length);
|
||||
info_log = (char *) alloca(length);
|
||||
_glgsg->_glGetShaderInfoLog(shader, length, &num_chars, info_log);
|
||||
if (strcmp(info_log, "Success.\n") != 0 && strcmp(info_log, "No errors.\n") != 0) {
|
||||
GLCAT.error(false) << info_log << "\n";
|
||||
}
|
||||
free(info_log);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1397,19 +1396,18 @@ glsl_report_program_errors(GLuint program) {
|
|||
_glgsg->_glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
if (length > 1) {
|
||||
info_log = (char *) malloc(length);
|
||||
info_log = (char *) alloca(length);
|
||||
_glgsg->_glGetProgramInfoLog(program, length, &num_chars, info_log);
|
||||
if (strcmp(info_log, "Success.\n") != 0 && strcmp(info_log, "No errors.\n") != 0) {
|
||||
GLCAT.error(false) << info_log << "\n";
|
||||
}
|
||||
free(info_log);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::glsl_compile_shader
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
glsl_compile_shader(Shader::ShaderType type) {
|
||||
|
|
@ -1451,16 +1449,21 @@ glsl_compile_shader(Shader::ShaderType type) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_glgsg->_use_object_labels) {
|
||||
string name = _shader->get_filename(type);
|
||||
_glgsg->_glObjectLabel(GL_SHADER, handle, name.size(), name.data());
|
||||
}
|
||||
|
||||
string text_str = _shader->get_text(type);
|
||||
const char* text = text_str.c_str();
|
||||
_glgsg->_glShaderSource(handle, 1, &text, NULL);
|
||||
_glgsg->_glCompileShader(handle);
|
||||
GLint status;
|
||||
_glgsg->_glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
||||
|
||||
|
||||
if (status != GL_TRUE) {
|
||||
GLCAT.error()
|
||||
<< "An error occurred while compiling shader "
|
||||
GLCAT.error()
|
||||
<< "An error occurred while compiling shader "
|
||||
<< _shader->get_filename(type) << "\n";
|
||||
glsl_report_shader_errors(handle);
|
||||
_glgsg->_glDeleteShader(handle);
|
||||
|
|
@ -1485,6 +1488,12 @@ glsl_compile_and_link() {
|
|||
if (!_glsl_program) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glgsg->_use_object_labels) {
|
||||
string name = _shader->get_filename();
|
||||
_glgsg->_glObjectLabel(GL_PROGRAM, _glsl_program, name.size(), name.data());
|
||||
}
|
||||
|
||||
bool valid = true;
|
||||
|
||||
if (!_shader->get_text(Shader::ST_vertex).empty()) {
|
||||
|
|
@ -1507,7 +1516,7 @@ glsl_compile_and_link() {
|
|||
nassertr(_glgsg->_glProgramParameteri != NULL, false);
|
||||
GLint max_vertices;
|
||||
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices);
|
||||
_glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices);
|
||||
_glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ TypeHandle CLP(TextureContext)::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CLP(TextureContext)::
|
||||
~CLP(TextureContext)() {
|
||||
#ifndef OPENGLES
|
||||
if (gl_enable_memory_barriers) {
|
||||
_glgsg->_textures_needing_fetch_barrier.erase(this);
|
||||
_glgsg->_textures_needing_image_access_barrier.erase(this);
|
||||
_glgsg->_textures_needing_update_barrier.erase(this);
|
||||
_glgsg->_textures_needing_framebuffer_barrier.erase(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
glDeleteTextures(1, &_index);
|
||||
_index = 0;
|
||||
|
|
@ -53,12 +55,15 @@ void CLP(TextureContext)::
|
|||
evict_lru() {
|
||||
dequeue_lru();
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_handle != 0) {
|
||||
if (_handle_resident) {
|
||||
_glgsg->_glMakeTextureHandleNonResident(_handle);
|
||||
}
|
||||
_handle_resident = false;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
reset_data();
|
||||
}
|
||||
|
||||
|
|
@ -74,9 +79,11 @@ evict_lru() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(TextureContext)::
|
||||
reset_data() {
|
||||
#ifndef OPENGLES
|
||||
if (_handle != 0 && _handle_resident) {
|
||||
_glgsg->_glMakeTextureHandleNonResident(_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Free the texture resources.
|
||||
glDeleteTextures(1, &_index);
|
||||
|
|
@ -108,6 +115,7 @@ reset_data() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(TextureContext)::
|
||||
make_handle_resident() {
|
||||
#ifndef OPENGLES
|
||||
if (_handle != 0) {
|
||||
if (!_handle_resident) {
|
||||
_glgsg->_glMakeTextureHandleResident(_handle);
|
||||
|
|
@ -115,6 +123,7 @@ make_handle_resident() {
|
|||
}
|
||||
set_resident(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
// Filename: glTimerQueryContext_src.I
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(TimerQueryContext)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(TimerQueryContext)::
|
||||
CLP(TimerQueryContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
int pstats_index) :
|
||||
TimerQueryContext(pstats_index),
|
||||
_glgsg(glgsg),
|
||||
_index(0)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// Filename: glTimerQueryContext_src.cxx
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pnotify.h"
|
||||
#include "dcast.h"
|
||||
#include "lightMutexHolder.h"
|
||||
#include "pStatTimer.h"
|
||||
|
||||
#ifndef OPENGLES // Timer queries not supported by OpenGL ES.
|
||||
|
||||
TypeHandle CLP(TimerQueryContext)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLTimerQueryContext::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLP(TimerQueryContext)::
|
||||
~CLP(TimerQueryContext)() {
|
||||
if (_index != 0) {
|
||||
// Tell the GSG to recycle this index when it gets around to it.
|
||||
LightMutexHolder holder(_glgsg->_lock);
|
||||
_glgsg->_deleted_queries.push_back(_index);
|
||||
_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLTimerQueryContext::is_answer_ready
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the query's answer is ready, false
|
||||
// otherwise. If this returns false, the application
|
||||
// must continue to poll until it returns true.
|
||||
//
|
||||
// It is only valid to call this from the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(TimerQueryContext)::
|
||||
is_answer_ready() const {
|
||||
GLuint result;
|
||||
_glgsg->_glGetQueryObjectuiv(_index, GL_QUERY_RESULT_AVAILABLE, &result);
|
||||
|
||||
return (result != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLTimerQueryContext::waiting_for_answer
|
||||
// Access: Public, Virtual
|
||||
// Description: Requests the graphics engine to expedite the pending
|
||||
// answer--the application is now waiting until the
|
||||
// answer is ready.
|
||||
//
|
||||
// It is only valid to call this from the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(TimerQueryContext)::
|
||||
waiting_for_answer() {
|
||||
PStatTimer timer(GraphicsStateGuardian::_wait_timer_pcollector);
|
||||
glFlush();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TimerQueryContext::get_timestamp
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the timestamp that is the result of this
|
||||
// timer query. There's no guarantee about which
|
||||
// clock this uses, the only guarantee is that
|
||||
// subtracting a start time from an end time should
|
||||
// yield a time in seconds.
|
||||
// If is_answer_ready() did not return true, this
|
||||
// function may block before it returns.
|
||||
//
|
||||
// It is only valid to call this from the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double CLP(TimerQueryContext)::
|
||||
get_timestamp() const {
|
||||
GLuint64 time_ns;
|
||||
|
||||
/*GLuint available;
|
||||
_glgsg->_glGetQueryObjectuiv(_index[1], GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
if (available) {
|
||||
// The answer is ready now.
|
||||
do_get_timestamps(begin_ns, end_ns);
|
||||
} else {
|
||||
// The answer is not ready; this call will block.
|
||||
PStatTimer timer(GraphicsStateGuardian::_wait_timer_pcollector);
|
||||
do_get_timestamps(begin_ns, end_ns);
|
||||
}*/
|
||||
|
||||
_glgsg->_glGetQueryObjectui64v(_index, GL_QUERY_RESULT, &time_ns);
|
||||
|
||||
return time_ns * 0.000000001;
|
||||
}
|
||||
|
||||
#endif // OPENGLES
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Filename: glTimerQueryContext_src.h
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "timerQueryContext.h"
|
||||
#include "deletedChain.h"
|
||||
#include "clockObject.h"
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
|
||||
#ifndef OPENGLES // Timer queries not supported by OpenGL ES.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLTimerQueryContext
|
||||
// Description : This class manages a timer query that can be used
|
||||
// by a PStatGPUTimer to measure the time a task takes
|
||||
// to execute on the GPU.
|
||||
// This records the current timestamp; a pair of these
|
||||
// is usually used to get the elapsed time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(TimerQueryContext) : public TimerQueryContext {
|
||||
public:
|
||||
INLINE CLP(TimerQueryContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
int pstats_index);
|
||||
virtual ~CLP(TimerQueryContext)();
|
||||
|
||||
ALLOC_DELETED_CHAIN(CLP(TimerQueryContext));
|
||||
|
||||
virtual bool is_answer_ready() const;
|
||||
virtual void waiting_for_answer();
|
||||
virtual double get_timestamp() const;
|
||||
|
||||
GLuint _index;
|
||||
CLP(GraphicsStateGuardian) *_glgsg;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TimerQueryContext::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "TimerQueryContext",
|
||||
TimerQueryContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "glTimerQueryContext_src.I"
|
||||
|
||||
#endif // OPENGLES
|
||||
|
||||
|
|
@ -151,6 +151,13 @@ ConfigVariableEnum<NotifySeverity> gl_debug_abort_level
|
|||
"that triggered the error message. "
|
||||
"This feature is not available when NDEBUG has been defined."));
|
||||
|
||||
ConfigVariableBool gl_debug_object_labels
|
||||
("gl-debug-object-labels", true,
|
||||
PRC_DESC("When gl-debug is set to true, this will tell OpenGL the "
|
||||
"name of textures, shaders, and other objects, so that OpenGL "
|
||||
"can display those in error messages. There's usually no "
|
||||
"reason to disable this."));
|
||||
|
||||
ConfigVariableBool gl_debug_buffers
|
||||
("gl-debug-buffers", false,
|
||||
PRC_DESC("Set this true, in addition to enabling debug notify for "
|
||||
|
|
@ -162,7 +169,8 @@ ConfigVariableBool gl_finish
|
|||
PRC_DESC("Set this true to force a call to glFinish() after every major "
|
||||
"graphics operation. This is likely to slow down rendering "
|
||||
"performance substantially, but it will make PStats graphs "
|
||||
"more accurately reflect where the graphics bottlenecks are. "
|
||||
"more accurately reflect where the graphics bottlenecks are, "
|
||||
"although it is better to use timer queries when available. "
|
||||
"This variable is enabled only if PStats is compiled in."));
|
||||
|
||||
ConfigVariableBool gl_force_depth_stencil
|
||||
|
|
@ -252,6 +260,8 @@ void CLP(init_classes)() {
|
|||
|
||||
#ifndef OPENGLES
|
||||
CLP(OcclusionQueryContext)::init_type();
|
||||
CLP(TimerQueryContext)::init_type();
|
||||
CLP(LatencyQueryContext)::init_type();
|
||||
#endif
|
||||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ extern ConfigVariableEnum<GeomEnums::UsageHint> gl_min_buffer_usage_hint;
|
|||
extern ConfigVariableBool gl_debug;
|
||||
extern ConfigVariableBool gl_debug_synchronous;
|
||||
extern ConfigVariableEnum<NotifySeverity> gl_debug_abort_level;
|
||||
extern ConfigVariableBool gl_debug_object_labels;
|
||||
extern ConfigVariableBool gl_debug_buffers;
|
||||
extern ConfigVariableBool gl_finish;
|
||||
extern ConfigVariableBool gl_force_depth_stencil;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include "glVertexBufferContext_src.cxx"
|
||||
#include "glIndexBufferContext_src.cxx"
|
||||
#include "glOcclusionQueryContext_src.cxx"
|
||||
#include "glTimerQueryContext_src.cxx"
|
||||
#include "glLatencyQueryContext_src.cxx"
|
||||
#include "glGeomContext_src.cxx"
|
||||
#include "glGeomMunger_src.cxx"
|
||||
#include "glShaderContext_src.cxx"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "glVertexBufferContext_src.h"
|
||||
#include "glIndexBufferContext_src.h"
|
||||
#include "glOcclusionQueryContext_src.h"
|
||||
#include "glTimerQueryContext_src.h"
|
||||
#include "glLatencyQueryContext_src.h"
|
||||
#include "glGeomContext_src.h"
|
||||
#include "glGeomMunger_src.h"
|
||||
#include "glShaderContext_src.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ extern "C" {
|
|||
|
||||
/*
|
||||
** Copyright (c) 2007-2012 The Khronos Group Inc.
|
||||
**
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
|
|
@ -14,10 +14,10 @@ extern "C" {
|
|||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
|
|
@ -1163,6 +1163,11 @@ extern "C" {
|
|||
/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */
|
||||
#endif
|
||||
|
||||
#ifndef GL_VERSION_4_3
|
||||
#define GL_VERSION_4_3 1
|
||||
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_multitexture
|
||||
#define GL_TEXTURE0_ARB 0x84C0
|
||||
#define GL_TEXTURE1_ARB 0x84C1
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
geomVertexWriter.h geomVertexWriter.I \
|
||||
indexBufferContext.I indexBufferContext.h \
|
||||
internalName.I internalName.h \
|
||||
internalName_ext.h internalName_ext.cxx \
|
||||
lens.h lens.I \
|
||||
material.I material.h materialPool.I materialPool.h \
|
||||
matrixLens.I matrixLens.h \
|
||||
|
|
@ -66,6 +67,7 @@
|
|||
textureReloadRequest.I textureReloadRequest.h \
|
||||
textureStage.I textureStage.h \
|
||||
textureStagePool.I textureStagePool.h \
|
||||
timerQueryContext.I timerQueryContext.h \
|
||||
transformBlend.I transformBlend.h \
|
||||
transformBlendTable.I transformBlendTable.h \
|
||||
transformTable.I transformTable.h \
|
||||
|
|
@ -136,6 +138,7 @@
|
|||
textureReloadRequest.cxx \
|
||||
textureStage.cxx \
|
||||
textureStagePool.cxx \
|
||||
timerQueryContext.cxx \
|
||||
transformBlend.cxx \
|
||||
transformBlendTable.cxx \
|
||||
transformTable.cxx \
|
||||
|
|
@ -208,6 +211,7 @@
|
|||
textureReloadRequest.I textureReloadRequest.h \
|
||||
textureStage.I textureStage.h \
|
||||
textureStagePool.I textureStagePool.h \
|
||||
timerQueryContext.I timerQueryContext.h \
|
||||
transformBlend.I transformBlend.h \
|
||||
transformBlendTable.I transformBlendTable.h \
|
||||
transformTable.I transformTable.h \
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "textureReloadRequest.h"
|
||||
#include "textureStage.h"
|
||||
#include "textureContext.h"
|
||||
#include "timerQueryContext.h"
|
||||
#include "shader.h"
|
||||
#include "shaderContext.h"
|
||||
#include "transformBlend.h"
|
||||
|
|
@ -92,7 +93,7 @@ ConfigVariableInt texture_scale_limit
|
|||
"to both X and Y."));
|
||||
|
||||
ConfigVariableList exclude_texture_scale
|
||||
("exclude-texture-scale",
|
||||
("exclude-texture-scale",
|
||||
PRC_DESC("This is a list of glob patterns for texture filenames "
|
||||
"(excluding the directory part of the filename, but including "
|
||||
"the extension); for instance, 'digits_*.png'. Any texture "
|
||||
|
|
@ -287,7 +288,7 @@ ConfigVariableInt vertex_column_alignment
|
|||
"this alignment for the vertex animation columns only."));
|
||||
|
||||
ConfigVariableBool vertex_animation_align_16
|
||||
("vertex-animation-align-16",
|
||||
("vertex-animation-align-16",
|
||||
#ifdef LINMATH_ALIGN
|
||||
true,
|
||||
#else
|
||||
|
|
@ -343,7 +344,7 @@ ConfigVariableInt simple_image_size
|
|||
|
||||
ConfigVariableDouble simple_image_threshold
|
||||
("simple-image-threshold", 0.1,
|
||||
PRC_DESC("This is a value that indicates how closely a texture's "
|
||||
PRC_DESC("This is a value that indicates how closely a texture's "
|
||||
"generated simple "
|
||||
"image should approximate the original image. The smaller the "
|
||||
"number, the closer the match; small numbers will result in "
|
||||
|
|
@ -568,6 +569,7 @@ ConfigureFn(config_gobj) {
|
|||
TexturePoolFilter::init_type();
|
||||
TextureReloadRequest::init_type();
|
||||
TextureStage::init_type();
|
||||
TimerQueryContext::init_type();
|
||||
TransformBlend::init_type();
|
||||
TransformBlendTable::init_type();
|
||||
TransformTable::init_type();
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ PUBLISHED:
|
|||
// The union of all of the above composite types.
|
||||
GR_composite_bits = 0x01c00,
|
||||
|
||||
// If strip-cut indices are used to restart a composite primitive.
|
||||
GR_strip_cut_index = 0x20000,
|
||||
|
||||
// If the shade model requires a particular vertex for flat shading.
|
||||
GR_flat_first_vertex = 0x02000,
|
||||
GR_flat_last_vertex = 0x04000,
|
||||
|
|
@ -216,4 +219,3 @@ EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, GeomEnums::NumericType nume
|
|||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, GeomEnums::Contents contents);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,11 @@ get_primitive_type() const {
|
|||
int GeomLinestrips::
|
||||
get_geom_rendering() const {
|
||||
if (is_indexed()) {
|
||||
return GR_line_strip | GR_indexed_other;
|
||||
if (get_num_primitives() > 1) {
|
||||
return GR_line_strip | GR_indexed_other | GR_strip_cut_index;
|
||||
} else {
|
||||
return GR_line_strip | GR_indexed_other;
|
||||
}
|
||||
} else {
|
||||
return GR_line_strip;
|
||||
}
|
||||
|
|
@ -106,6 +110,20 @@ get_min_num_vertices_per_primitive() const {
|
|||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomLinestrips::get_num_unused_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the number of vertices that are added between
|
||||
// primitives that aren't, strictly speaking, part of
|
||||
// the primitives themselves. This is used, for
|
||||
// instance, to define degenerate triangles to connect
|
||||
// otherwise disconnected triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomLinestrips::
|
||||
get_num_unused_vertices_per_primitive() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomLinestrips::draw
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -138,9 +156,13 @@ decompose_impl() const {
|
|||
lines->set_shade_model(get_shade_model());
|
||||
CPTA_int ends = get_ends();
|
||||
|
||||
int vi = 0;
|
||||
int num_unused = get_num_unused_vertices_per_primitive();
|
||||
|
||||
int vi = -num_unused;
|
||||
int li = 0;
|
||||
while (li < (int)ends.size()) {
|
||||
// Skip unused vertices between tristrips.
|
||||
vi += num_unused;
|
||||
int end = ends[li];
|
||||
nassertr(vi + 1 <= end, lines.p());
|
||||
int v0 = get_vertex(vi);
|
||||
|
|
@ -210,6 +232,33 @@ rotate_impl() const {
|
|||
return new_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomLinestrips::requires_unused_vertices
|
||||
// Access: Protected, Virtual
|
||||
// Description: Should be redefined to return true in any primitive
|
||||
// that implements append_unused_vertices().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomLinestrips::
|
||||
requires_unused_vertices() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomLinestrips::append_unused_vertices
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called when a new primitive is begun (other than the
|
||||
// first primitive), this should add some degenerate
|
||||
// vertices between primitives, if the primitive type
|
||||
// requires that. The second parameter is the first
|
||||
// vertex that begins the new primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomLinestrips::
|
||||
append_unused_vertices(GeomVertexArrayData *vertices, int vertex) {
|
||||
GeomVertexWriter to(vertices, 0);
|
||||
to.set_row_unsafe(vertices->get_num_rows());
|
||||
to.add_data1i(get_strip_cut_index());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomLinestrips::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public:
|
|||
virtual PrimitiveType get_primitive_type() const;
|
||||
virtual int get_geom_rendering() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
virtual int get_num_unused_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual bool draw(GraphicsStateGuardianBase *gsg,
|
||||
|
|
@ -43,6 +44,9 @@ public:
|
|||
protected:
|
||||
virtual CPT(GeomPrimitive) decompose_impl() const;
|
||||
virtual CPT(GeomVertexArrayData) rotate_impl() const;
|
||||
virtual bool requires_unused_vertices() const;
|
||||
virtual void append_unused_vertices(GeomVertexArrayData *vertices,
|
||||
int vertex);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ get_first_vertex() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices used by all the
|
||||
// Description: Returns the number of indices used by all the
|
||||
// primitives in this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
|
|
@ -310,6 +310,20 @@ get_index_stride() const {
|
|||
return reader.get_index_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_strip_cut_index
|
||||
// Access: Published
|
||||
// Description: If relevant, returns the index value that may be
|
||||
// used in some cases to signify the end of a
|
||||
// primitive. This is typically the highest value
|
||||
// that the numeric type can store.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_strip_cut_index() const {
|
||||
CDReader cdata(_cycler);
|
||||
return get_strip_cut_index(cdata->_index_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_ends
|
||||
// Access: Published
|
||||
|
|
@ -415,6 +429,17 @@ add_vertices(int v1, int v2, int v3, int v4) {
|
|||
add_vertex(v4);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_index_format
|
||||
// Access: Public
|
||||
// Description: Returns a registered format appropriate for using to
|
||||
// store the index table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayFormat *GeomPrimitive::
|
||||
get_index_format() const {
|
||||
return get_index_format(get_index_type());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::make_index_data
|
||||
// Access: Public
|
||||
|
|
@ -425,6 +450,22 @@ make_index_data() const {
|
|||
return new GeomVertexArrayData(get_index_format(), get_usage_hint());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::make_index_format
|
||||
// Access: Private, Static
|
||||
// Description: Returns a registered format appropriate for using to
|
||||
// store the index table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
|
||||
make_index_format(NumericType index_type) {
|
||||
PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
|
||||
// It's important that the index format *not* respect the global
|
||||
// setting of vertex-column-alignment. It needs to be tightly
|
||||
// packed, so we specify an explict column_alignment of 1.
|
||||
format->add_column(InternalName::get_index(), 1, index_type, C_index, 0, 1);
|
||||
return GeomVertexArrayFormat::register_format(format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::CData::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -679,6 +720,16 @@ get_read_pointer(bool force) const {
|
|||
return _vertices_reader->get_read_pointer(force);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_strip_cut_index
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_strip_cut_index() const {
|
||||
return GeomPrimitive::get_strip_cut_index(_cdata->_index_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_ends
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -62,18 +62,18 @@ make_cow_copy() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomPrimitive::
|
||||
GeomPrimitive(GeomPrimitive::UsageHint usage_hint) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_usage_hint = usage_hint;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomPrimitive::
|
||||
GeomPrimitive(const GeomPrimitive ©) :
|
||||
|
|
@ -81,7 +81,7 @@ GeomPrimitive(const GeomPrimitive ©) :
|
|||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::Copy Assignment Operator
|
||||
// Access: Published
|
||||
|
|
@ -99,7 +99,7 @@ operator = (const GeomPrimitive ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomPrimitive::
|
||||
~GeomPrimitive() {
|
||||
|
|
@ -198,7 +198,7 @@ add_vertex(int vertex) {
|
|||
|
||||
int num_primitives = get_num_primitives();
|
||||
if (num_primitives > 0 &&
|
||||
requires_unused_vertices() &&
|
||||
requires_unused_vertices() &&
|
||||
get_num_vertices() == get_primitive_end(num_primitives - 1)) {
|
||||
// If we are beginning a new primitive, give the derived class a
|
||||
// chance to insert some degenerate vertices.
|
||||
|
|
@ -225,7 +225,7 @@ add_vertex(int vertex) {
|
|||
cdata->_got_minmax = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Otherwise, we need to suddenly become an indexed primitive.
|
||||
do_make_indexed(cdata);
|
||||
}
|
||||
|
|
@ -289,7 +289,7 @@ add_consecutive_vertices(int start, int num_vertices) {
|
|||
cdata->_got_minmax = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Otherwise, we need to suddenly become an indexed primitive.
|
||||
do_make_indexed(cdata);
|
||||
}
|
||||
|
|
@ -469,12 +469,18 @@ offset_vertices(int offset) {
|
|||
recompute_minmax(cdata);
|
||||
nassertv(cdata->_got_minmax);
|
||||
}
|
||||
|
||||
|
||||
consider_elevate_index_type(cdata, cdata->_max_vertex + offset);
|
||||
|
||||
int strip_cut_index = get_strip_cut_index(cdata->_index_type);
|
||||
|
||||
GeomVertexRewriter index(do_modify_vertices(cdata), 0);
|
||||
while (!index.is_at_end()) {
|
||||
index.set_data1i(index.get_data1i() + offset);
|
||||
int vertex = index.get_data1i();
|
||||
|
||||
if (vertex != strip_cut_index) {
|
||||
index.set_data1i(vertex + offset);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -484,7 +490,7 @@ offset_vertices(int offset) {
|
|||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_got_minmax = false;
|
||||
|
||||
consider_elevate_index_type(cdata,
|
||||
consider_elevate_index_type(cdata,
|
||||
cdata->_first_vertex + cdata->_num_vertices - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -517,14 +523,19 @@ offset_vertices(int offset, int begin_row, int end_row) {
|
|||
|
||||
if (is_indexed()) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
|
||||
int strip_cut_index = get_strip_cut_index(cdata->_index_type);
|
||||
|
||||
// Calculate the maximum vertex over our range.
|
||||
int max_vertex = 0;
|
||||
{
|
||||
GeomVertexReader index_r(cdata->_vertices.get_read_pointer(), 0);
|
||||
index_r.set_row_unsafe(begin_row);
|
||||
for (int j = begin_row; j < end_row; ++j) {
|
||||
max_vertex = max(max_vertex, index_r.get_data1i());
|
||||
int vertex = index_r.get_data1i();
|
||||
if (vertex != strip_cut_index) {
|
||||
max_vertex = max(max_vertex, vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +544,10 @@ offset_vertices(int offset, int begin_row, int end_row) {
|
|||
GeomVertexRewriter index(do_modify_vertices(cdata), 0);
|
||||
index.set_row_unsafe(begin_row);
|
||||
for (int j = begin_row; j < end_row; ++j) {
|
||||
index.set_data1i(index.get_data1i() + offset);
|
||||
int vertex = index.get_data1i();
|
||||
if (vertex != strip_cut_index) {
|
||||
index.set_data1i(vertex + offset);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -545,7 +559,7 @@ offset_vertices(int offset, int begin_row, int end_row) {
|
|||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_got_minmax = false;
|
||||
|
||||
consider_elevate_index_type(cdata,
|
||||
consider_elevate_index_type(cdata,
|
||||
cdata->_first_vertex + cdata->_num_vertices - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -555,17 +569,20 @@ offset_vertices(int offset, int begin_row, int end_row) {
|
|||
// Access: Published
|
||||
// Description: Converts the primitive from indexed to nonindexed by
|
||||
// duplicating vertices as necessary into the indicated
|
||||
// dest GeomVertexData.
|
||||
// dest GeomVertexData. Note: does not support
|
||||
// primitives with strip cut indices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
make_nonindexed(GeomVertexData *dest, const GeomVertexData *source) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
int num_vertices = get_num_vertices();
|
||||
int dest_start = dest->get_num_rows();
|
||||
int strip_cut_index = get_strip_cut_index();
|
||||
|
||||
dest->set_num_rows(dest_start + num_vertices);
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
int v = get_vertex(i);
|
||||
nassertd(v != strip_cut_index) continue;
|
||||
dest->copy_row_from(dest_start + i, source, v, current_thread);
|
||||
}
|
||||
|
||||
|
|
@ -597,14 +614,18 @@ pack_vertices(GeomVertexData *dest, const GeomVertexData *source) {
|
|||
|
||||
int num_vertices = get_num_vertices();
|
||||
int dest_start = dest->get_num_rows();
|
||||
int strip_cut_index = get_strip_cut_index();
|
||||
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
int v = get_vertex(i);
|
||||
if (v == strip_cut_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to add the relation { v : size() }. If that succeeds,
|
||||
// great; if it doesn't, look up whatever we previously added
|
||||
// for v.
|
||||
pair<CopiedIndices::iterator, bool> result =
|
||||
pair<CopiedIndices::iterator, bool> result =
|
||||
copied_indices.insert(CopiedIndices::value_type(v, (int)copied_indices.size()));
|
||||
int v2 = (*result.first).second + dest_start;
|
||||
index.add_data1i(v2);
|
||||
|
|
@ -614,7 +635,7 @@ pack_vertices(GeomVertexData *dest, const GeomVertexData *source) {
|
|||
dest->copy_row_from(v2, source, v, current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set_vertices(new_vertices);
|
||||
}
|
||||
}
|
||||
|
|
@ -644,7 +665,7 @@ make_indexed() {
|
|||
// Function: GeomPrimitive::get_primitive_start
|
||||
// Access: Published
|
||||
// Description: Returns the element within the _vertices list at which
|
||||
// the nth primitive starts.
|
||||
// the nth primitive starts.
|
||||
//
|
||||
// If i is one more than the highest valid primitive
|
||||
// vertex, the return value will be one more than the
|
||||
|
|
@ -724,7 +745,7 @@ get_primitive_num_vertices(int n) const {
|
|||
} else {
|
||||
int num_unused_vertices_per_primitive = get_num_unused_vertices_per_primitive();
|
||||
return cdata->_ends[n] - cdata->_ends[n - 1] - num_unused_vertices_per_primitive;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
|
|
@ -733,6 +754,28 @@ get_primitive_num_vertices(int n) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_num_used_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices used by all of the
|
||||
// primitives. This is the same as summing
|
||||
// get_primitive_num_vertices(n) for n in
|
||||
// get_num_primitives(). It is like get_num_vertices
|
||||
// except that it excludes all of the degenerate
|
||||
// vertices and strip-cut indices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_num_used_vertices() const {
|
||||
int num_primitives = get_num_primitives();
|
||||
|
||||
if (num_primitives > 0) {
|
||||
return get_num_vertices() - ((num_primitives - 1) *
|
||||
get_num_unused_vertices_per_primitive());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_primitive_min_vertex
|
||||
// Access: Published
|
||||
|
|
@ -960,10 +1003,14 @@ make_points() const {
|
|||
int num_vertices = get_num_vertices();
|
||||
if (is_indexed()) {
|
||||
CPT(GeomVertexArrayData) vertices = get_vertices();
|
||||
int strip_cut_index = get_strip_cut_index();
|
||||
GeomVertexReader index(vertices, 0);
|
||||
for (int vi = 0; vi < num_vertices; ++vi) {
|
||||
nassertr(!index.is_at_end(), NULL);
|
||||
bits.set_bit(index.get_data1i());
|
||||
int vertex = index.get_data1i();
|
||||
if (vertex != strip_cut_index) {
|
||||
bits.set_bit(vertex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int first_vertex = get_first_vertex();
|
||||
|
|
@ -997,14 +1044,13 @@ make_points() const {
|
|||
// Access: Published
|
||||
// Description: Decomposes a complex primitive type into a simpler
|
||||
// primitive type, for instance triangle strips to
|
||||
// triangles, puts these in a new GeomPatches objectand returns a pointer to the new primitive
|
||||
// triangles, puts these in a new GeomPatches object
|
||||
// and returns a pointer to the new primitive
|
||||
// definition. If the decomposition cannot be
|
||||
// performed, this might return the original object.
|
||||
//
|
||||
// This method is useful for application code that wants
|
||||
// to iterate through the set of triangles on the
|
||||
// primitive without having to write handlers for each
|
||||
// possible kind of primitive type.
|
||||
// to use tesselation shaders on arbitrary geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomPrimitive) GeomPrimitive::
|
||||
make_patches() const {
|
||||
|
|
@ -1080,7 +1126,7 @@ request_resident() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
output(ostream &out) const {
|
||||
|
|
@ -1091,7 +1137,7 @@ output(ostream &out) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::write
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
write(ostream &out, int indent_level) const {
|
||||
|
|
@ -1188,6 +1234,11 @@ set_vertices(const GeomVertexArrayData *vertices, int num_vertices) {
|
|||
cdata->_vertices = (GeomVertexArrayData *)vertices;
|
||||
cdata->_num_vertices = num_vertices;
|
||||
|
||||
// Validate the format and make sure to copy its numeric type.
|
||||
const GeomVertexArrayFormat *format = vertices->get_array_format();
|
||||
nassertv(format->get_num_columns() == 1);
|
||||
cdata->_index_type = format->get_column(0)->get_numeric_type();
|
||||
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_got_minmax = false;
|
||||
}
|
||||
|
|
@ -1449,7 +1500,7 @@ is_prepared(PreparedGraphicsObjects *prepared_objects) const {
|
|||
// rendered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *GeomPrimitive::
|
||||
prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg) {
|
||||
nassertr(is_indexed(), NULL);
|
||||
|
||||
|
|
@ -1519,18 +1570,41 @@ release_all() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_index_format
|
||||
// Access: Public
|
||||
// Description: Returns a registered format appropriate for using to
|
||||
// store the index table.
|
||||
// Access: Public, Static
|
||||
// Description: Returns a registered GeomVertexArrayFormat of the
|
||||
// indicated unsigned integer numeric type for storing
|
||||
// index values.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(GeomVertexArrayFormat) GeomPrimitive::
|
||||
get_index_format() const {
|
||||
PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
|
||||
// It's important that the index format *not* respect the global
|
||||
// setting of vertex-column-alignment. It needs to be tightly
|
||||
// packed, so we specify an explict column_alignment of 1.
|
||||
format->add_column(InternalName::get_index(), 1, get_index_type(), C_index, 0, 1);
|
||||
return GeomVertexArrayFormat::register_format(format);
|
||||
const GeomVertexArrayFormat *GeomPrimitive::
|
||||
get_index_format(NumericType index_type) {
|
||||
switch (index_type) {
|
||||
case NT_uint8:
|
||||
{
|
||||
static CPT(GeomVertexArrayFormat) cformat = NULL;
|
||||
if (cformat == NULL) {
|
||||
cformat = make_index_format(NT_uint8);
|
||||
}
|
||||
return cformat;
|
||||
}
|
||||
case NT_uint16:
|
||||
{
|
||||
static CPT(GeomVertexArrayFormat) cformat = NULL;
|
||||
if (cformat == NULL) {
|
||||
cformat = make_index_format(NT_uint16);
|
||||
}
|
||||
return cformat;
|
||||
}
|
||||
case NT_uint32:
|
||||
{
|
||||
static CPT(GeomVertexArrayFormat) cformat = NULL;
|
||||
if (cformat == NULL) {
|
||||
cformat = make_index_format(NT_uint32);
|
||||
}
|
||||
return cformat;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1559,11 +1633,44 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_highest_index_value
|
||||
// Access: Private, Static
|
||||
// Description: Returns the largest index value that can be stored in
|
||||
// an index of the indicated type.
|
||||
// Description: Returns the largest index value that can be stored
|
||||
// in an index of the indicated type, minus one (to
|
||||
// leave room for a potential strip cut index)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_highest_index_value(NumericType index_type) {
|
||||
// Reserve the highest possible index because implementations use
|
||||
// this as a strip-cut index.
|
||||
switch (index_type) {
|
||||
case NT_uint8:
|
||||
return 0xff - 1;
|
||||
|
||||
case NT_uint16:
|
||||
return 0xffff - 1;
|
||||
|
||||
case NT_uint32:
|
||||
// We don't actually allow use of the sign bit, since all of our
|
||||
// functions receive an "int" instead of an "unsigned int".
|
||||
return 0x7fffffff - 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_strip_cut_index
|
||||
// Access: Private, Static
|
||||
// Description: Returns the index of the indicated type that is
|
||||
// reserved for use as a strip cut index, if enabled
|
||||
// for the primitive. When the renderer encounters
|
||||
// this index, it will restart the primitive. This
|
||||
// is guaranteed not to point to an actual vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_strip_cut_index(NumericType index_type) {
|
||||
// Reserve the highest possible index because implementations use
|
||||
// this as a strip-cut index.
|
||||
switch (index_type) {
|
||||
case NT_uint8:
|
||||
return 0xff;
|
||||
|
|
@ -1572,12 +1679,8 @@ get_highest_index_value(NumericType index_type) {
|
|||
return 0xffff;
|
||||
|
||||
case NT_uint32:
|
||||
// We don't actually allow use of the sign bit, since all of our
|
||||
// functions receive an "int" instead of an "unsigned int".
|
||||
return 0x7fffffff;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1594,7 +1697,7 @@ get_highest_index_value(NumericType index_type) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
const InternalName *column_name,
|
||||
|
|
@ -1614,7 +1717,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
|||
for (int i = 0; i < cdata->_num_vertices; i++) {
|
||||
reader.set_row_unsafe(cdata->_first_vertex + i);
|
||||
LPoint3 vertex = mat.xform_point(reader.get_data3());
|
||||
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
min(min_point[1], vertex[1]),
|
||||
|
|
@ -1632,7 +1735,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
|||
for (int i = 0; i < cdata->_num_vertices; i++) {
|
||||
reader.set_row_unsafe(cdata->_first_vertex + i);
|
||||
const LVecBase3 &vertex = reader.get_data3();
|
||||
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
min(min_point[1], vertex[1]),
|
||||
|
|
@ -1651,13 +1754,17 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
|||
} else {
|
||||
// Indexed case.
|
||||
GeomVertexReader index(cdata->_vertices.get_read_pointer(), 0, current_thread);
|
||||
int strip_cut_index = get_strip_cut_index(cdata->_index_type);
|
||||
|
||||
if (got_mat) {
|
||||
while (!index.is_at_end()) {
|
||||
int ii = index.get_data1i();
|
||||
if (ii == strip_cut_index) {
|
||||
continue;
|
||||
}
|
||||
reader.set_row_unsafe(ii);
|
||||
LPoint3 vertex = mat.xform_point(reader.get_data3());
|
||||
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
min(min_point[1], vertex[1]),
|
||||
|
|
@ -1674,9 +1781,12 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
|||
} else {
|
||||
while (!index.is_at_end()) {
|
||||
int ii = index.get_data1i();
|
||||
if (ii == strip_cut_index) {
|
||||
continue;
|
||||
}
|
||||
reader.set_row_unsafe(ii);
|
||||
const LVecBase3 &vertex = reader.get_data3();
|
||||
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
min(min_point[1], vertex[1]),
|
||||
|
|
@ -1798,63 +1908,77 @@ recompute_minmax(GeomPrimitive::CData *cdata) {
|
|||
cdata->_max_vertex = 0;
|
||||
cdata->_mins.clear();
|
||||
cdata->_maxs.clear();
|
||||
|
||||
|
||||
} else if (get_num_vertices_per_primitive() == 0) {
|
||||
// This is a complex primitive type like a triangle strip; compute
|
||||
// the minmax of each primitive (as well as the overall minmax).
|
||||
GeomVertexReader index(cdata->_vertices.get_read_pointer(), 0);
|
||||
|
||||
|
||||
cdata->_mins = make_index_data();
|
||||
cdata->_maxs = make_index_data();
|
||||
|
||||
|
||||
GeomVertexWriter mins(cdata->_mins.get_write_pointer(), 0);
|
||||
mins.reserve_num_rows(cdata->_ends.size());
|
||||
GeomVertexWriter maxs(cdata->_maxs.get_write_pointer(), 0);
|
||||
maxs.reserve_num_rows(cdata->_ends.size());
|
||||
|
||||
|
||||
int pi = 0;
|
||||
|
||||
|
||||
unsigned int vertex = index.get_data1i();
|
||||
cdata->_min_vertex = vertex;
|
||||
cdata->_max_vertex = vertex;
|
||||
unsigned int min_prim = vertex;
|
||||
unsigned int max_prim = vertex;
|
||||
|
||||
|
||||
int num_unused_vertices = get_num_unused_vertices_per_primitive();
|
||||
|
||||
for (int vi = 1; vi < num_vertices; ++vi) {
|
||||
nassertv(!index.is_at_end());
|
||||
unsigned int vertex = index.get_data1i();
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, vertex);
|
||||
cdata->_max_vertex = max(cdata->_max_vertex, vertex);
|
||||
|
||||
nassertv(pi < (int)cdata->_ends.size());
|
||||
|
||||
unsigned int vertex;
|
||||
|
||||
if (vi == cdata->_ends[pi]) {
|
||||
// Skip unused vertices, since they won't be very relevant and
|
||||
// may contain a strip-cut index, which would distort the result.
|
||||
if (num_unused_vertices > 0) {
|
||||
vi += num_unused_vertices;
|
||||
index.set_row_unsafe(vi);
|
||||
}
|
||||
vertex = index.get_data1i();
|
||||
|
||||
mins.add_data1i(min_prim);
|
||||
maxs.add_data1i(max_prim);
|
||||
min_prim = vertex;
|
||||
max_prim = vertex;
|
||||
++pi;
|
||||
|
||||
|
||||
} else {
|
||||
vertex = index.get_data1i();
|
||||
min_prim = min(min_prim, vertex);
|
||||
max_prim = max(max_prim, vertex);
|
||||
}
|
||||
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, vertex);
|
||||
cdata->_max_vertex = max(cdata->_max_vertex, vertex);
|
||||
}
|
||||
|
||||
mins.add_data1i(min_prim);
|
||||
maxs.add_data1i(max_prim);
|
||||
nassertv(mins.get_array_data()->get_num_rows() == (int)cdata->_ends.size());
|
||||
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle; just compute
|
||||
// the overall minmax.
|
||||
GeomVertexReader index(cdata->_vertices.get_read_pointer(), 0);
|
||||
|
||||
|
||||
cdata->_mins.clear();
|
||||
cdata->_maxs.clear();
|
||||
|
||||
|
||||
unsigned int vertex = index.get_data1i();
|
||||
cdata->_min_vertex = vertex;
|
||||
cdata->_max_vertex = vertex;
|
||||
|
||||
|
||||
for (int vi = 1; vi < num_vertices; ++vi) {
|
||||
nassertv(!index.is_at_end());
|
||||
unsigned int vertex = index.get_data1i();
|
||||
|
|
@ -1863,7 +1987,7 @@ recompute_minmax(GeomPrimitive::CData *cdata) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cdata->_got_minmax = true;
|
||||
}
|
||||
|
||||
|
|
@ -1900,22 +2024,25 @@ do_make_indexed(CData *cdata) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
consider_elevate_index_type(CData *cdata, int vertex) {
|
||||
// Note that we reserve the highest possible index of a particular
|
||||
// index type (ie. -1) because this is commonly used as a strip-cut
|
||||
// (also known as primitive restart) index.
|
||||
switch (cdata->_index_type) {
|
||||
case NT_uint8:
|
||||
if (vertex > 0xff) {
|
||||
if (vertex >= 0xff) {
|
||||
do_set_index_type(cdata, NT_uint16);
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_uint16:
|
||||
if (vertex > 0xffff) {
|
||||
if (vertex >= 0xffff) {
|
||||
do_set_index_type(cdata, NT_uint32);
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_uint32:
|
||||
// Not much we can do here.
|
||||
nassertv(vertex <= 0x7fffffff);
|
||||
nassertv(vertex < 0x7fffffff);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1930,6 +2057,9 @@ consider_elevate_index_type(CData *cdata, int vertex) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
do_set_index_type(CData *cdata, GeomPrimitive::NumericType index_type) {
|
||||
int old_strip_cut_index = get_strip_cut_index(cdata->_index_type);
|
||||
int new_strip_cut_index = get_strip_cut_index(index_type);
|
||||
|
||||
cdata->_index_type = index_type;
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
|
|
@ -1939,7 +2069,7 @@ do_set_index_type(CData *cdata, GeomPrimitive::NumericType index_type) {
|
|||
|
||||
if (!cdata->_vertices.is_null()) {
|
||||
CPT(GeomVertexArrayFormat) new_format = get_index_format();
|
||||
|
||||
|
||||
CPT(GeomVertexArrayData) array_obj = cdata->_vertices.get_read_pointer();
|
||||
if (array_obj->get_array_format() != new_format) {
|
||||
PT(GeomVertexArrayData) new_vertices = make_index_data();
|
||||
|
|
@ -1947,9 +2077,13 @@ do_set_index_type(CData *cdata, GeomPrimitive::NumericType index_type) {
|
|||
|
||||
GeomVertexReader from(array_obj, 0);
|
||||
GeomVertexWriter to(new_vertices, 0);
|
||||
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
to.set_data1i(from.get_data1i());
|
||||
int index = from.get_data1i();
|
||||
if (index == old_strip_cut_index) {
|
||||
index = new_strip_cut_index;
|
||||
}
|
||||
to.set_data1i(index);
|
||||
}
|
||||
cdata->_vertices = new_vertices;
|
||||
cdata->_got_minmax = false;
|
||||
|
|
@ -2057,7 +2191,7 @@ int GeomPrimitive::CData::
|
|||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
_vertices = DCAST(GeomVertexArrayData, p_list[pi++]);
|
||||
_vertices = DCAST(GeomVertexArrayData, p_list[pi++]);
|
||||
|
||||
if (manager->get_file_minor_ver() < 6 && !_vertices.is_null()) {
|
||||
// Older bam files might have a meaningless number in
|
||||
|
|
@ -2107,7 +2241,7 @@ check_minmax() const {
|
|||
#ifdef DO_PIPELINING
|
||||
unref_delete((CycleData *)_cdata);
|
||||
#endif
|
||||
GeomPrimitive::CDWriter fresh_cdata(((GeomPrimitive *)_object.p())->_cycler,
|
||||
GeomPrimitive::CDWriter fresh_cdata(((GeomPrimitive *)_object.p())->_cycler,
|
||||
false, _current_thread);
|
||||
((GeomPrimitivePipelineReader *)this)->_cdata = fresh_cdata;
|
||||
#ifdef DO_PIPELINING
|
||||
|
|
@ -2133,7 +2267,7 @@ check_minmax() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_first_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitivePipelineReader::
|
||||
get_first_vertex() const {
|
||||
|
|
@ -2171,7 +2305,7 @@ get_vertex(int i) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_num_primitives
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitivePipelineReader::
|
||||
get_num_primitives() const {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ PUBLISHED:
|
|||
int get_primitive_start(int n) const;
|
||||
int get_primitive_end(int n) const;
|
||||
int get_primitive_num_vertices(int n) const;
|
||||
int get_num_used_vertices() const;
|
||||
|
||||
INLINE int get_num_faces() const;
|
||||
INLINE int get_primitive_num_faces(int n) const;
|
||||
|
|
@ -163,6 +164,7 @@ PUBLISHED:
|
|||
void set_nonindexed_vertices(int first_vertex, int num_vertices);
|
||||
|
||||
INLINE int get_index_stride() const;
|
||||
INLINE int get_strip_cut_index() const;
|
||||
|
||||
INLINE CPTA_int get_ends() const;
|
||||
PTA_int modify_ends();
|
||||
|
|
@ -183,17 +185,21 @@ public:
|
|||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
|
||||
|
||||
IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
CPT(GeomVertexArrayFormat) get_index_format() const;
|
||||
static const GeomVertexArrayFormat *get_index_format(NumericType index_type);
|
||||
INLINE const GeomVertexArrayFormat *get_index_format() const;
|
||||
INLINE PT(GeomVertexArrayData) make_index_data() const;
|
||||
|
||||
private:
|
||||
static CPT(GeomVertexArrayFormat) make_index_format(NumericType index_type);
|
||||
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
static int get_highest_index_value(NumericType index_type);
|
||||
static int get_strip_cut_index(NumericType index_type);
|
||||
|
||||
public:
|
||||
virtual bool draw(GraphicsStateGuardianBase *gsg,
|
||||
|
|
@ -201,7 +207,7 @@ public:
|
|||
bool force) const=0;
|
||||
|
||||
void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
|
||||
bool &found_any,
|
||||
bool &found_any,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool got_mat, const LMatrix4 &mat,
|
||||
const InternalName *column_name,
|
||||
|
|
@ -213,7 +219,7 @@ protected:
|
|||
virtual CPT(GeomPrimitive) doubleside_impl() const;
|
||||
virtual CPT(GeomPrimitive) reverse_impl() const;
|
||||
virtual bool requires_unused_vertices() const;
|
||||
virtual void append_unused_vertices(GeomVertexArrayData *vertices,
|
||||
virtual void append_unused_vertices(GeomVertexArrayData *vertices,
|
||||
int vertex);
|
||||
|
||||
private:
|
||||
|
|
@ -358,6 +364,7 @@ public:
|
|||
INLINE int get_index_stride() const;
|
||||
INLINE const GeomVertexArrayDataHandle *get_vertices_reader() const;
|
||||
INLINE const unsigned char *get_read_pointer(bool force) const;
|
||||
INLINE int get_strip_cut_index() const;
|
||||
INLINE CPTA_int get_ends() const;
|
||||
INLINE CPT(GeomVertexArrayData) get_mins() const;
|
||||
INLINE CPT(GeomVertexArrayData) get_maxs() const;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,17 @@ get_geom_rendering() const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomTristrips::get_min_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minimum number of vertices that must be
|
||||
// added before close_primitive() may legally be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomTristrips::
|
||||
get_min_num_vertices_per_primitive() const {
|
||||
return 3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomTristrips::get_num_unused_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -142,6 +153,7 @@ decompose_impl() const {
|
|||
CPTA_int ends = get_ends();
|
||||
|
||||
int num_vertices = get_num_vertices();
|
||||
int num_unused = get_num_unused_vertices_per_primitive();
|
||||
|
||||
// We need a slightly different algorithm for SM_flat_first_vertex
|
||||
// than for SM_flat_last_vertex, to preserve the key vertex in the
|
||||
|
|
@ -150,11 +162,11 @@ decompose_impl() const {
|
|||
if (get_shade_model() == SM_flat_first_vertex) {
|
||||
// Preserve the first vertex of each component triangle as the
|
||||
// first vertex of each generated triangle.
|
||||
int vi = -2;
|
||||
int vi = -num_unused;
|
||||
int li = 0;
|
||||
while (li < (int)ends.size()) {
|
||||
// Skip unused vertices between tristrips.
|
||||
vi += 2;
|
||||
vi += num_unused;
|
||||
int end = ends[li];
|
||||
nassertr(vi + 2 <= end, NULL);
|
||||
int v0 = get_vertex(vi);
|
||||
|
|
@ -192,11 +204,11 @@ decompose_impl() const {
|
|||
} else {
|
||||
// Preserve the last vertex of each component triangle as the
|
||||
// last vertex of each generated triangle.
|
||||
int vi = -2;
|
||||
int vi = -num_unused;
|
||||
int li = 0;
|
||||
while (li < (int)ends.size()) {
|
||||
// Skip unused vertices between tristrips.
|
||||
vi += 2;
|
||||
vi += num_unused;
|
||||
int end = ends[li];
|
||||
nassertr(vi + 2 <= end, NULL);
|
||||
int v0 = get_vertex(vi);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ public:
|
|||
virtual PT(GeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
virtual int get_geom_rendering() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
virtual int get_num_unused_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ PT(InternalName) InternalName::_view;
|
|||
TypeHandle InternalName::_type_handle;
|
||||
TypeHandle InternalName::_texcoord_type_handle;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
InternalName::PyInternTable InternalName::_py_intern_table;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::Constructor
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@ class EXPCL_PANDA_GOBJ InternalName : public TypedWritableReferenceCount {
|
|||
private:
|
||||
InternalName(InternalName *parent, const string &basename);
|
||||
|
||||
public:
|
||||
INLINE static PT(InternalName) make(const string &name);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~InternalName();
|
||||
virtual bool unref() const;
|
||||
|
||||
INLINE static PT(InternalName) make(const string &name);
|
||||
static PT(InternalName) make(const string &name, int index);
|
||||
PT(InternalName) append(const string &basename);
|
||||
|
||||
|
|
@ -88,6 +90,22 @@ PUBLISHED:
|
|||
INLINE static PT(InternalName) get_model();
|
||||
INLINE static PT(InternalName) get_view();
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
EXTENSION(static PT(InternalName) make(PyUnicodeObject *str));
|
||||
#else
|
||||
EXTENSION(static PT(InternalName) make(PyStringObject *str));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef HAVE_PYTHON
|
||||
// It's OK for us to define it here since these are just pointers of
|
||||
// which the reference is maintained indefinitely.
|
||||
typedef phash_map<PyObject *, InternalName *, pointer_hash> PyInternTable;
|
||||
static PyInternTable _py_intern_table;
|
||||
#endif
|
||||
|
||||
private:
|
||||
PT(InternalName) _parent;
|
||||
string _basename;
|
||||
|
|
@ -116,7 +134,7 @@ private:
|
|||
static PT(InternalName) _camera;
|
||||
static PT(InternalName) _model;
|
||||
static PT(InternalName) _view;
|
||||
|
||||
|
||||
public:
|
||||
// Datagram stuff
|
||||
static void register_with_read_factory();
|
||||
|
|
@ -157,5 +175,3 @@ INLINE ostream &operator << (ostream &out, const InternalName &tcn);
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
// Filename: internalName_ext.I
|
||||
// Created by: rdb (28Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "internalName_ext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::make
|
||||
// Access: Published, Static
|
||||
// Description: This extension method serves to allow coercion of
|
||||
// Python interned strings to InternalName objects
|
||||
// more efficiently by storing a mapping between
|
||||
// Python and Panda interned strings.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PT(InternalName) Extension<InternalName>::
|
||||
make(PyUnicodeObject *str) {
|
||||
if (!PyUnicode_CHECK_INTERNED(str)) {
|
||||
// Not an interned string; don't bother.
|
||||
Py_ssize_t len = 0;
|
||||
char *c_str = PyUnicode_AsUTF8AndSize((PyObject *)str, &len);
|
||||
if (c_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string name(c_str, len);
|
||||
return InternalName::make(c_str, len);
|
||||
}
|
||||
|
||||
InternalName::PyInternTable::const_iterator it;
|
||||
it = InternalName::_py_intern_table.find((PyObject*)str);
|
||||
|
||||
if (it != InternalName::_py_intern_table.end()) {
|
||||
return (*it).second;
|
||||
|
||||
} else {
|
||||
Py_ssize_t len = 0;
|
||||
char *c_str = PyUnicode_AsUTF8AndSize((PyObject *)str, &len);
|
||||
string name(c_str, len);
|
||||
|
||||
#else
|
||||
PT(InternalName) Extension<InternalName>::
|
||||
make(PyStringObject *str) {
|
||||
if (!PyString_CHECK_INTERNED(str)) {
|
||||
// Not an interned string; don't bother.
|
||||
string name(PyString_AS_STRING(str), PyString_GET_SIZE(str));
|
||||
return InternalName::make(name);
|
||||
}
|
||||
|
||||
InternalName::PyInternTable::const_iterator it;
|
||||
it = InternalName::_py_intern_table.find((PyObject*)str);
|
||||
|
||||
if (it != InternalName::_py_intern_table.end()) {
|
||||
return (*it).second;
|
||||
|
||||
} else {
|
||||
string name(PyString_AS_STRING(str), PyString_GET_SIZE(str));
|
||||
|
||||
#endif // PY_MAJOR_VERSION
|
||||
|
||||
PT(InternalName) iname = InternalName::make(name);
|
||||
|
||||
// We basically leak references to both the PyObject and the
|
||||
// InternalName. We may want to change that in the future if it
|
||||
// becomes a problem.
|
||||
Py_INCREF(str);
|
||||
iname->ref();
|
||||
|
||||
InternalName::_py_intern_table.insert(make_pair((PyObject *)str, iname.p()));
|
||||
return iname.p();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Filename: internalName_ext.h
|
||||
// Created by: rdb (28Sep14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INTERNALNAME_EXT_H
|
||||
#define INTERNALNAME_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "internalName.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<InternalName>
|
||||
// Description : This class defines the extension methods for
|
||||
// InternalName, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<InternalName> : public ExtensionBase<InternalName> {
|
||||
public:
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
static PT(InternalName) make(PyUnicodeObject *str);
|
||||
#else
|
||||
static PT(InternalName) make(PyStringObject *str);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // INTERNALNAME_EXT_H
|
||||
|
|
@ -30,3 +30,6 @@
|
|||
#include "indexBufferContext.cxx"
|
||||
#include "internalName.cxx"
|
||||
#include "lens.cxx"
|
||||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
#include "matrixLens.cxx"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
#include "matrixLens.cxx"
|
||||
#include "occlusionQueryContext.cxx"
|
||||
#include "orthographicLens.cxx"
|
||||
#include "perspectiveLens.cxx"
|
||||
|
|
@ -21,6 +18,7 @@
|
|||
#include "textureReloadRequest.cxx"
|
||||
#include "textureStage.cxx"
|
||||
#include "textureStagePool.cxx"
|
||||
#include "timerQueryContext.cxx"
|
||||
#include "transformBlend.cxx"
|
||||
#include "transformBlendTable.cxx"
|
||||
#include "transformTable.cxx"
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::get_filename
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Return the Shader's filename for the given shader
|
||||
// type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const Filename Shader::
|
||||
INLINE Filename Shader::
|
||||
get_filename(const ShaderType &type) const {
|
||||
if (_filename->_separate) {
|
||||
nassertr(type != ST_none || !_filename->_shared.empty(), "");
|
||||
if (_filename->_separate && type == ST_none) {
|
||||
switch (type) {
|
||||
case ST_vertex:
|
||||
return _filename->_vertex;
|
||||
|
|
@ -51,7 +51,7 @@ get_filename(const ShaderType &type) const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::get_text
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Return the Shader's text for the given shader type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &Shader::
|
||||
|
|
@ -146,7 +146,7 @@ have_shader_utilization() {
|
|||
// Description: Returns the shader language in which this shader
|
||||
// was written.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const Shader::ShaderLanguage Shader::
|
||||
INLINE Shader::ShaderLanguage Shader::
|
||||
get_language() const {
|
||||
return _language;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,10 +96,10 @@ PUBLISHED:
|
|||
const string &tess_evaluation = "");
|
||||
static PT(Shader) make_compute(const ShaderLanguage &lang, const string &body);
|
||||
|
||||
INLINE const Filename get_filename(const ShaderType &type = ST_none) const;
|
||||
INLINE Filename get_filename(const ShaderType &type = ST_none) const;
|
||||
INLINE const string &get_text(const ShaderType &type = ST_none) const;
|
||||
INLINE const bool get_error_flag() const;
|
||||
INLINE const ShaderLanguage get_language() const;
|
||||
INLINE ShaderLanguage get_language() const;
|
||||
|
||||
INLINE static ShaderUtilization get_shader_utilization();
|
||||
INLINE static void set_shader_utilization(ShaderUtilization utl);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Filename: occlusionQueryContext.I
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TimerQueryContext::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TimerQueryContext::
|
||||
TimerQueryContext(int pstats_index) :
|
||||
_pstats_index(pstats_index),
|
||||
_frame_index(ClockObject::get_global_clock()->get_frame_count())
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Filename: timerQueryContext.cxx
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "timerQueryContext.h"
|
||||
|
||||
TypeHandle TimerQueryContext::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TimerQueryContext::get_timestamp
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the timestamp that is the result of this
|
||||
// timer query. There's no guarantee about which
|
||||
// clock this uses, the only guarantee is that
|
||||
// subtracting a start time from an end time should
|
||||
// yield a time in seconds.
|
||||
// If is_answer_ready() did not return true, this
|
||||
// function may block before it returns.
|
||||
//
|
||||
// It is only valid to call this from the draw thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double TimerQueryContext::
|
||||
get_timestamp() const {
|
||||
return 0.0;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// Filename: timerQueryContext.h
|
||||
// Created by: rdb (22Aug14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TIMERQUERYCONTEXT_H
|
||||
#define TIMERQUERYCONTEXT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "queryContext.h"
|
||||
#include "clockObject.h"
|
||||
#include "pStatCollector.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TimerQueryContext
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ TimerQueryContext : public QueryContext {
|
||||
public:
|
||||
INLINE TimerQueryContext(int pstats_index);
|
||||
|
||||
ALLOC_DELETED_CHAIN(TimerQueryContext);
|
||||
|
||||
virtual double get_timestamp() const=0;
|
||||
|
||||
int _frame_index;
|
||||
int _pstats_index;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
QueryContext::init_type();
|
||||
register_type(_type_handle, "TimerQueryContext",
|
||||
QueryContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "timerQueryContext.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -32,7 +32,6 @@ class GraphicsOutputBase;
|
|||
|
||||
class VertexBufferContext;
|
||||
class IndexBufferContext;
|
||||
class OcclusionQueryContext;
|
||||
class GeomContext;
|
||||
class GeomNode;
|
||||
class Geom;
|
||||
|
|
@ -123,9 +122,10 @@ PUBLISHED:
|
|||
|
||||
virtual bool get_supports_multisample() const=0;
|
||||
virtual int get_supported_geom_rendering() const=0;
|
||||
virtual bool get_supports_occlusion_query() const=0;
|
||||
virtual bool get_supports_shadow_filter() const=0;
|
||||
|
||||
virtual bool get_supports_texture_srgb() const=0;
|
||||
|
||||
public:
|
||||
// These are some general interface functions; they're defined here
|
||||
// mainly to make it easy to call these from code in some directory
|
||||
|
|
@ -153,16 +153,13 @@ public:
|
|||
|
||||
virtual ShaderContext *prepare_shader(Shader *shader)=0;
|
||||
virtual void release_shader(ShaderContext *sc)=0;
|
||||
|
||||
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data)=0;
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc)=0;
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data)=0;
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc)=0;
|
||||
|
||||
virtual void begin_occlusion_query()=0;
|
||||
virtual PT(OcclusionQueryContext) end_occlusion_query()=0;
|
||||
|
||||
virtual void dispatch_compute(int size_x, int size_y, int size_z)=0;
|
||||
|
||||
virtual PT(GeomMunger) get_geom_munger(const RenderState *state,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#if defined(WIN32_VC) || defined(WIN64_VC)
|
||||
#include <winsock2.h> // For gethostname()
|
||||
#include <Iphlpapi.h> // For GetAdaptersAddresses()
|
||||
#elif defined(ANDROID)
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
|
|
@ -542,14 +544,14 @@ scan_interfaces() {
|
|||
TextEncoder encoder;
|
||||
encoder.set_wtext(wstring(p->FriendlyName));
|
||||
string friendly_name = encoder.get_text();
|
||||
|
||||
|
||||
Interface iface;
|
||||
iface.set_name(friendly_name);
|
||||
|
||||
if (p->PhysicalAddressLength > 0) {
|
||||
iface.set_mac_address(format_mac_address((const unsigned char *)p->PhysicalAddress, p->PhysicalAddressLength));
|
||||
}
|
||||
|
||||
|
||||
if (p->OperStatus == IfOperStatusUp) {
|
||||
// Prefixes are a linked list, in the order Network IP,
|
||||
// Adapter IP, Broadcast IP (plus more).
|
||||
|
|
@ -586,6 +588,9 @@ scan_interfaces() {
|
|||
PANDA_FREE_ARRAY(addresses);
|
||||
}
|
||||
|
||||
#elif defined(ANDROID)
|
||||
// TODO: implementation using netlink_socket?
|
||||
|
||||
#else // WIN32_VC
|
||||
struct ifaddrs *ifa;
|
||||
if (getifaddrs(&ifa) != 0) {
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
nassertr(geom_reader.check_valid(&data_reader), false);
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
geom_rendering = geom_reader.get_geom_rendering();
|
||||
geom_rendering = _state->get_geom_rendering(geom_rendering);
|
||||
geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering);
|
||||
|
||||
|
||||
if (geom_rendering & Geom::GR_point_bits) {
|
||||
if (geom_reader.get_primitive_type() != Geom::PT_points) {
|
||||
if (singular_points) {
|
||||
|
|
@ -92,7 +92,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
|
||||
int gsg_bits = gsg->get_supported_geom_rendering();
|
||||
if (!hardware_point_sprites) {
|
||||
|
|
@ -115,7 +115,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
// _munged_data, and might also replace _state.
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "munge_points_to_quads() for geometry with bits: "
|
||||
<< "munge_points_to_quads() for geometry with bits: "
|
||||
<< hex << geom_rendering << ", unsupported: "
|
||||
<< (unsupported_bits & Geom::GR_point_bits) << dec << "\n";
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
// If we have to compute the light vector, we have to animate
|
||||
// the vertices in the CPU--and we have to do it before we call
|
||||
// munge_geom(), which might lose the tangent and binormal.
|
||||
CPT(GeomVertexData) animated_vertices =
|
||||
CPT(GeomVertexData) animated_vertices =
|
||||
_munged_data->animate_vertices(force, current_thread);
|
||||
if (animated_vertices != _munged_data) {
|
||||
cpu_animated = true;
|
||||
|
|
@ -156,7 +156,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||
// has been munged--that is, we couldn't arrange to handle the
|
||||
// animation in hardware--then we have to calculate that
|
||||
// animation now.
|
||||
CPT(GeomVertexData) animated_vertices =
|
||||
CPT(GeomVertexData) animated_vertices =
|
||||
_munged_data->animate_vertices(force, current_thread);
|
||||
if (animated_vertices != _munged_data) {
|
||||
cpu_animated = true;
|
||||
|
|
@ -240,7 +240,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
|
||||
// Better get the animated vertices, in case we're showing sprites
|
||||
// on an animated model for some reason.
|
||||
CPT(GeomVertexData) source_data =
|
||||
CPT(GeomVertexData) source_data =
|
||||
_munged_data->animate_vertices(force, current_thread);
|
||||
|
||||
if (!force && !source_data->request_resident()) {
|
||||
|
|
@ -308,22 +308,22 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
FormatMap::iterator fmi = _format_map.find(sformat);
|
||||
if (fmi != _format_map.end()) {
|
||||
new_format = (*fmi).second;
|
||||
|
||||
|
||||
} else {
|
||||
// We have to construct the format now.
|
||||
PT(GeomVertexArrayFormat) new_array_format;
|
||||
if (sformat._retransform_sprites) {
|
||||
// With retransform_sprites in effect, we will be sending ordinary
|
||||
// 3-D points to the graphics API.
|
||||
new_array_format =
|
||||
new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
|
||||
new_array_format =
|
||||
new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
|
||||
Geom::NT_stdfloat,
|
||||
Geom::C_point);
|
||||
} else {
|
||||
// Without retransform_sprites, we will be sending 4-component
|
||||
// clip-space points.
|
||||
new_array_format =
|
||||
new GeomVertexArrayFormat(InternalName::get_vertex(), 4,
|
||||
new_array_format =
|
||||
new GeomVertexArrayFormat(InternalName::get_vertex(), 4,
|
||||
Geom::NT_stdfloat,
|
||||
Geom::C_clip_point);
|
||||
}
|
||||
|
|
@ -344,14 +344,14 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
(InternalName::get_texcoord(), 2,
|
||||
Geom::NT_stdfloat,
|
||||
Geom::C_texcoord);
|
||||
|
||||
|
||||
} else if (has_texcoord) {
|
||||
const GeomVertexColumn *c = texcoord.get_column();
|
||||
new_array_format->add_column
|
||||
(InternalName::get_texcoord(), c->get_num_components(),
|
||||
c->get_numeric_type(), c->get_contents());
|
||||
}
|
||||
|
||||
|
||||
new_format = GeomVertexFormat::register_format(new_array_format);
|
||||
_format_map[sformat] = new_format;
|
||||
}
|
||||
|
|
@ -408,7 +408,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
LPoint3 eye = modelview.xform_point(vertex.get_data3());
|
||||
points[vi]._eye = eye;
|
||||
points[vi]._dist = gsg->compute_distance_to(points[vi]._eye);
|
||||
|
||||
|
||||
// The point in clip coordinates.
|
||||
LPoint4 p4 = LPoint4(eye[0], eye[1], eye[2], 1.0f) * projection;
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
scale_y /= gsg->compute_distance_to(eye);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Also factor in the homogeneous scale for being in clip
|
||||
// coordinates still.
|
||||
scale_y *= p4[3];
|
||||
|
|
@ -447,7 +447,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
LPoint2 c0(scale_x, scale_y);
|
||||
LPoint2 c1(-scale_x, scale_y);
|
||||
|
||||
if (has_rotate) {
|
||||
if (has_rotate) {
|
||||
// If we have a rotate factor, apply it to those two corners.
|
||||
PN_stdfloat r = rotate.get_data1f();
|
||||
LMatrix3 mat = LMatrix3::rotate_mat(r);
|
||||
|
|
@ -461,7 +461,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
PN_stdfloat ry = 1.0f / viewport_height;
|
||||
c0.set(c0[0] * rx, c0[1] * ry);
|
||||
c1.set(c1[0] * rx, c1[1] * ry);
|
||||
|
||||
|
||||
if (retransform_sprites) {
|
||||
// With retransform_sprites in effect, we must reconvert the
|
||||
// resulting quad back into the original 3-D space.
|
||||
|
|
@ -469,7 +469,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3])));
|
||||
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
|
||||
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
|
||||
|
||||
|
||||
if (has_normal) {
|
||||
const LNormal &c = normal.get_data3();
|
||||
new_normal.set_data3(c);
|
||||
|
|
@ -477,7 +477,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
new_normal.set_data3(c);
|
||||
new_normal.set_data3(c);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// Without retransform_sprites, we can simply load the
|
||||
// clip-space coordinates.
|
||||
|
|
@ -485,7 +485,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
new_vertex.set_data4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3]);
|
||||
new_vertex.set_data4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]);
|
||||
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
|
||||
|
||||
|
||||
if (has_normal) {
|
||||
LNormal c = render_transform.xform_vec(normal.get_data3());
|
||||
new_normal.set_data3(c);
|
||||
|
|
@ -521,18 +521,20 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
nassertr(new_data->get_num_rows() == new_verts, false);
|
||||
}
|
||||
|
||||
PT(Geom) new_geom = new Geom(new_data);
|
||||
|
||||
// Create an appropriate GeomVertexArrayFormat for the primitive
|
||||
// index.
|
||||
static CPT(GeomVertexArrayFormat) new_prim_format;
|
||||
if (new_prim_format == (GeomVertexArrayFormat *)NULL) {
|
||||
new_prim_format =
|
||||
GeomVertexArrayFormat::register_format
|
||||
(new GeomVertexArrayFormat(InternalName::get_index(), 1,
|
||||
GeomEnums::NT_uint16, GeomEnums::C_index));
|
||||
// Determine the format we should use to store the indices.
|
||||
const GeomVertexArrayFormat *new_prim_format = NULL;
|
||||
if (new_verts < 0xff) {
|
||||
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint8);
|
||||
|
||||
} else if (new_verts < 0xffff) {
|
||||
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint16);
|
||||
|
||||
} else {
|
||||
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint32);
|
||||
}
|
||||
|
||||
PT(Geom) new_geom = new Geom(new_data);
|
||||
|
||||
// Replace each primitive in the Geom (it's presumably a GeomPoints
|
||||
// primitive, although it might be some other kind of primitive if
|
||||
// we got here because RenderModeAttrib::M_point is enabled) with a
|
||||
|
|
@ -575,11 +577,11 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
vertices[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now sort the points in order from back-to-front so they will
|
||||
// render properly with transparency, at least with each other.
|
||||
sort(vertices, vertices_end, SortPoints(points));
|
||||
|
||||
|
||||
// Go through the points, now in sorted order, and generate a pair
|
||||
// of triangles for each one. We generate indexed triangles
|
||||
// instead of two-triangle strips, since this seems to be
|
||||
|
|
@ -589,7 +591,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||
PT(GeomPrimitive) new_primitive = new GeomTriangles(Geom::UH_stream);
|
||||
int new_prim_verts = 6 * num_vertices; // two triangles per point.
|
||||
|
||||
PT(GeomVertexArrayData) new_index
|
||||
PT(GeomVertexArrayData) new_index
|
||||
= new GeomVertexArrayData(new_prim_format, GeomEnums::UH_stream);
|
||||
new_index->unclean_set_num_rows(new_prim_verts);
|
||||
|
||||
|
|
@ -669,14 +671,14 @@ munge_texcoord_light_vector(const CullTraverser *traverser, bool force) {
|
|||
string source_name = tex_gen->get_source_name(stage);
|
||||
Light *light_obj = light.node()->as_light();
|
||||
nassertr(light_obj != (Light *)NULL, false);
|
||||
|
||||
|
||||
// Determine the names of the tangent and binormal columns
|
||||
// associated with the stage's texcoord name.
|
||||
PT(InternalName) tangent_name = InternalName::get_tangent_name(source_name);
|
||||
PT(InternalName) binormal_name = InternalName::get_binormal_name(source_name);
|
||||
|
||||
|
||||
PT(InternalName) texcoord_name = stage->get_texcoord_name();
|
||||
|
||||
|
||||
if (_munged_data->has_column(tangent_name) &&
|
||||
_munged_data->has_column(binormal_name)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ make_single_threshold(PN_stdfloat thresh0, PN_stdfloat val0) {
|
|||
CPT(RenderAttrib) LightRampAttrib::
|
||||
make_double_threshold(PN_stdfloat thresh0, PN_stdfloat val0, PN_stdfloat thresh1, PN_stdfloat val1) {
|
||||
LightRampAttrib *attrib = new LightRampAttrib();
|
||||
attrib->_mode = LRT_single_threshold;
|
||||
attrib->_mode = LRT_double_threshold;
|
||||
attrib->_threshold[0] = thresh0;
|
||||
attrib->_level[0] = val0;
|
||||
attrib->_threshold[1] = thresh1;
|
||||
|
|
|
|||
|
|
@ -2322,7 +2322,7 @@ do_calc_components() {
|
|||
_hpr.set(0.0f, 0.0f, 0.0f);
|
||||
_quat = LQuaternion::ident_quat();
|
||||
_pos.set(0.0f, 0.0f, 0.0f);
|
||||
_flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale;
|
||||
_flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale | F_identity_scale;
|
||||
|
||||
} else {
|
||||
// If we don't have components and we're not identity, the only
|
||||
|
|
|
|||
|
|
@ -1180,12 +1180,11 @@ synthesize_shader(const RenderState *rs) {
|
|||
PN_stdfloat t1 = light_ramp->get_threshold(1);
|
||||
PN_stdfloat l0 = light_ramp->get_level(0);
|
||||
PN_stdfloat l1 = light_ramp->get_level(1);
|
||||
PN_stdfloat l2 = light_ramp->get_level(2);
|
||||
text << "\t // Double-threshold light ramp\n";
|
||||
text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n";
|
||||
text << "\t float lr_out = " << l0 << "\n";
|
||||
text << "\t if (lr_in > " << t0 << ") lr_out=" << l1 << ";\n";
|
||||
text << "\t if (lr_in > " << t1 << ") lr_out=" << l2 << ";\n";
|
||||
text << "\t float lr_out = 0.0;\n";
|
||||
text << "\t if (lr_in > " << t0 << ") lr_out=" << l0 << ";\n";
|
||||
text << "\t if (lr_in > " << t1 << ") lr_out=" << l1 << ";\n";
|
||||
text << "\t tot_diffuse = tot_diffuse * (lr_out / lr_in);\n";
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,17 @@ ConfigVariableDouble pstats_target_frame_rate
|
|||
"This frame rate is marked with a different-colored line; "
|
||||
"otherwise, this setting has no effect."));
|
||||
|
||||
ConfigVariableBool pstats_gpu_timing
|
||||
("pstats-gpu-timing", false,
|
||||
PRC_DESC("Set this true to query the graphics library for the actual time "
|
||||
"that graphics operations take to execute on the video card. "
|
||||
"Enabling this will harm performance, but this information can "
|
||||
"be more useful than the regular Draw information in tracking "
|
||||
"down bottlenecks, because the CPU-based Draw collectors only "
|
||||
"measure how long it takes for the API call to complete, which "
|
||||
"is not usually an accurate reflectino of how long the actual "
|
||||
"operation takes on the video card."));
|
||||
|
||||
// The rest are different in that they directly control the server,
|
||||
// not the client.
|
||||
ConfigVariableBool pstats_scroll_mode
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ extern EXPCL_PANDA_PSTATCLIENT ConfigVariableDouble pstats_tcp_ratio;
|
|||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableString pstats_host;
|
||||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableInt pstats_port;
|
||||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableDouble pstats_target_frame_rate;
|
||||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableBool pstats_gpu_timing;
|
||||
|
||||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableBool pstats_scroll_mode;
|
||||
extern EXPCL_PANDA_PSTATCLIENT ConfigVariableDouble pstats_history;
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ get_collector_fullname(int index) const {
|
|||
if (parent_index == 0) {
|
||||
return collector->get_name();
|
||||
} else {
|
||||
return get_collector_fullname(parent_index) + ":" +
|
||||
return get_collector_fullname(parent_index) + ":" +
|
||||
collector->get_name();
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +180,6 @@ get_main_thread() const {
|
|||
return PStatThread((PStatClient *)this, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::get_current_thread
|
||||
// Access: Published
|
||||
|
|
@ -191,7 +190,7 @@ get_main_thread() const {
|
|||
PStatThread PStatClient::
|
||||
get_current_thread() const {
|
||||
if (!client_is_connected()) {
|
||||
// No need to make the relatively expensive call to
|
||||
// No need to make the relatively expensive call to
|
||||
// Thread::get_current_thread() if we're not even connected.
|
||||
return get_main_thread();
|
||||
}
|
||||
|
|
@ -222,10 +221,10 @@ main_tick() {
|
|||
|
||||
|
||||
_mmap_size_pcollector.set_level(MemoryUsage::get_panda_mmap_size());
|
||||
|
||||
|
||||
TypeRegistry *type_reg = TypeRegistry::ptr();
|
||||
int num_typehandles = type_reg->get_num_typehandles();
|
||||
|
||||
|
||||
while ((int)type_handle_cols.size() < num_typehandles) {
|
||||
type_handle_cols.push_back(TypeHandleCollector());
|
||||
}
|
||||
|
|
@ -261,7 +260,7 @@ main_tick() {
|
|||
case TypeHandle::MC_limit:
|
||||
// Not used.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t min_usage = (single_total_usage + array_total_usage + dc_active_total_usage + dc_inactive_total_usage) / 1024;
|
||||
|
|
@ -288,7 +287,7 @@ main_tick() {
|
|||
case TypeHandle::MC_singleton:
|
||||
category = "Heap:Single";
|
||||
break;
|
||||
|
||||
|
||||
case TypeHandle::MC_array:
|
||||
category = "Heap:Array";
|
||||
break;
|
||||
|
|
@ -315,11 +314,11 @@ main_tick() {
|
|||
case TypeHandle::MC_singleton:
|
||||
single_other_usage -= usage;
|
||||
break;
|
||||
|
||||
|
||||
case TypeHandle::MC_array:
|
||||
array_other_usage -= usage;
|
||||
break;
|
||||
|
||||
|
||||
case TypeHandle::MC_deleted_chain_active:
|
||||
dc_active_other_usage -= usage;
|
||||
break;
|
||||
|
|
@ -348,7 +347,7 @@ main_tick() {
|
|||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
get_global_pstats()->client_main_tick();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::thread_tick
|
||||
|
|
@ -359,7 +358,7 @@ main_tick() {
|
|||
void PStatClient::
|
||||
thread_tick(const string &sync_name) {
|
||||
get_global_pstats()->client_thread_tick(sync_name);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::client_main_tick
|
||||
|
|
@ -383,8 +382,8 @@ client_main_tick() {
|
|||
_threads_by_sync_name.find("Main");
|
||||
if (ni != _threads_by_sync_name.end()) {
|
||||
const vector_int &indices = (*ni).second;
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
++vi) {
|
||||
_impl->new_frame(*vi);
|
||||
}
|
||||
|
|
@ -407,8 +406,8 @@ client_thread_tick(const string &sync_name) {
|
|||
_threads_by_sync_name.find(sync_name);
|
||||
if (ni != _threads_by_sync_name.end()) {
|
||||
const vector_int &indices = (*ni).second;
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
++vi) {
|
||||
_impl->new_frame(*vi);
|
||||
}
|
||||
|
|
@ -463,7 +462,7 @@ PStatClient *PStatClient::
|
|||
get_global_pstats() {
|
||||
if (_global_pstats == (PStatClient *)NULL) {
|
||||
_global_pstats = new PStatClient;
|
||||
|
||||
|
||||
ClockObject::_start_clock_wait = start_clock_wait;
|
||||
ClockObject::_start_clock_busy_wait = start_clock_busy_wait;
|
||||
ClockObject::_stop_clock_wait = stop_clock_wait;
|
||||
|
|
@ -616,8 +615,8 @@ do_make_thread(Thread *thread) {
|
|||
// We have seen a thread with this name before. Can we re-use any
|
||||
// of them?
|
||||
const vector_int &indices = (*ni).second;
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
for (vector_int::const_iterator vi = indices.begin();
|
||||
vi != indices.end();
|
||||
++vi) {
|
||||
int index = (*vi);
|
||||
nassertr(index >= 0 && index < _num_threads, PStatThread());
|
||||
|
|
@ -637,20 +636,26 @@ do_make_thread(Thread *thread) {
|
|||
int new_index = _num_threads;
|
||||
thread->set_pstats_index(new_index);
|
||||
thread->set_pstats_callback(this);
|
||||
_threads_by_name[thread->get_name()].push_back(new_index);
|
||||
_threads_by_sync_name[thread->get_sync_name()].push_back(new_index);
|
||||
|
||||
|
||||
InternalThread *pthread = new InternalThread(thread);
|
||||
add_thread(pthread);
|
||||
|
||||
// We need an additional PerThreadData for this thread in all of the
|
||||
// collectors.
|
||||
CollectorPointer *collectors = (CollectorPointer *)_collectors;
|
||||
for (int ci = 0; ci < _num_collectors; ++ci) {
|
||||
Collector *collector = collectors[ci];
|
||||
collector->_per_thread.push_back(PerThreadData());
|
||||
nassertr((int)collector->_per_thread.size() == _num_threads, PStatThread());
|
||||
}
|
||||
return PStatThread(this, new_index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::make_gpu_thread
|
||||
// Access: Private
|
||||
// Description: Returns a PStatThread representing the GPU.
|
||||
// This is normally called by the GSG only.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PStatThread PStatClient::
|
||||
make_gpu_thread(const string &name) {
|
||||
ReMutexHolder holder(_lock);
|
||||
int new_index = _num_threads;
|
||||
|
||||
InternalThread *pthread = new InternalThread(name, "GPU");
|
||||
add_thread(pthread);
|
||||
|
||||
return PStatThread(this, new_index);
|
||||
}
|
||||
|
|
@ -960,7 +965,7 @@ get_level(int collector_index, int thread_index) const {
|
|||
// Description: This function is added as a hook into ClockObject, so
|
||||
// that we may time the delay for
|
||||
// ClockObject::wait_until(), used for certain special
|
||||
// clock modes.
|
||||
// clock modes.
|
||||
//
|
||||
// This callback is a hack around the fact that we can't
|
||||
// let the ClockObject directly create a PStatCollector,
|
||||
|
|
@ -977,7 +982,7 @@ start_clock_wait() {
|
|||
// Description: This function is added as a hook into ClockObject, so
|
||||
// that we may time the delay for
|
||||
// ClockObject::wait_until(), used for certain special
|
||||
// clock modes.
|
||||
// clock modes.
|
||||
//
|
||||
// This callback is a hack around the fact that we can't
|
||||
// let the ClockObject directly create a PStatCollector,
|
||||
|
|
@ -995,7 +1000,7 @@ start_clock_busy_wait() {
|
|||
// Description: This function is added as a hook into ClockObject, so
|
||||
// that we may time the delay for
|
||||
// ClockObject::wait_until(), used for certain special
|
||||
// clock modes.
|
||||
// clock modes.
|
||||
//
|
||||
// This callback is a hack around the fact that we can't
|
||||
// let the ClockObject directly create a PStatCollector,
|
||||
|
|
@ -1051,6 +1056,9 @@ add_collector(PStatClient::Collector *collector) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClient::
|
||||
add_thread(PStatClient::InternalThread *thread) {
|
||||
_threads_by_name[thread->_name].push_back(_num_threads);
|
||||
_threads_by_sync_name[thread->_sync_name].push_back(_num_threads);
|
||||
|
||||
if (_num_threads >= _threads_size) {
|
||||
// We need to grow the array. We have to be careful here, because
|
||||
// there might be clients accessing the array right now who are
|
||||
|
|
@ -1071,12 +1079,21 @@ add_thread(PStatClient::InternalThread *thread) {
|
|||
// and then no more.)
|
||||
|
||||
new_threads[_num_threads] = thread;
|
||||
AtomicAdjust::inc(_num_threads);
|
||||
|
||||
} else {
|
||||
ThreadPointer *threads = (ThreadPointer *)_threads;
|
||||
threads[_num_threads] = thread;
|
||||
AtomicAdjust::inc(_num_threads);
|
||||
}
|
||||
|
||||
AtomicAdjust::inc(_num_threads);
|
||||
|
||||
// We need an additional PerThreadData for this thread in all of the
|
||||
// collectors.
|
||||
CollectorPointer *collectors = (CollectorPointer *)_collectors;
|
||||
for (int ci = 0; ci < _num_collectors; ++ci) {
|
||||
Collector *collector = collectors[ci];
|
||||
collector->_per_thread.push_back(PerThreadData());
|
||||
nassertv((int)collector->_per_thread.size() == _num_threads);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1148,7 +1165,7 @@ make_def(const PStatClient *client, int this_index) {
|
|||
if (_def == (PStatCollectorDef *)NULL) {
|
||||
_def = new PStatCollectorDef(this_index, _name);
|
||||
if (_parent_index != this_index) {
|
||||
const PStatCollectorDef *parent_def =
|
||||
const PStatCollectorDef *parent_def =
|
||||
client->get_collector_def(_parent_index);
|
||||
_def->set_parent(*parent_def);
|
||||
}
|
||||
|
|
@ -1157,9 +1174,9 @@ make_def(const PStatClient *client, int this_index) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::Collector::make_def
|
||||
// Function: PStatClient::InternalThread::Constructor
|
||||
// Access: Private
|
||||
// Description: Creates the new PStatCollectorDef for this collector.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PStatClient::InternalThread::
|
||||
InternalThread(Thread *thread) :
|
||||
|
|
@ -1174,4 +1191,22 @@ InternalThread(Thread *thread) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatClient::InternalThread::Constructor
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PStatClient::InternalThread::
|
||||
InternalThread(const string &name, const string &sync_name) :
|
||||
_thread(NULL),
|
||||
_name(name),
|
||||
_sync_name(sync_name),
|
||||
_is_active(false),
|
||||
_frame_number(0),
|
||||
_next_packet(0.0),
|
||||
_thread_active(true),
|
||||
_thread_lock(string("PStatClient::InternalThread ") + name)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // DO_PSTATS
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
class PStatCollector;
|
||||
class PStatCollectorDef;
|
||||
class PStatThread;
|
||||
class GraphicsStateGuardian;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PStatClient
|
||||
|
|
@ -113,6 +114,7 @@ private:
|
|||
PStatThread do_get_current_thread() const;
|
||||
PStatThread make_thread(Thread *thread);
|
||||
PStatThread do_make_thread(Thread *thread);
|
||||
PStatThread make_gpu_thread(const string &name);
|
||||
|
||||
bool is_active(int collector_index, int thread_index) const;
|
||||
bool is_started(int collector_index, int thread_index) const;
|
||||
|
|
@ -171,7 +173,7 @@ private:
|
|||
INLINE const string &get_name() const;
|
||||
INLINE bool is_active() const;
|
||||
INLINE PStatCollectorDef *get_def(const PStatClient *client, int this_index) const;
|
||||
|
||||
|
||||
private:
|
||||
void make_def(const PStatClient *client, int this_index);
|
||||
|
||||
|
|
@ -201,6 +203,7 @@ private:
|
|||
class InternalThread {
|
||||
public:
|
||||
InternalThread(Thread *thread);
|
||||
InternalThread(const string &name, const string &sync_name = "Main");
|
||||
|
||||
WPT(Thread) _thread;
|
||||
string _name;
|
||||
|
|
@ -248,6 +251,7 @@ private:
|
|||
friend class PStatCollector;
|
||||
friend class PStatThread;
|
||||
friend class PStatClientImpl;
|
||||
friend class GraphicsStateGuardian;
|
||||
};
|
||||
|
||||
#include "pStatClient.I"
|
||||
|
|
@ -272,4 +276,3 @@ PUBLISHED:
|
|||
#endif // DO_PSTATS
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue