我有一个用于读取.ply文件的opengl c ++代码。我想读取键盘箭头键(向上,向下,向右,向左)以在屏幕上移动一个点。我使用glutKeyboardFunc
函数,但我有一个错误:
Unhandled exception at 0x1000bb1e in opengl3.exe: 0xC0000005: Access violation reading location 0x00000070.
在这一行:
glutKeyboardFunc(keyPressed);
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <string>
#include <conio.h>
HWND hWnd;
HDC hDC;
HGLRC hRC;
// Set up pixel format for graphics initialization
void SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;
ppfd = &pfd;
ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_COLORINDEX;
ppfd->cColorBits = 16;
ppfd->cDepthBits = 16;
ppfd->cAccumBits = 0;
ppfd->cStencilBits = 0;
pixelformat = ChoosePixelFormat(hDC, ppfd);
SetPixelFormat(hDC, pixelformat, ppfd);
}
void InitGraphics()
{
hDC = GetDC(hWnd);
SetupPixelFormat();
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
glClearColor(0, 0, 0, 0.5);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
}
// Resize graphics to fit window
void ResizeGraphics()
{
// Get new window size
RECT rect;
int width, height;
GLfloat aspect;
GetClientRect(hWnd, &rect);
width = rect.right;
height = rect.bottom;
aspect = (GLfloat)width / height;
// Adjust graphics to window size
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, aspect, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// Draw frame
void DrawGraphics()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set location in front of camera
glLoadIdentity();
glTranslated(0, 0, -10);
// Draw a square
glBegin(GL_QUADS);
glColor3d(100, 200, 30);
/*
glVertex3d(-2, 2, 0);
glVertex3d(2, 2, 0);
glVertex3d(2, -2, 0);
glVertex3d(-2, -2, 0);
*/
//FILE * file = fopen("D:\\dart.ply","r");
FILE * file = fopen("mosalas.ply","r");
if (file!=NULL)
{
fseek(file,0,SEEK_END);
long fileSize = ftell(file);
float* Vertex_Buffer;
try
{
Vertex_Buffer = (float*) malloc (ftell(file));
}
catch (char* )
{
//return -1;
}
//if (Vertex_Buffer == NULL) return -1;
fseek(file,0,SEEK_SET);
//Faces_Triangles = (float*) malloc(fileSize*sizeof(float));
//Normals = (float*) malloc(fileSize*sizeof(float));
if (file)
{
int i = 0;
int temp = 0;
int quads_index = 0;
int triangle_index = 0;
int normal_index = 0;
char buffer[1000];
fgets(buffer,300,file); // ply
// READ HEADER
// -----------------
int TotalConnectedPoints;
// Find number of vertexes
while ( strncmp( "element vertex", buffer,strlen("element vertex")) != 0 )
{
fgets(buffer,300,file); // format
}
strcpy(buffer, buffer+strlen("element vertex"));
sscanf(buffer,"%i", &TotalConnectedPoints);
int TotalFaces;
// Find number of face
fseek(file,0,SEEK_SET);
while ( strncmp( "element face", buffer,strlen("element face")) != 0 )
{
fgets(buffer,300,file); // format
}
strcpy(buffer, buffer+strlen("element face"));
sscanf(buffer,"%i", &TotalFaces);
// go to end_header
while ( strncmp( "end_header", buffer,strlen("end_header")) != 0 )
{
fgets(buffer,300,file); // format
}
i =0;
float* ver0,ver1,ver2,ver3;
//char* key[100];
for (int iterator = 0; iterator < TotalConnectedPoints; iterator++)
{
fgets(buffer,300,file);
//sscanf(buffer,"%f %f %f", &Vertex_Buffer[i], &Vertex_Buffer[i+1], &Vertex_Buffer[i+2]);
sscanf(buffer,"%f %f %f", &ver1, &ver2, &ver3);
glNormal3f(ver1, ver2, ver3);
glVertex3d(ver1, ver2, ver3);
//glVertex3f(ver1, ver2, ver3);
i += 3;
}
}
}
glPushMatrix();
glBegin;
glTranslatef(-10,5,0);
glColor3f(1,1,1);
glRotatef(90,0,1,0);
glutSolidCone(0.25, 15, 20, 20);
glEnd();
glPopMatrix();
//glutMouseFunc(0,0,0);
/*
glVertex3d(1.000000, 1.000000, 6);
glVertex3d(3.000000, 0.000000, 4);
glVertex3d(0.000000, 0.000000, 4);
glVertex3d(0.000000, 3.000000, 4);
glVertex3d(1.500000, 0.500000, 0);*/
glEnd();
// Show the new scene
SwapBuffers(hDC);/**/
}
void keyPressed (unsigned char key, int x, int y) {
}
// Handle window events and messages
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
ResizeGraphics();
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
// Default event handler
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
return 1;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const LPCWSTR appname = TEXT("OpenGL Sample");
WNDCLASS wndclass;
MSG msg;
// Define the window class
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, appname);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszMenuName = appname;
wndclass.lpszClassName = appname;
// Register the window class
if (!RegisterClass(&wndclass)) return FALSE;
// Create the window
hWnd = CreateWindow(
appname,
appname,
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd) return FALSE;
// Initialize OpenGL
InitGraphics();
// Display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
DrawGraphics();
// Event loop
int key;
int asgh = 0;
POINT pt;
/**/while (1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (!GetMessage(&msg, NULL, 0, 0))
return TRUE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
glutKeyboardFunc(keyPressed);
DrawGraphics();
}
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
}
答案 0 :(得分:3)
您发布的程序没有拨打glutInit()
。
此外,您正在进行所有特定于平台的窗口管理和上下文创建,而GLUT应该是抽象的。
底线:如果您想使用GLUT,请使用GLUT。如果要使用Win32,请使用Win32。不要试图混合搭配。