intcmp(structmaze gidle*head,intf("QQ:%s\nname:%s\nage:%s\n\

/var/www//android/mydroid/dalvik/vm/Native.c
* Copyright (C) 2008 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the &License&);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &AS IS& BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Native method resolution.
* Currently the &Dalvik native& methods are only used for internal methods.
* Someday we may want to export the interface as a faster but riskier
* alternative to JNI.
#include &Dalvik.h&
#include &stdlib.h&
#include &dlfcn.h&
static void freeSharedLibEntry(void* ptr);
static void* lookupSharedLibMethod(const Method* method);
* Initialize the native code loader.
bool dvmNativeStartup(void)
gDvm.nativeLibs = dvmHashTableCreate(4, freeSharedLibEntry);
if (gDvm.nativeLibs == NULL)
return false;
return true;
* Free up our tables.
void dvmNativeShutdown(void)
dvmHashTableFree(gDvm.nativeLibs);
gDvm.nativeLibs = NULL;
* Resolve a native method and invoke it.
* This is executed as if it were a native bridge or function.
* resolution succeeds, method-&insns is replaced, and we don't go through
* here again.
* Initializes method's class if necessary.
* An exception is thrown on resolution failure.
void dvmResolveNativeMethod(const u4* args, JValue* pResult,
const Method* method, Thread* self)
ClassObject* clazz = method-&clazz;
void* func;
* If this is a static method, it could be called before the class
* has been initialized.
if (dvmIsStaticMethod(method)) {
if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
assert(dvmCheckException(dvmThreadSelf()));
assert(dvmIsClassInitialized(clazz) ||
dvmIsClassInitializing(clazz));
/* start with our internal-native methods */
func = dvmLookupInternalNativeMethod(method);
if (func != NULL) {
/* resolution always gets the same answer, so no race here */
IF_LOGVV() {
char* desc = dexProtoCopyMethodDescriptor(&method-&prototype);
LOGVV(&+++ resolved native %s.%s %s, invoking\n&,
clazz-&descriptor, method-&name, desc);
free(desc);
if (dvmIsSynchronizedMethod(method)) {
LOGE(&ERROR: internal-native can't be declared 'synchronized'\n&);
LOGE(&Failing on %s.%s\n&, method-&clazz-&descriptor, method-&name);
dvmAbort();
// harsh, but this is VM-internal problem
DalvikBridgeFunc dfunc = (DalvikBridgeFunc) func;
dvmSetNativeFunc(method, dfunc, NULL);
assert(method-&insns == NULL);
dfunc(args, pResult, method, self);
/* now scan any DLLs we have loaded for JNI signatures */
func = lookupSharedLibMethod(method);
if (func != NULL) {
if (dvmIsSynchronizedMethod(method))
dvmSetNativeFunc(method, dvmCallSynchronizedJNIMethod, func);
dvmSetNativeFunc(method, dvmCallJNIMethod, func);
dvmCallJNIMethod(args, pResult, method, self);
IF_LOGW() {
char* desc = dexProtoCopyMethodDescriptor(&method-&prototype);
LOGW(&No implementation found for native %s.%s %s\n&,
clazz-&descriptor, method-&name, desc);
free(desc);
dvmThrowException(&Ljava/lang/UnsatisfiedLinkE&, method-&name);
* ===========================================================================
Native shared library support
* ===========================================================================
// TODO? if a ClassLoader is unloaded, we need to unload all DLLs that
// are associated with it.
(Or not -- can't determine if native code
// is still using parts of it.)
* We add one of these to the hash table for every library we load.
* hash is on the &pathName& field.
typedef struct SharedLib {
/* absolute path to library */
/* from dlopen */
classLoader;
/* ClassLoader we are associated with */
} SharedLib;
* (This is a dvmHashTableLookup callback.)
* Find an entry that matches the string.
static int hashcmpNameStr(const void* ventry, const void* vname)
const SharedLib* pLib = (const SharedLib*) ventry;
const char* name = (const char*) vname;
return strcmp(pLib-&pathName, name);
* (This is a dvmHashTableLookup callback.)
* Find an entry that matches the new entry.
static int hashcmpSharedLib(const void* ventry, const void* vnewEntry)
const SharedLib* pLib = (const SharedLib*) ventry;
const SharedLib* pNewLib = (const SharedLib*) vnewEntry;
LOGD(&--- comparing %p '%s' %p '%s'\n&,
pLib, pLib-&pathName, pNewLib, pNewLib-&pathName);
return strcmp(pLib-&pathName, pNewLib-&pathName);
* Check to see if an entry with the same pathname already exists.
static const SharedLib* findSharedLibEntry(const char* pathName)
u4 hash = dvmComputeUtf8Hash(pathName);
void* ent;
ent = dvmHashTableLookup(gDvm.nativeLibs, hash, (void*)pathName,
hashcmpNameStr, false);
return ent;
* Add the new entry to the table.
* Returns &true& on success, &false& if the entry already exists.
static bool addSharedLibEntry(SharedLib* pLib)
u4 hash = dvmComputeUtf8Hash(pLib-&pathName);
void* ent;
* Do the lookup with the &add& flag set.
If we add it, we will get
* our own pointer back.
If somebody beat us to the punch, we'll get
* their pointer back instead.
ent = dvmHashTableLookup(gDvm.nativeLibs, hash, pLib, hashcmpSharedLib,
return (ent == pLib);
* Free up an entry.
(This is a dvmHashTableFree callback.)
static void freeSharedLibEntry(void* ptr)
SharedLib* pLib = (SharedLib*) ptr;
* Calling dlclose() here is somewhat dangerous, because it's possible
* that a thread outside the VM is still accessing the code we loaded.
if (false)
dlclose(pLib-&handle);
free(pLib-&pathName);
free(pLib);
* Convert library name to system-dependent form, e.g. &jpeg& becomes
* &libjpeg.so&.
* (Should we have this take buffer+len and avoid the alloc?
* called very rarely.)
char* dvmCreateSystemLibraryName(char* libName)
char buf[<font color="#FF];
len = snprintf(buf, sizeof(buf), OS_SHARED_LIB_FORMAT_STR, libName);
if (len &= (int) sizeof(buf))
return NULL;
return strdup(buf);
* Find a library, given the lib's system-dependent name (e.g. &libjpeg.so&).
* We need to search through the path defined by the java.library.path
* property.
* Returns NULL if the library was not found.
static char* findLibrary(const char* libSysName)
char* javaLibraryPath = NULL;
char* testName = NULL;
char* start;
bool done;
javaLibraryPath = dvmGetProperty(&java.library.path&);
if (javaLibraryPath == NULL)
goto bail;
LOGVV(&+++ path is '%s'\n&, javaLibraryPath);
start = cp = javaLibraryPath;
while (cp != NULL) {
char pathBuf[<font color="#FF];
cp = strchr(start, ':');
if (cp != NULL)
*cp = '\0';
len = snprintf(pathBuf, sizeof(pathBuf), &%s/%s&, start, libSysName);
if (len &= (int) sizeof(pathBuf)) {
LOGW(&Path overflowed %d bytes: '%s' / '%s'\n&,
len, start, libSysName);
/* keep going, next one might fit */
LOGVV(&+++
trying '%s'\n&, pathBuf);
if (access(pathBuf, R_OK) == 0) {
testName = strdup(pathBuf);
start = cp +1;
free(javaLibraryPath);
return testName;
* Load a native shared library, given the system-independent piece of
* the library name.
* Throws an exception on failure.
void dvmLoadNativeLibrary(StringObject* libNameObj, Object* classLoader)
char* libName = NULL;
char* libSysName = NULL;
char* libPath = NULL;
* If &classLoader& isn't NULL, call the class loader's &findLibrary&
* method with the lib name.
If it returns a non-NULL result, we use
* that as the pathname.
if (classLoader != NULL) {
Method* findLibrary;
Object* findLibResult;
findLibrary = dvmFindVirtualMethodByDescriptor(classLoader-&clazz,
&findLibrary&, &(Ljava/lang/S)Ljava/lang/S&);
if (findLibrary == NULL) {
LOGW(&Could not find findLibrary() in %s\n&,
classLoader-&clazz-&name);
dvmThrowException(&Ljava/lang/UnsatisfiedLinkE&,
&findLibrary&);
goto bail;
findLibResult = (Object*)(u4) dvmCallMethod(findLibrary, classLoader,
libNameObj);
if (dvmCheckException()) {
LOGV(&returning early on exception\n&);
goto bail;
if (findLibResult != NULL) {
/* success! */
libPath = dvmCreateCstrFromString(libNameObj);
LOGI(&Found library through CL: '%s'\n&, libPath);
dvmLoadNativeCode(libPath, classLoader);
goto bail;
libName = dvmCreateCstrFromString(libNameObj);
if (libName == NULL)
goto bail;
libSysName = dvmCreateSystemLibraryName(libName);
if (libSysName == NULL)
goto bail;
libPath = findLibrary(libSysName);
if (libPath != NULL) {
LOGD(&Found library through path: '%s'\n&, libPath);
dvmLoadNativeCode(libPath, classLoader);
LOGW(&Unable to locate shared lib matching '%s'\n&, libSysName);
dvmThrowException(&Ljava/lang/UnsatisfiedLinkE&, libName);
free(libName);
free(libSysName);
free(libPath);
typedef int (*OnLoadFunc)(JavaVM*, void*);
* Load native code from the specified absolute pathname.
Per the spec,
* if we've already loaded a library with the specified pathname, we
* return without doing anything.
* TODO? for better results we should absolutify the pathname.
* correct results we should stat to get the inode and compare that.
* existing implementation is fine so long as everybody is using
* System.loadLibrary.
* The library will be associated with the specified class loader.
* spec says we can't load the same library into more than one class loader.
* Returns &true& on success.
bool dvmLoadNativeCode(const char* pathName, Object* classLoader)
const SharedLib* pEntry;
void* handle;
LOGD(&Trying to load lib %s %p\n&, pathName, classLoader);
* See if we've already loaded it.
If we have, and the class loader
* matches, return successfully without doing anything.
pEntry = findSharedLibEntry(pathName);
if (pEntry != NULL) {
if (pEntry-&classLoader != classLoader) {
LOGW(&Shared lib '%s' already opened by CL %p; can't open in %p\n&,
pathName, pEntry-&classLoader, classLoader);
return false;
LOGD(&Shared lib '%s' already loaded in same CL %p\n&,
pathName, classLoader);
return true;
* Open the shared library.
Because we're using a full path, the system
* doesn't have to search through LD_LIBRARY_PATH.
(It may do so to
* resolve this library's dependencies though.)
* Failures here are expected when java.library.path has several entries.
* The current android-arm dynamic linker implementation tends to
* return &Cannot find library& from dlerror() regardless of the actual
* problem.
A more useful diagnostic may be sent to stdout/stderr,
* but often that's not visible.
Some things to try:
- make sure the library exists on the device
- verify that the right path is being opened (the debug log message
above can help with that)
- check to see if the library is valid
- check config/prelink-linux-arm.map to ensure that the library
is listed and is not being overrun by the previous entry (if
loading suddenly stops working, this is a good one to check)
handle = dlopen(pathName, RTLD_LAZY);
if (handle == NULL) {
LOGI(&Unable to dlopen(%s): %s\n&, pathName, dlerror());
return false;
SharedLib* pNewEntry;
pNewEntry = (SharedLib*) malloc(sizeof(SharedLib));
pNewEntry-&pathName = strdup(pathName);
pNewEntry-&handle = handle;
pNewEntry-&classLoader = classLoader;
if (!addSharedLibEntry(pNewEntry)) {
LOGI(&WOW: we lost a race to add a shared lib (%s %p)\n&,
pathName, classLoader);
/* free up our entry, and just return happy that one exists */
freeSharedLibEntry(pNewEntry);
LOGD(&Added shared lib %s %p\n&, pathName, classLoader);
void* vonLoad;
int version;
vonLoad = dlsym(handle, &JNI_OnLoad&);
if (vonLoad == NULL) {
LOGD(&No JNI_OnLoad found in %s %p\n&, pathName, classLoader);
* Call JNI_OnLoad.
We have to override the current class
* loader, which will always be &null& since the stuff at the
* top of the stack is around Runtime.loadLibrary().
OnLoadFunc func = vonLoad;
Thread* self = dvmThreadSelf();
Object* prevOverride = self-&classLoaderOverride;
self-&classLoaderOverride = classLoader;
dvmChangeStatus(NULL, THREAD_NATIVE);
version = (*func)(gDvm.vmList, NULL);
dvmChangeStatus(NULL, THREAD_RUNNING);
self-&classLoaderOverride = prevOverride;
if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 &&
version != JNI_VERSION_1_6)
LOGW(&JNI_OnLoad returned bad version (%d) in %s %p\n&,
version, pathName, classLoader);
// TODO: dlclose, remove hash table entry
return false;
return true;
* ===========================================================================
Signature-based method lookup
* ===========================================================================
* Create the pre-mangled form of the class+method string.
* Returns a newly-allocated string, and sets &*pLen& to the length.
static char* createJniNameString(const char* classDescriptor,
const char* methodName, int* pLen)
char* result;
size_t descriptorLength = strlen(classDescriptor);
*pLen = 4 + descriptorLength + strlen(methodName);
result = malloc(*pLen +1);
if (result == NULL)
return NULL;
* Add one to classDescriptor to skip the &L&, and then replace
* the final &;& with a &/& after the sprintf() call.
sprintf(result, &Java/%s%s&, classDescriptor + 1, methodName);
result[5 + (descriptorLength - 2)] = '/';
return result;
* Returns a newly-allocated, mangled copy of &str&.
* &str& is a &modified UTF-8& string.
We convert it to UTF-16 first to
* make life simpler.
static char* mangleString(const char* str, int len)
u2* utf16 = NULL;
char* mangle = NULL;
int charLen;
//LOGI(&mangling '%s' %d\n&, str, len);
assert(str[len] == '\0');
charLen = dvmUtf8Len(str);
utf16 = (u2*) malloc(sizeof(u2) * charLen);
if (utf16 == NULL)
goto bail;
dvmConvertUtf8ToUtf16(utf16, str);
* Compute the length of the mangled string.
int i, mangleLen = 0;
for (i = 0; i & charLen; i++) {
u2 ch = utf16[i];
if (ch & <font color="#FF) {
mangleLen += 6;
switch (ch) {
mangleLen += 2;
mangleLen++;
mangle = (char*) malloc(mangleLen +1);
if (mangle == NULL)
goto bail;
for (i = 0, cp = mangle; i & charLen; i++) {
u2 ch = utf16[i];
if (ch & <font color="#FF) {
sprintf(cp, &_0%04x&, ch);
switch (ch) {
*cp++ = '_';
*cp++ = '1';
*cp++ = '_';
*cp++ = '2';
*cp++ = '_';
*cp++ = '3';
*cp++ = '_';
*cp++ = (char) ch;
*cp = '\0';
free(utf16);
return mangle;
* Create the mangled form of the parameter types.
static char* createMangledSignature(const DexProto* proto)
DexStringCache sigCache;
const char* interim;
char* result;
dexStringCacheInit(&sigCache);
interim = dexProtoGetParameterDescriptors(proto, &sigCache);
result = mangleString(interim, strlen(interim));
dexStringCacheRelease(&sigCache);
return result;
* (This is a dvmHashForeach callback.)
* Search for a matching method in this shared library.
static int findMethodInLib(void* vlib, void* vmethod)
const SharedLib* pLib = (const SharedLib*) vlib;
const Method* meth = (const Method*) vmethod;
char* preMangleCM = NULL;
char* mangleCM = NULL;
char* mangleSig = NULL;
char* mangleCMSig = NULL;
void* func = NULL;
if (meth-&clazz-&classLoader != pLib-&classLoader) {
LOGD(&+++ not scanning '%s' for '%s' (wrong CL)\n&,
pLib-&pathName, meth-&name);
LOGV(&+++ scanning '%s' for '%s'\n&, pLib-&pathName, meth-&name);
* First, we try it without the signature.
preMangleCM =
createJniNameString(meth-&clazz-&descriptor, meth-&name, &len);
if (preMangleCM == NULL)
goto bail;
mangleCM = mangleString(preMangleCM, len);
if (mangleCM == NULL)
goto bail;
LOGV(&+++ calling dlsym(%s)\n&, mangleCM);
func = dlsym(pLib-&handle, mangleCM);
if (func == NULL) {
mangleSig =
createMangledSignature(&meth-&prototype);
if (mangleSig == NULL)
goto bail;
mangleCMSig = (char*) malloc(strlen(mangleCM) + strlen(mangleSig) +3);
if (mangleCMSig == NULL)
goto bail;
sprintf(mangleCMSig, &%s__%s&, mangleCM, mangleSig);
LOGV(&+++ calling dlsym(%s)\n&, mangleCMSig);
func = dlsym(pLib-&handle, mangleCMSig);
if (func != NULL) {
LOGV(&Found '%s' with dlsym\n&, mangleCMSig);
LOGV(&Found '%s' with dlsym\n&, mangleCM);
free(preMangleCM);
free(mangleCM);
free(mangleSig);
free(mangleCMSig);
return (int) func;
* See if the requested method lives in any of the currently-loaded
* shared libraries.
We do this by checking each of them for the expected
* method signature.
static void* lookupSharedLibMethod(const Method* method)
if (gDvm.nativeLibs == NULL) {
LOGE(&Unexpected init state: nativeLibs not ready\n&);
dvmAbort();
return (void*) dvmHashForeach(gDvm.nativeLibs, findMethodInLib,
(void*) method);
syntax highlighted by , v. 0.9.1192.168.1.21的server端会显示, connected by ('192.168.1.4',58559)后面的端口应该是随机的临时端口。其实它的确起到了转发作用,这个nginx进程相当于一个通用网关,如果有两个client向nginx进程发起连接,一旦nginx那边调度到同一个上游TCP服务器,那么只需要从NGINX进程建立一个TCP连接到上游TCP服务器即可。之前我自己设计网关的时候,不是依赖于用户的,而是通过静态配置来建立连接的,比如上游逻辑服务器跟网关有连接,那都是在启动服务器的时候,就建立起来了。这样有个好处就是可以省事,不过也可以采用这种方式,有玩家连接进某个上游TCP服务器才让网关跟这个TCP服务器建立连接,否则无需处理。因为不少时候还是会有不少服务器处于空闲的.
struct A{&// 装备&// 角色数据&};void main( void ){&//printf("hello world!");&char buffer[] = "This is a test of the memset function";
&A aS&// 发现数据相同。&memset(&aStruct,'*',sizeof(aStruct));&printf( "Before: %s\n", buffer );&memset( buffer, '*', 4 );&printf( "After:& %s\n", buffer );&if (buffer[2] == '*')&{&&printf("hello,world\n");&}&// 判断这个是否要保存。&if (aStruct.a == 0x2a2a2a2a)&{&&// 发送给DBSERVER.&&printf("hello char\n");&}&if (aStruct.c == 0x2a)&{
&}&getchar();
gamma系数就是灰度系数,改变gamma系数的值就是相当于改变色阶(图象亮度强弱的指数标准),gamma值越少,图象越亮. 调试d3d,将控制面板中D3DDebugging打开,进行调试,在选择调试信息输出等级的时候,可以选择more来获得更加多得详细信息。。 Direct3D9: (INFO) :MemFini!Direct3D9: (WARN) :Memory still allocated!& Alloc count = 152Direct3D9: (WARN) :Current Process (pid) = 00000fb8Direct3D9: (WARN) :Memory Address: 00c95988 lAllocID=1 dwSize=, (pid=00000fb8)这里是检测出内存泄露了.一般是内存信息什么的没有releasing和deleting掉. 之前遇到的一个问题lock is not supported when multi-sampling is enabled是因为shader debugging打开了,之后关闭了,就没有事情了。刚才编译hlsl的时候,发现了x3025错误,后来的dx版本要使用D3DXSHADER_ENABLE_BACKWARDS_COMPATIABLITY|D3DXSHADER_DEBUG才能编译,特别是2008年的dx版本。&DX默认的是D3DFILL_SOLID,如果出现D3DFILL_WIREFRAME的情况一定要设置回去。 CD3DArcBall:允许你将用户的输入解释为旋转或者平移.我们所要做的是将鼠标消息传递给这个类,并且将视图矩阵设为类的旋转或者平移矩阵就可以了. 点乘: a.b = ||a|| *||b|| * cosA, 一般用来判断为0,那么表明正交,&0,方向基本相同,&0,方向基本相反.使用点乘来计算投影.给定两向量v,n,将其分解为v平和v垂,分别平行于和垂直于n,并且满足 v = v平+v垂,一般成平行分量v平为v在n 上的投影.V平 = n * ||V平|| / ||n||.cosA = ||V平||/||V|| cosA||V|| = ||V平||V平= n*n*v/( ||n||*||n||).叉乘得到的向量垂直于原来的两个向量.a *b指向该平面的正上方,垂直于a和b.||a*b|| = ||a|| * ||b|| * sinA.||a*b|| 也等于以a和b为两边的平行四边形的面积.如果a,b平行或任意一个为0,则a*b = 0,叉乘对零向量的解释是它平行于任意其他向量,点乘的解释是和任意其他向量垂直. 任意对角矩阵D,都有D转置矩阵= D,包括单位矩阵.DirectX使用的行向量.v = xp+yq+zr,向量v就表示成p,q,r的线性变换了,向量p,q,r称做基向量.这里基向量是笛卡尔坐标系变换物体相当于以相反的量变换描述这个物体的坐标系.2d里面是这样设置的:逆时针旋转经常(不是必须)被认为是正方向,顺时针方向是负方向.绕x轴旋转:[ 1 0 0&&&&&&&& 0 cosA sinA0 -sinA cosA]绕y轴旋转:[cosA 0 -sinA0& 1 0sinA 0 cosA]绕z轴旋转:[ cosA sinA 0-sinA cosA 00 0 1] 绕轴n旋转角度A,那么获得的矩阵是:[nx*nx*(1-cosA)+cosA&&&& nx*ny*(1-cosA)-nz * sinA& nx*nz*(1-cosA) + ny*sinAnx * ny *(1-cosA) - nz *sinA ny*ny*(1-cosA)+cosA& ny*nz*(1-cosA) - nx* sinAnx * nz *(1-cosA)+ny * sinA ny * nz *(1-cosA) + nx* sinA nz*nz*(1-cosA)+cosA]缩放:通过基向量构造矩阵,得到以单位向量n为缩放方向,k为因子的缩放矩阵:s(n,k) = [ p]&&&& [ 1 + (k-1)nx2& (k-1)nxny&& (k-1)nxnz]&&&&&&&&&&&&&&&&&&& = &&&&&&&&&&&& [ q]&&&& [ (k -1)nxny&& 1+(k-1)ny2&& (k-1)nxnz]&&&&&&&&&&&& [ r]&&&& [(k-1)nxnz& (k-1)nzny&& 1+(k-1)nz2]投影意味着降维操作,有一种投影方法是在某个方向上用零做缩放因子,这种情况下,所有点都被拉平至垂直的轴(2D)或平面(3D),这种类型的投影称做正交投影,或者平行投影,因为从原来的点到投影点的直线相互平行.n垂直于投影直线,而不是平行,3D中,向垂直于n的平面投影的矩阵如公式:p(N) =&& [1-nx2 -nxny -nxnz]&&&&&&&&&&&&& [-nxny 1-ny2 -nynz]&&&&&&&&&&&&& [-nxnz -nzny 1-nz2]镜像: 将物体沿直线(2D中)或平面(3D中)翻折.P(n) = [ 1-2nx2 -2nxny -2nxnz]&&&&&&&&& [-2nxny 1-2ny2 -2nynz]&&&&&&&&& [-2nxnz -2nzny 1-2nz2] Hxy的意义是x,y坐标被坐标z改变Hxy(s,t) = [1 0 0]&&&&&&&&&&&&&&& [0 1 0]&&&&&&&&&&&&&&& [s& t 1&]Hxz(s,t) = [ 1 0 0]&&&&&&&&&&&&&&& [s& 1 t]&&&&&&&&&&&&&&& [0 0 1]Hyz(s,t) = [1 s t]&&&&&&&&&&&&&&& [0 1 0]&&&&&&&&&&&&&&& [0 0 1]&M物体-&像机 = M物体-&世界M世界-&像机P-&像机 = P物体 M物体-&像机线形变换: 如果满足下式,那么映射f(a)就是线性的:f(a+b) = f(a) + f(b)以及F(ka) = kf(a).仿射变换: 线性变换后接着平移,因此仿射变换的集合是线性变换的超集.任何线性变换都是仿射变换,但不是所有仿射变换都是线性变换. 如果存在一个逆变换可以"撤消"原变换,那么该变换是可逆的.如果变换前后两向量夹角的大小和方向都不改变,该变换是等角.只有平移,旋转和均匀缩放是等角变换.等角变换将会保持比例不变.平移,旋转和镜像是仅有的正交变换.长度,角度,面积,和体积都保持不变.刚体变换只改变物体的位置和方向,不包括形状,所有长度,角度,面积和体积都不变.平移和旋转是仅有的刚体变换,镜像并不被认为是刚体变换. 假设矩阵M有r行,c列,记法Mij表示从M中除去第i行和第j列后剩下的矩阵.显然,该矩阵有r-1行,c-1列,矩阵Mij称为M的余子式.
这几天安装这个sql server 2000,花掉了很多时间,希望以后安装的时候,尽量避免出现这些情况,其它的错误情况就不说明了,现在只说明我遇到的问题的解决办法:将原来的安装目录删除掉,将c:\program files\Microsoft SQL Server下面的80目录给删除掉,将注册表里面的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server以及HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer里面的键值信息删除掉。我机器上面并没有HKEY_LOCAL_USER\SOFTWARE\Microsoft\Microsoft SQL Server这个目录的。 application verifier 的信息可以从这里获得:/en-us/library/bb457063.aspxapplication verifier主要用来检测指针引起的内存错误.在程序运行期间进行跟踪内存使用情况. application verifier的log信息包括错误所在的调用堆栈,并且要注意及时地清除上次的错误记录,我之前遇到的问题是,我用application verifier检测到某个错误,而之后再用这个exedebug启动的时候,就报错,后来在application verifier里面清除了记录才可以正常运行.
computer display = a single graphics adapter + a display monitor.graphics adapter contains the hardware needed store and display images on a monitor or other display device.all of these adapters stored a representation of the displayed image in a bank of dual-ported memeory called a frame buffer.the system uses one of the ports to read and write images into the frame buffer.the second port is used by the video scan out circuitry of the adapter to create a signal for the monitor.Direct3D only supports VGA compatible adapters.Frame&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Color LookupBuffer&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Table2D Pixel&&&&&&&&&&&&&&&&&&&&&&&&&& D/AEngine&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ConverterHost CPU&&&&&&&&&&&&&&&&&&&&&&& CRT MonitorDirect3D abstractions include :device, swap chains, surfaces, and resource .an application enumerates the devices available on each adapter, examining their capablities and supported display modes to find an acceptable device.device is the object that expose the rendering operations of the hardware. its properties control the rendering behavior or provide information about rendering, while the device's methods are used to perform the rendering itself.devices always contain at least one swap chain and a collection of resources used for rendering.resources are application specific data stored in or near the device hardware for use during rendering Direct3D provides resources for scene geometry(vertices and indices) and appearance(images, textures, and volumes).a surface is a resource containing a rectangular collection of pixel data such as color, alpha, depth/stencil or texture information.a swap chain contains one or more back buffer surfaces where scenes are rendered and presented for display on the monitor, is a collection of back buffers.a device's render target is the back buffer surface, with an optional depth/stencil surface, in which rendering will occur.while all back buffers are valid render targets, not all render targets are back buffers.it is also possible to have a texture as a render target allowing dynamic rendering effects.to obtain a device object, Direct3D provides an object for device enumeration and creation. all other objects are created through the device. an application first obtains the runtime interface, then selects and creates a device from those available, and using the device creates the necessary resources for rendering.most COM methods return HRESULT to indicate success or failure.in windowed mode: the results of graphic rendering are presented for display insidei the client area of a window on the desktop.Direct3D cooperates with GDI to make the results of rendering visible, using a ::StretchBlt operation to present a back buffer in the window's client regionin exclusive mode: Direct3D communicates directly with the display driver avoiding GDI. when an exclusive mode application is running, no other applications have access to display hardware and no GDI is visible on the screen.HAL(hardware abstraction layer): has hardware acceleration of graphics rendering, making it fastest device type.reference device: useful for debugging, when developing software applications that target new features not&yet common in hardware, the reference device maybe your obly choice for generating an image with those Direct3D features.the null reference device: does nothing and all rendering will result in a black screen.useful for manipulating resources on a machine that provides no hardware or software &implementation of the runtime.the pluggable software device: RegisterSoftwareDevice method, each resource has Type, Pool, Format, and Usage attributes, each of these attributes of a resource are specified at the time the resource is created and remain constant for the lifetime of the resource object.type attributes describes the kind of resource and is defined by D3DRESOURCETYPE.pool attribute of a resource describes how it is managed by the Direct3D runtime and is defined by the D3DPOOL enumeration.resources in the default pool exist only in device memory.resources in the managed pool exist in system memory and will be copied into the device's memory by the runtime when needed.resource in the system memory pool exist only in system memoryresource in the scratch pool reside only in system memory and are not bound& by format constraints of the devicewhen a device is lost, all resources in the default pool are lost and should be released and recreated by the application when the device is regained.Format attribute of a resource describes the layout of the resources's data in memory and is defined by the D3DFORMAT enumeration. all resources have a format, but most of the format enumerants define the memory layout for pixel data.D3DFMT_D24S8: D:depth buffer, S:stencil buffer.Usage attribute describes how the application will be use the resource and is defined by a collection of flag bits. static reources are typically loaded with data once and used repeatedly without change, while dynamic resources are repeatedly modified bu the application.a direct3D application starts by obtaining the IDirect3D9 COM interface pointer by calling Direct3DCreate9.GetAdapterCount is to determine the number of adapters in the system. each adapter provides a number of video display modes. each display mode contains a screen dimention, refresh rate and pixel format and is described by D3DDISPLAYMODE structure.the back buffer surface format of a device must be compatible with the display mode's format. CheckDeviceFormat method can be used to discover compatible formats.GetAdapterModeCount: the number of display modes.EnumAdapterModes: the display mode information.GetAdapterDisplayMode: the display mode currently in use by the adapter.two display modes can have the same width, height and format values but different values for the RefreshRates.the CheckDeviceType method tells us if a particular combination of display format and back buffer format are valid for a device of a given type operating in windowed or exclusive mode.with a valid device type, we can check the device's capabilities for rendering required by our application with GetDeviceCaps.
we can validate all the resources required by our application with the CheckDeviceFormat, checkDeviceFormat should be used to validate all the format of all resources used by the application: back buffer surfaces, depth/stencil surfaces, texture surfaces, and volume texture formats. if the application requires a depth buffer for viaiblitiy determination, it should use CheckDepthStencilMatch to find a depth buffer that can be used with its render target formats in a given display mode.CheckDeviceMultiSampleType: check multisampling needs.GetAdapterIdentifier: allows an application to identify a specific brand of adapter from a specific vendor.D3DCREATE_ADAPTERGROUP_DEVICE: allows an application to drive both video outputs through a single device interface, allowing resources to be shaed for both outputs.Direct3D uses single precision floating point computations. if an application requires higher precision from FPU.there are two choices, either the application can ensure that the FPU is in single precision mode when calling into Direct3D, or ir can request that the device preserve the application's FPU precision before Direct3D performs any floating -point operations and restore the precision before returning to the application.D3DCREATE_SOFTWARE_VERTEXPROCESSING: select software vertex processing, which is always available from the runtime.the runtime used an efficient implementation of software vertex processing that is optimized for the CPU.D3DCREATE_MIXED_VEVERTEXPROCESSING: select a combination of software and hardware vertex processing selected by SetSoftwareVertexProcessing mixed vertex processing is incompatible with a pure device and will fail if both are requested together.D3DPRESENTFLAG_DEVICECLIP: restricts the results of a present operation to the client area of the device window in windowed mode.D3DPRESENTFLAG_DISCARDDEPTHSTENCIL: instructs the runtime to discard the contents of the depth stencil surface after a call to Present, or when a new depth stencil surface is set on the device.D3DPRESENTFLAG_LOCKABLEBACKBUFFER: requests a default swap chain with back buffer surfaces that can be directly accessed by the application.in windowed mode: hDeviceWindow specifies the window whose client area will be used for presentation in windowed operation& if hDeviceWindow is zero, then the focus window willbe used for presentation.in exclusive mode, hDeviceWindow specifies the top-level window used by the applicationD3DPRESENT_RATE_DEFAULT: instructs the runtime to choose a suitable refresh rate in exclusive mode, and uses the current refresh rate in windowed mode.an application may wish to create a full-screen display on a specific monitor.GetAdapterMonitor: return an HMONITOR handle for an adapter, once you have the handle to the device 's montior, u can determine what part of the virtual desktop is covered by the monitor.
a scene is a collection of three dimensional objects that are projected onto the render target surface from the viewpoint of a syntheitic camera each object in a scene is described by a collection of geometric primitives,&such as points, lines, and triangles, with the device's action methods.&the pipeline converts geometric descriptions into pixels on the render target surface through the process of rasterization. graphic primitives are rendered in the order in which they are described to the devices similar to the way a CPU executes binary instructions sequentially through memory.the entire graphics pipeline is controlled through the properties of the device.the properites are manipulated through the Get/Set methods of the device.every device has a distinct set of capabilities. Direct3D specifies an abstract machine interface, but does not provide a software emulation for a feature not provided directly by the hardware's driver.&a device provides specific information on its capabilities to allow an application to adapt to the capabilities of the device.much of the behavior of the graphics pipeline is controlled by render states.groups of device properties, including render states, can be cached and set as a group with state blocks.the device object represents the rendering pipeline, we get images from the pipeline by supplying it with scene data and instructing it to render scenes into images.scene data consists of geometric data defining shapes in space and data defining the appearance of the shapes.we can break the pipeline up into large sections consisting of vertex data assembly, vertex processing, promitive assembly and rasterization, pixel processing, the frame buffer,a dn video scan out.vertex data assembly section gathers together vertex components from a collection of data streams to assemble a compute vertex and its associated data.vertex processing performs computations on each vertex such as the transformation and lighting of vertices.the processed vertex data is then assembled into graphic primitives and rasterized into a stream of pixels.pixel processing performs a computations on each rasterized pixel to determine the final color of the pixel that will be written into the frame buffer.frame buffer performs a read/modify/write operations combining processed pixels from the rasterizer with the existing pixels in the render ttarget.video scan out reads the pixels out of the frame buffer for conversion into video signals displayed by the monitor.scenes are rendered to the render target selected on the device. if the render target is part of a swap chain, the render target can be made viaible on the device through presentation.the render target may not be part of a swap chain if the render target is a texture resource.you present renderings for display through a swap chain as the last thing you do when rendering a scene.a swap chain consists of one or more back color buffers into which images are rendered. a device is always associated with at least one swap chain and in windowed mode additional swap chains can be created to obtain multiple presentable surfaces.the philosophy of the Direct3D object is to expose the capabilities of the hardware to the application programmer and let the application adapt to the hardware.GetDeviceCaps: return the capabilities of an actual device, while GetDeviceCaps method on the Direct3D object returns the generic capabilities of a device.IUnknown&&&&&& IDirect3DVolume9&&&&& IDirect3DResource9&&&&&&&&&& IDirect3DIndexBuffer9&&&&&&&&&& IDirect3DVertexBuffer9&&&&&&&&&& IDirect3DSurface9&&&&&&&&&& IDirect3DBaseTexture9&&&&&&&&&&&&&& IDirect3DTexture9&&&&&&&&&&&&&& IDirect3DCubeTexture9&&&&&&&&&&&&&& IDirect3DVolumeTexture9resource objects are used as containers for the scene data rendered by the device such as primitive vertices, indices intto vertex arrays, surface textures and volumes.& two and three dimensional textures expose their contents as collections of sutfaces and volumes, respectively. the back buffer, depth/stencil buffer and render target properties of the device are also exposed as surfaces.volume objects do not inherit from IDirect3DResoutce9 and therefore do not participate in the resource management exposed by this interface.managed resources are assigned an unsigned integer priority, with higher priority taking precedence so that resources with a lower priority are discarded from device memory first.non-managed resources always return a priority of zero. within the same priority, Direct3D uses a least-recently used strategy to discard old resoucrs in preference to newly created resources.when the application attempts to use more resources than the card can hold while rendering a scene, Direct3D switches to a most-recently used first strategy for discarding memory.resources in D3DPOOL_DEFAULT are not managed and are never discarded from device memory by the resource manager.if u need to allocate new resources in the default pool after managed resources have been loaded, you should evict all managed resources before allocating new resources in the default pool.resources in pool D3DPOOL_SYSTEMMEM are never located in device memory, so that they do not participate in resource management.GetAvailableTextureMem: obtain an estimate of the available texture memory.the GetDevice method returns the device with which this resource is associated. resources cannot be shared across devices.GetPrivateData/SetPrivateData: allow an application to associate its own arbitrary chunks of data with any Direct3D erouces.each distinct item of private data is identified by a GUID. all private data associated with a resource is freed when the associated resource itself is freed.methods and functions in Direct3D that create COM objects, such as CreateDevice, add a reference to the object for the caller before they return the interface pointer, the application must release these objects when they are no longer needed to avoid a memory leak.Device queries allow you to obtain information from the driver layer of the device, the two main uses for driver queries are for obtaining rendering statistics and event notifications from the device.D3DQUERYTYPE enumeration gives the possible kinds of queries: vertex cache description queries, resource manager statistics queries, vertex statistics queries, event queries, occlusion queries, timestamp queries, time queries and cache utilization queries.a query exists in one of three state: signaled, building, or issued.Issue: used by the application to signal a state transition on the query.the device driver can also change the state of a query when it has returned the data requested by the query.the query will report the results for primitives issued between the begining of the query and the end of the query.occlusion queries return the number of pixels that passed the depth test for primitives rendered between the begin and end of the query.the resource manager statistics query returns a D3DDEVINFO_RESOURCEMANAGER structure, which contains an array of D3DRESOURCESTATS structure, one for each resource type. the vertex cache is a memory cache close to the GPU that avoids access to vertex memory for a small number of recently used vertices.PIX: is a performance measurement tool for DirectX applications. the remaining query types return data for performance measurements with tools like PIX.the device object's properties control the behavior of the rendering pipeline while its methods supply data for the pipeline to render.state blocks are COM objects that provide a way for your application to cache a group of device properties for later use.each state block is associated with a device, returned by the GetDevice method.once& a state block has been created, the state block can be applied to the device by calling apply on the state block, calling capture on an existing state block captures the current values of the device properties into the state block.there are two ways to create a state block object and fill it with specific device property values.the first way: call CreateStateBlock with D3DSTATEBLOCKTYPE value identifying the kind of state you& want recorded in the block.the second way of obtaining a state block object is to call BeginStateBlock, set device properties and then call EndStateBlock.when EndStateBlock is called, each device property marked for capture is recorded into the state block. if&a device property is set multiple times between BeginStateBlock and EndStateBlock, only the last value set in the property is captureed into the state block.release the state block COM object when you are finished with a state block.a pure device has a performance advantage because the runtime and driver do not have to keep a copy of the non-queryable state for the application. scenes contain one or more objects that are positioned relative to each other and to the virtual camera that views the scene. such objects are called "models", and contain data that define their shape and apperance. the shape of a model is described by a collection of a simple geometric shapes, called graphic primitives.when we draw a three dimensional scene, we need to solve the problem of visibility: objects in the foreground should occlude objects in the background. Two- dimensional applications use a painter's algorithm to determine visibility. Direct3D can use depth/stencil surfaces to resolve visibility. using either a flexible vertex format or a vertex shader declaration, Direct3D describes colors, textures corrdinates,vertex blending weights and arbitrary shader data at each vertex.the vertex data is supplied to the device through a collection of streams, each associated with a vertex buffer.the streams can be driven through a level of indirection with an index buffer.the streams can be driven though a level of indirection with an index buffer. the scene is described to the device one primitive at&a time. each primitive& is rasterized into a collection of pixels written to the render target property of the device.All Direct3D rendering is done within a scene. each successive frame draws the models at successive moments in time, as in cel animation used for cartoons. frame rates of greater than 15 fps can be preceived as "real-time", the z-buffer algorithm solution to the visibility problem works at each pixels on the render target instead of on models, as models are rasterized, each pixel that is associated with z value is used to determine which pixel is cloest to the camera.the closer pixels are stored into the render target, while pixels farther away are discarded. the depth/stencil buffer holds each pixel's depth from the camera. to use the Z-buffer for resolving visibility, set RS_Z Enable to D3DZB_TRUE,&RS_Z Write Enable to TRUE,&and RS_Z&Func to D3DCMP_LESS.if the D3DPRASTERCAPS_ZBUFFERLESSHSR bit of D3DCAPS9:RasterCaps is set, it indicates the device has an alternative visivility algorithm for hidden surface removal that doesn't use a Z-buffer. how visibility is determined is hardware dependent and application transparent.&all back buffers on swap chains are valid render targets, but render targets are not restricted to back buffer surfaces, when the device is created or reset, the render target is back buffer zero of the device's default swap chain. when present is called on the device, the render target& advances to the next back buffer so that after present returns, render target is back buffer zero again.setting the render target to a surface other than a back buffer surface allows the device to render directly into an imanage surface instead of rendering into a swap chain's back buffer and using stretchrect to obtain the results of the rendering, which could stall the pipeline. D3DPT_POINTLIST draws a collection of points, D3DPT_LINELIST draws a squence of possibly disjoint line segments.
&// 接受密聊对方名称,将焦点设置到聊天输入框中,并且将光标设置为第一个位置&// 参数1:密聊用户名,参数2:频道信息&static bool ChangeChannelAndSetFocus(char* username,Channel channel);这段代码看起来是没有事情的,但是在接口设置上面存在不好的做法,如果是私密频道的话,是有用username做私聊对象的,如果是非私聊频道的话,就没有这个私聊对象了.但是如果要调用这个接口的话,还得给个这样的值.比如这样的用法:-&ChangeChannelAndSetFocus("",public_channel),其实如果稍微改变一下接口设置的话,就好了.&static bool ChangeChannelAndSetFocus(Channel channelchar* username = "");这样使用默认参数就好了.之前的调用就可以这样使用了.:-&ChangeChannelAndSetFocus(public_channel),看起来舒服多了.哎感觉编程功底还有待加强,这么简单的问题,拿出来想想,还有这么多学问呢. 这几天写了一段函数代码,后来被一个家伙调用了,他直接在我的函数里面修改,这样造成了原来我函数里面的逻辑出现错误,现在想来,如果以后是这样的情况,就不能允许他在我的函数里面修改我的逻辑和相关调用,但是要留出接口给它调用,至于具体的操作,要我自己允许才能添加,当然我可以帮他看看原来他添加的代码,但是这样也就没有什么意义了.这种合作性的工作尤其要讲究这些,不然很麻烦的. 突然想起来要记录点什么,调试引擎的时候,可以采用这样的方式,打开上层逻辑的工程,然后将引擎相关的代码拖拽到上层逻辑所在的工程里面去,然后在这个代码里面可以设置相关断点,以前总不知道怎么找上层逻辑与底层引擎的入口,最近终于知道了.呵呵.通过这样的方法,就可以在上层逻辑做某些操作,然后关联这些逻辑相关的引擎代码. 今天一直在被单态困扰着,事情是这样的:大厅和战斗场景里面都有两个类似的chatroom,并且他们各自使用的协议是不一样的.现在想把他合并起来做成类似singleton的东西. 之前就遇到一个问题,大厅和战斗场景不能在相互之间发送信息,后来我的处理方法是将战斗场景里面添加大厅里面的响应事件,这样的话,在大厅里面发送私聊信息到战斗场景里面,就可以接受到了,但是后来发现在战斗场景里面发送信息到大厅里面,却接受不到,并且这个时候,在大厅和战斗场景里面已经存在很多冗余代码了,这样的处理让我感觉很不爽,我在想有没有其它办法,后来请教了老大,老大帮忙解释了一下,后来,在协议处理方式上面修改了一下,才可以的。chatroom在不同的时候发送不同的协议就好了,并且在接受的时候分开大厅和战斗场景处理就好了,这样还是用了接受、和发送这两段废代码。对于singleton的了解还是不够好。& 之前遇到的问题,是聊天发送消息并不立即显示在本地,而要先将信息转到服务端,服务端进行查询,如果能够找到这个私聊对象,那么就返回给信息,否则就显示说该用户不存在,在战斗场景里面向大厅的某个玩家发送私聊信息以后,退出战斗场景以后,发现大厅里面还显示着在战斗场景里面发送的聊天信息。这样即使我按照常规思路去把网络接受端的相关代码注释掉也不能达到消除大厅里面的聊天信息的目的,感觉很郁闷。后来查看私聊信息方面的代码,发现没有将信息有效地拦截,私聊信息在本地上面还可以被显示,没有经过网络方面的验证就直接发送过来了。在私聊信息方面做一些处理并且在退出战斗场景的时候做一些信息删除处理,这样就可以达到目的了。 因为玩家对象位置数据是从服务器那边发送过来的,玩家从服务器获得数据需要一段时间,所以需要加入一个插值,来将现在的位置过渡到下一个的位置.这里可以采用多种插值方法.今天写了代码去改写强制动作的处理,结果发现很多处是有问题的,其中原因是没有将原来的代码作用看仔细造成了,感到羞愧呢,另外在编写交互性比较强的代码时,一定要考虑自己的代码可能带来的影响。更新某个文件比较麻烦的话,那么可以先采用原始文件删除,并且重新全部更新的做法去做,而不是用更新某个字段的方法去做.如果没有初始化声音设备成功的话,那么应该可以弹出提示信息框,并且将原始声音音量设置为0.之前在修改一个bug(在人物控制面板打开以后,一直克隆object,造成了在引擎底层无法锁定vertexBuffer的问题),开始以为是内存泄露了,在打开控制面板10分钟以后,游戏就突然出错了,还一度想用一些辅助工具来查找内存的信息是否出错,后来发现在人物控制面板里面克隆了过多的人物object,而这些object却没有及时地删除,造成占用过多的资源,到最后连锁住vertex buffer也不行了.在分析这个问题上面的时候,我还是一个劲地挖底层而没有考虑太多的逻辑层面的东西,实在有点南辕北辙的味道.值得反省.在输入的使用上面,一般的游戏都采用directInput,即使是U2,上次遇到的问题是,在一同事机器上面运行输入的时候就进入不了,但是在别人的机器上面却可以运行好好的,后来经常查访发现:1)用配置文件写入的,之后再绑定到某个特定键的快捷键都不能用,因为这些是读入内存以后,然后用add_binding来绑定到directInput设备上面的,2) 在游戏里面使用windows message的却可以正常使用.进入游戏的时候,你不能输入,而只能回车,按tab键以后,就可以在登陆界面输入,如果不能按tab键,则不能输入,进入游戏以后却可以按不是从配置文件里面读取的信息,比如技能,人物面板,仓库,以及地图等.其中我个人建议是,尽量不要用directInput.1)首先是directInput依赖于机器,如果机器好的话,那么没事情,如果有事情的话,那么也很难解决,2)directInput里面采用了hook,来拦截消息,这样,还不如直接用windows message来的快?详细的讨论见上面.在调试逻辑没有发现什么错误提示的时候,试着去调试引擎,可能问题发生得更加深,不在逻辑层面上,而在引擎内部,这样就要直接调试引擎了.在涉及到渲染方面的bug,尽量借用d3ddebugging来辅助查错.这样可以方便解决问题.连接错误:IID_IDirectSound3DBuffer,其实加上dxguid.lib就好了。纹理寻址模式包括:wrap, border color, clamp,和mirror以及mirror once.&pDrawPrimInternal-&SetTexture(hTex);之前遇到的一个问题是,显示玩家在小地图上面到地图边界了,还能重复绘制地图,给人的感觉好像是走不到边界,走地图好像是在卷轴里面一样。后来才知道一般默认的纹理寻址模式是wrap方式。&get_device()-&SetSamplerState(0,D3DSAMP_BORDERCOLOR,0x00ffffff);&get_device()-&SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);&get_device()-&SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);解决bug有时候不如重写尽量让策划去管理逻辑,逻辑程序员尽量将重心放在具体技术问题上面,不懂的地方应该主动跟策划沟通,而不是自己想。代码可以先模拟出来,然后再放到具体的环境里面测试,独立写个demo之后再去测试,这样往往会比较快捷和省事情。学会模拟机器执行代码的次序,并且提高阅读代码的问题,之前的时候,我使劲去调试,每次调试只为了解决一个问题,但是事实上,如果从阅读代码开始的话,那么我可以省掉1天的时间。学会调节编写代码时候的心情和心态,这样有助于进行高效编程,当心情不好的时候,一定要集中全部的注意力,并且将思路和流程作出图记载在纸上面,这样可以强迫自己全神贯注。今天遇到的文件打开问题是文件名路径有空格造成的,值得指出的是对于文件打开报错,一般很难获得返回值信息,但是可以通过GetLastError或者@Err,以及hr等来获得一些错误返回值信息。对字符串操作,尽量要检查是否有空格,如果字符串长度前面有空格的话,那么将被认为所提供的字符串是空的。要避免这种情况的发生。对于字符串匹配要注意部分匹配的情况,比如"Tex", "Text",这里如果只匹配前面三个字符的话,那么两者是相等的,之前就遇到一个这样的问题,就是texture的信息被text信息所覆盖了,导致控件找不到正确的texture而不能显示出来。&今天遇到的问题是这样的,之前遇到的状态切换问题,是与状态切换无关,而与插值有关,在切换状态以后,收到一个插值位置,这样又给角色一个新的位置,给别人看的效果就是角色先落地了,之后又上升了,像坐电梯一样。不过从这里说明了一个问题:我在思考问题的时候,有欠周全的因素。今天跟踪一个bug,在战斗的时候,出现卡死的情况,后来发现状态切换出现了问题,后来一直去查看战斗方面的状态,但是还没有发现什么结果,现在在想在战斗中的标志或者状态的时候应该设立一些标志集合,这样便于在某个时候检查一些状态的信息。现在很多的标志在游戏里面,局部的,全局的,标志在角色上面的,标志在物体上面的,这些都需要好好地管理。全方面,多角度地思考问题,而不能将思维局限在某处.学会从大局或者小处去分析问题,大处不行的话,就小处,将相关的信息串起来.所有的信息应该是个串型或者链型的.之前在处理问题的时候,把思路限制在太小的范围内了.以至于花了很多时间才找到问题所在.根据正常情况和非正常情况来获得数据比较,以确定正确的流程和结构。如果遇到错误的乱值,那么就看看正常的数值,然后根据这个比较来获得一些提示信息。今天犯了错误,自己有最新版本,但是没有上传,结果vss上面的版本把自己的最新版本给覆盖了。在发送消息的时候,有时候为了防止频繁发送消息,要加入一个cd时间,防止因为网络问题,服务端收到玩家连续的信息。物理系统, v = v0 - gt. 玩家上跳的速度表示,而在下降,则是v = gt,按照自由落体运动来进行.并且速度是个向量,这样如果在X,Z轴上面有初速度的话,那么就可能出现抛物线的情况.

我要回帖

更多关于 maze gidle 的文章

 

随机推荐