您好我目前正在使用c ++和opengl进行一个非常简单的游戏,但不知道我的程序的哪个部分在Windows XP和8中出错。它在我的Windows 7中工作得很好。
编辑由visual studio 6.0完成。在大多数情况下,我在mingw中使用GCC但是我发现使用GCC编译的那个在处理opengl时在屏幕上不断出现一些意外的白色眼泪(如撕裂/撕裂/撕裂)。
无论如何,这个程序在Windows 7中运行没有任何问题。我对malloc / free的担心有点担心,但就目前而言,它表现得非常好。
我在windows xp和8.1中使用我朋友的计算机测试了这个程序,发现两者都运行不正常。我在xp计算机上安装了另一个visual studio 6.0并运行调试。令人惊讶的是,虽然win7中的visual studio没有,但xp vs6.0告诉我XXXX.exe中的未处理异常(OPENGL32.DLL):0xC0000005:Acces Violation',反汇编代码如下:(错误是黄色箭头指向的地方)
5E66E683 push dword ptr [ebp+0Ch]
5E66E686 mov dword ptr [esi+18F8h],eax
5E66E68C mov ecx,dword ptr [ebx+24h]
5E66E68F mov eax,dword ptr [edi+24h]
5E66E692 mov edx,ecx
5E66E694 sub edx,eax
err: 5E66E696 mov eax,dword ptr [edx*4+5E6DC820h]
5E66E69D or eax,80000000h
5E66E6A2 mov dword ptr [ebp-10h],eax
5E66E6A5 mov eax,dword ptr [ebp+0Ch]
5E66E6A8 mov eax,dword ptr [eax+24h]
5E66E6AB mov edx,eax
5E66E6AD sub eax,dword ptr [edi+24h]
5E66E6B0 sub edx,ecx
5E66E6B2 mov edx,dword ptr [edx*4+5E6DC820h]
5E66E6B9 mov eax,dword ptr [eax*4+5E6DC820h]
5E66E6C0 mov ecx,80000000h
5E66E6C5 or edx,ecx
5E66E6C7 or eax,ecx
5E66E6C9 mov dword ptr [ebp-14h],edx
5E66E6CC push ebx
不幸的是,我对汇编语言并不了解,当我阅读它时,我的代码仍然显得很好......但它确实会导致错误,所以我不得不在这里寻求帮助。
你可以在这里看到整个cpp源
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <list>
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
using namespace std;
#define DELAY 1
#define TOP 0
#define BOTTOM 1
#define RIGHT 2
#define LEFT 3
#define X0Y1 0
#define XHY1 1
#define X1Y1 2
#define X1YH 3
#define X1Y0 4
#define PLUS 1
#define MINUS -1
void display();
void add(int n);
GLdouble *aniData();
void move();
void arrowPress(int key, int x, int y);
void arrowUp(int key, int x, int y);
bool upDownPress(), rightLeftPress();
GLdouble dRand(GLdouble min, GLdouble max);
int iRand(int min, int max);
const GLdouble unit = 1.0 / 256.0, sideLen = 1.0 / 32.0, maxAttack = 1.0 / 8.0;
const int maxMove = (int)(maxAttack + 2.0) / unit + 5;
GLdouble x = -sideLen / 2.0, y = -sideLen / 2.0;
GLboolean upPress = GL_FALSE, downPress = GL_FALSE, rightPress = GL_FALSE, leftPress = GL_FALSE;
list<GLdouble *> dList;
list<GLdouble *>::iterator it;
unsigned k = -8, attacks = 0;
struct attacker {
GLdouble width, height, ax, ay;
int side, slope, xSign, ySign;
void init()
{
width = dRand(unit, maxAttack);
height = dRand(unit, maxAttack);
side = iRand(0, 3);
bool fromOtherSide = false;
switch (side) {
case TOP:
topI:
ax = dRand(-1.0 - unit, 1.0 - width + unit);
ay = 1.0 + unit;
if (!fromOtherSide) {
slope = iRand(0, 4);
if (slope == X1Y0) {
if (iRand(0, 1) == 0)
goto rightI;
goto leftI;
}
}
xSign = 2 * (rand() % 2) - 1;
ySign = MINUS;
break;
case BOTTOM:
bottomI:
ax = dRand(-1.0 - unit, 1.0 - width + unit);
ay = -1.0 - height - unit;
if (!fromOtherSide) {
slope = iRand(0, 4);
if (slope == X1Y0) {
if (iRand(0, 1) == 0)
goto rightI;
goto leftI;
}
}
xSign = 2 * (rand() % 2) - 1;
ySign = PLUS;
break;
case RIGHT:
rightI:
ax = 1.0 + unit;
ay = dRand(-1.0 - unit, 1.0 - height + unit);
if (!fromOtherSide) {
slope = iRand(0, 4);
if (slope == X0Y1) {
if (iRand(0, 1) == 0)
goto topI;
goto bottomI;
}
}
xSign = MINUS;
ySign = 2 * (rand() % 2) - 1;
break;
case LEFT:
leftI:
ax = -1.0 - width - unit;
ay = dRand(-1.0 - unit, 1.0 - height + unit);
if (!fromOtherSide) {
slope = iRand(0, 4);
if (slope == X0Y1) {
if (iRand(0, 1) == 0)
goto topI;
goto bottomI;
}
}
xSign = PLUS;
ySign = 2 * (rand() % 2) - 1;
break;
}
}
};
struct attacker *makeAttacker()
{
return (struct attacker *)malloc(sizeof(struct attacker));
}
int main()
{
srand((unsigned)time(NULL));
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(200, 100);
glutCreateWindow("¿?¿?¿?¿?¿?¿? 1.0");
glutDisplayFunc(display);
glutSpecialFunc(arrowPress);
glutSpecialUpFunc(arrowUp);
glutIdleFunc(move);
glClearColor(0.0, 0.0, 0.0, 0.0);
glutMainLoop();
return 0;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3d(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2d(x, y);
glVertex2d(x, y + sideLen);
glVertex2d(x + sideLen, y + sideLen);
glVertex2d(x + sideLen, y);
glEnd();
if (k == 8 * maxMove) {
k = -8;
for (int i = 0; i < attacks; ++i) {
free(*dList.begin());
dList.erase(dList.begin());
}
++attacks;
add(attacks);
}
k += 8;
it = dList.begin();
glColor3d(1.0, 0.0, 1.0);
for (int i = 0; i < attacks; ++i) {
glBegin(GL_POLYGON);
glVertex2d((*it)[k], (*it)[k + 1]);
glVertex2d((*it)[k + 2], (*it)[k + 3]);
glVertex2d((*it)[k + 4], (*it)[k + 5]);
glVertex2d((*it)[k + 6], (*it)[k + 7]);
glEnd();
it++;
}
glutSwapBuffers();
}
void add(int n)
{
for (int i = 0; i < n; ++i)
dList.push_back(aniData());
}
GLdouble *aniData()
{
GLdouble *d = (GLdouble *)malloc(8 * maxMove * sizeof(GLdouble));
struct attacker *sample = makeAttacker();
sample->init();
GLdouble sx = sample->ax, sy = sample->ay;
int i, signX = sample->xSign, signY = sample->ySign;
switch (sample->slope) {
case X0Y1:
for (i = 0; i < 8 * maxMove; i += 8) {
sy += unit * signY;
d[i] = sx;
d[i + 1] = sy;
d[i + 2] = sx;
d[i + 3] = sy + sample->height;
d[i + 4] = sx + sample->width;
d[i + 5] = sy + sample->height;
d[i + 6] = sx + sample->width;
d[i + 7] = sy;
}
break;
case XHY1:
for (i = 0; i < 8 * maxMove; i += 8) {
sx += unit * 0.5 * signX;
sy += unit * signY;
d[i] = sx;
d[i + 1] = sy;
d[i + 2] = sx;
d[i + 3] = sy + sample->height;
d[i + 4] = sx + sample->width;
d[i + 5] = sy + sample->height;
d[i + 6] = sx + sample->width;
d[i + 7] = sy;
}
break;
case X1Y1:
for (i = 0; i < 8 * maxMove; i += 8) {
sx += unit * signX;
sy += unit * signY;
d[i] = sx;
d[i + 1] = sy;
d[i + 2] = sx;
d[i + 3] = sy + sample->height;
d[i + 4] = sx + sample->width;
d[i + 5] = sy + sample->height;
d[i + 6] = sx + sample->width;
d[i + 7] = sy;
}
break;
case X1YH:
for (i = 0; i < 8 * maxMove; i += 8) {
sx += unit * signX;
sy += unit * 0.5 * signY;
d[i] = sx;
d[i + 1] = sy;
d[i + 2] = sx;
d[i + 3] = sy + sample->height;
d[i + 4] = sx + sample->width;
d[i + 5] = sy + sample->height;
d[i + 6] = sx + sample->width;
d[i + 7] = sy;
}
break;
case X1Y0:
for (i = 0; i < 8 * maxMove; i += 8) {
sx += unit * signX;
d[i] = sx;
d[i + 1] = sy;
d[i + 2] = sx;
d[i + 3] = sy + sample->height;
d[i + 4] = sx + sample->width;
d[i + 5] = sy + sample->height;
d[i + 6] = sx + sample->width;
d[i + 7] = sy;
}
break;
}
free(sample);
return d;
}
void move()
{
if (!upDownPress()) {
if (upPress == GL_TRUE && y + sideLen <= 1.0)
y += 2 * unit;
else if (downPress == GL_TRUE && y >= -1.0)
y -= 2 * unit;
}
if (!rightLeftPress()) {
if (rightPress == GL_TRUE && x + sideLen <= 1.0)
x += 2 * unit;
else if (leftPress == GL_TRUE && x >= -1.0)
x -= 2 * unit;
}
glutPostRedisplay();
Sleep(DELAY);
}
void arrowPress(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP:
upPress = GL_TRUE;
break;
case GLUT_KEY_DOWN:
downPress = GL_TRUE;
break;
case GLUT_KEY_RIGHT:
rightPress = GL_TRUE;
break;
case GLUT_KEY_LEFT:
leftPress = GL_TRUE;
break;
}
}
void arrowUp(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP:
upPress = GL_FALSE;
break;
case GLUT_KEY_DOWN:
downPress = GL_FALSE;
break;
case GLUT_KEY_RIGHT:
rightPress = GL_FALSE;
break;
case GLUT_KEY_LEFT:
leftPress = GL_FALSE;
break;
}
}
bool upDownPress()
{
if (upPress == GL_TRUE && downPress == GL_TRUE)
return true;
return false;
}
bool rightLeftPress()
{
if (rightPress == GL_TRUE && leftPress == GL_TRUE)
return true;
return false;
}
GLdouble dRand(GLdouble min, GLdouble max)
{
return ((GLdouble)rand() / (GLdouble)RAND_MAX) * (max - min) + min;
}
int iRand(int min, int max)
{
return rand() % (max + 1 - min) + min;
}
该程序的结构是,结构攻击者&#39;中的函数init()。制作随机正方形的四个顶点的信息。 makeAttacker()执行&#39; struct attacker *&#39;的malloc()。并将内存地址发送到aniData(),其中存储在&#struct; struct attacker * sample&#39;中。 aniData()生成一个数组,其中包含随机方块未来线性运动的所有信息。 &#39; struct attacker * sample&#39;最后被释放。
另一部分只是处理键盘输入和两个功能,以便更容易制作随机数。
我因为sleep()而使用了windows.h。我相信你也可以通过将window.h更改为unistd.h来编译代码而没有任何问题。
我真的希望这个问题得到解决。我今天花了整整一天试图在我的代码中找到问题。任何帮助都将不胜感激。
修改 我已经阅读了回复,我不确定这是否是我需要的,但我发现了一个名为&#39; call stack&#39;
的窗口-> OPENGL32! 5e66e696()
OPENGL32! 5e6c1399()
OPENGL32! 5e6bd671()
OPENGL32! 5e6bd74a()
OPENGL32! 5e6ac7fc()
OPENGL32! 5e6ae640()
OPENGL32! 5e6cd115()
OPENGL32! 5e64c5c0()
GDI32! 77e56443()
GLUT32! 10009e55()
display() line 171
GLUT32! 100050c2()
GLUT32! 100048d6()
main() line 137
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c7e7077()
我逐行运行调试器,程序在执行glutMainLoop()时完全停止。然后调试器向我显示反汇编的opengl32库。在这里,我打开了“调用堆栈”#39;如上所述
答案 0 :(得分:0)
一切都解决了!
谢谢大家的回答。
特别有用的建议是我应该使用向量而不是原始指针来进行更安全的内存分配。这个简单游戏的完整代码如下。嵌套的lambda函数c ++ 11非常有助于删除代码的一些重复部分。
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <list>
#include <vector>
#include "glut.h"
using namespace std;
#define TOP 0
#define BOTTOM 1
#define RIGHT 2
#define LEFT 3
#define X0Y1 0
#define XHY1 1
#define X1Y1 2
#define X1YH 3
#define X1Y0 4
#define PLUS 1
#define MINUS -1
void display();
vector<double> aniData();
void move();
void arrowPress(int key, int x, int y);
void arrowUp(int key, int x, int y);
bool upDownPress(), rightLeftPress();
double dRand(double min, double max);
int iRand(int min, int max);
const double unit = 1.0 / 1280.0, sideLen = 1.0 / 32.0, maxAttack = 1.0 / 8.0;
const int maxMove = (int)((maxAttack + 2.0) / unit) + 5;
double mvx1 = -sideLen / 2.0, mvy1 = -sideLen / 2.0, mvx2, mvy2, mvx3, mvy3, mvx4, mvy4, avx1, avy1, avx2, avy2, avx3, avy3, avx4, avy4;
GLboolean upPress = GL_FALSE, downPress = GL_FALSE, rightPress = GL_FALSE, leftPress = GL_FALSE;
list<vector<double>> dList;
list<vector<double>>::iterator it;
vector<double>::iterator vit;
int k = -8, attacks = 0;
class Attacker{
public:
double width, height, ax, ay;
int side, slope, xSign, ySign;
Attacker(){
width = dRand(maxAttack / 8.0, maxAttack);
height = dRand(maxAttack / 8.0, maxAttack);
side = iRand(0, 3);
bool fromOtherSide = false;
switch (side){
case TOP:
topI :
ax = dRand(-1.0 - unit, 1.0 - width + unit);
ay = 1.0 + unit;
if (!fromOtherSide){
slope = iRand(0, 4);
if (slope == X1Y0){
if (iRand(0, 1) == 0){
goto rightI;
}
goto leftI;
}
}
xSign = 2 * (rand() % 2) - 1;
ySign = MINUS;
break;
case BOTTOM:
bottomI :
ax = dRand(-1.0 - unit, 1.0 - width + unit);
ay = -1.0 - height - unit;
if (!fromOtherSide){
slope = iRand(0, 4);
if (slope == X1Y0){
if (iRand(0, 1) == 0){
goto rightI;
}
goto leftI;
}
}
xSign = 2 * (rand() % 2) - 1;
ySign = PLUS;
break;
case RIGHT:
rightI :
ax = 1.0 + unit;
ay = dRand(-1.0 - unit, 1.0 - height + unit);
if (!fromOtherSide){
slope = iRand(0, 4);
if (slope == X0Y1){
if (iRand(0, 1) == 0){
goto topI;
}
goto bottomI;
}
}
xSign = MINUS;
ySign = 2 * (rand() % 2) - 1;
break;
case LEFT:
leftI :
ax = -1.0 - width - unit;
ay = dRand(-1.0 - unit, 1.0 - height + unit);
if (!fromOtherSide){
slope = iRand(0, 4);
if (slope == X0Y1){
if (iRand(0, 1) == 0){
goto topI;
}
goto bottomI;
}
}
xSign = PLUS;
ySign = 2 * (rand() % 2) - 1;
break;
}
}
};
int main(){
srand((unsigned)time(NULL));
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 650);
glutInitWindowPosition(0, 0);
glutCreateWindow("닷지비스한거 1.0");
glutDisplayFunc(display);
glutSpecialFunc(arrowPress);
glutSpecialUpFunc(arrowUp);
glutIdleFunc(move);
glClearColor(0.0, 0.0, 0.0, 0.0);
glutMainLoop();
return 0;
}
void display(){
glClear(GL_COLOR_BUFFER_BIT);
glColor3d(0.0, 1.0, 0.0);
mvx2 = mvx1;
mvy2 = mvy1 + sideLen;
mvx3 = mvx1 + sideLen;
mvy3 = mvy1 + sideLen;
mvx4 = mvx1 + sideLen;
mvy4 = mvy1;
glBegin(GL_POLYGON);
glVertex2d(mvx1, mvy1);
glVertex2d(mvx2, mvy2);
glVertex2d(mvx3, mvy3);
glVertex2d(mvx4, mvy4);
glEnd();
if (k >= 8 * maxMove){
k = 0;
for (int i = 0; i < attacks; ++i){
dList.erase(dList.begin());
}
++attacks;
for (int i = 0; i < attacks; ++i){
dList.push_back(aniData());
}
}
it = dList.begin();
glColor3d(1.0, 0.0, 1.0);
for (int i = 0; i < attacks; ++i){
vit = it->begin();
avx1 = *(vit + k);
avy1 = *(vit + k + 1);
avx2 = *(vit + k + 2);
avy2 = *(vit + k + 3);
avx3 = *(vit + k + 4);
avy3 = *(vit + k + 5);
avx4 = *(vit + k + 6);
avy4 = *(vit + k + 7);
glBegin(GL_POLYGON);
glVertex2d(avx1, avy1);
glVertex2d(avx2, avy2);
glVertex2d(avx3, avy3);
glVertex2d(avx4, avy4);
glEnd();
it++;
if ((mvx1 >= avx1 && mvx1 <= avx3 && mvy1 >= avy1 && mvy1 <= avy3)
|| (mvx2 >= avx1 && mvx2 <= avx3 && mvy2 >= avy1 && mvy2 <= avy3)
|| (mvx3 >= avx1 && mvx3 <= avx3 && mvy3 >= avy1 && mvy3 <= avy3)
|| (mvx4 >= avx1 && mvx4 <= avx3 && mvy4 >= avy1 && mvy4 <= avy3)
|| (avx1 >= mvx1 && avx1 <= mvx3 && avy1 >= mvy1 && avy1 <= mvy3)
|| (avx2 >= mvx1 && avx2 <= mvx3 && avy2 >= mvy1 && avy2 <= mvy3)
|| (avx3 >= mvx1 && avx3 <= mvx3 && avy3 >= mvy1 && avy3 <= mvy3)
|| (avx4 >= mvx1 && avx4 <= mvx3 && avy4 >= mvy1 && avy4 <= mvy3)){
exit(0);
}
}
k += 8;
glutSwapBuffers();
}
vector<double> aniData(){
vector<double> v;
Attacker sample;
double sx = sample.ax, sy = sample.ay, sh = sample.height, sw = sample.width;
int i, signX = sample.xSign, signY = sample.ySign;
auto arrange = [&]{
v.push_back(sx);
v.push_back(sy);
v.push_back(sx);
v.push_back(sy + sh);
v.push_back(sx + sw);
v.push_back(sy + sh);
v.push_back(sx + sw);
v.push_back(sy);
};
switch (sample.slope){
case X0Y1:
for (i = 0; i < maxMove; ++i){
sy += (double)(unit*signY);
arrange();
}
break;
case XHY1:
for (i = 0; i < maxMove; ++i){
sx += 0.5*(double)(unit*signX);
sy += (double)(unit*signY);
arrange();
}
break;
case X1Y1:
for (i = 0; i < maxMove; ++i){
sx += (double)(unit*signX);
sy += (double)(unit*signY);
arrange();
}
break;
case X1YH:
for (i = 0; i < maxMove; ++i){
sx += (double)(unit*signX);
sy += 0.5*(double)(unit*signY);
arrange();
}
break;
case X1Y0:
for (i = 0; i < maxMove; ++i){
sx += (double)(unit*signX);
arrange();
}
break;
}
return v;
}
void move(){
if (!upDownPress()){
if (upPress == GL_TRUE && mvy1 + sideLen <= 1.0){
mvy1 += 0.8 * unit;
}
else if (downPress == GL_TRUE && mvy1 >= -1.0){
mvy1 -= 0.8 * unit;
}
}
if (!rightLeftPress()){
if (rightPress == GL_TRUE && mvx1 + sideLen <= 1.0){
mvx1 += 0.8 * unit;
}
else if (leftPress == GL_TRUE && mvx1 >= -1.0){
mvx1 -= 0.8 * unit;
}
}
glutPostRedisplay();
}
void arrowPress(int key, int x, int y){
switch (key){
case GLUT_KEY_UP:
upPress = GL_TRUE;
break;
case GLUT_KEY_DOWN:
downPress = GL_TRUE;
break;
case GLUT_KEY_RIGHT:
rightPress = GL_TRUE;
break;
case GLUT_KEY_LEFT:
leftPress = GL_TRUE;
break;
}
}
void arrowUp(int key, int x, int y){
switch (key){
case GLUT_KEY_UP:
upPress = GL_FALSE;
break;
case GLUT_KEY_DOWN:
downPress = GL_FALSE;
break;
case GLUT_KEY_RIGHT:
rightPress = GL_FALSE;
break;
case GLUT_KEY_LEFT:
leftPress = GL_FALSE;
break;
}
}
bool upDownPress(){
if (upPress == GL_TRUE && downPress == GL_TRUE){
return true;
}
return false;
}
bool rightLeftPress(){
if (rightPress == GL_TRUE && leftPress == GL_TRUE){
return true;
}
return false;
}
double dRand(double min, double max){
return ((double)rand() / (double)RAND_MAX)*(max - min) + min;
}
int iRand(int min, int max){
return rand() % (max + 1 - min) + min;
}