我正在加载一个高度图并尝试将结果呈现为一系列 GL_POINTS,因为目前的代码有时会在我的屏幕中心呈现一个点(无论相机位于何处 - 我已经尝试展开进一步指出它们是否堆叠在一起)。尽可能最小化 Visual Studio 并再次最大化它可能会停止或开始渲染点。你会注意到我有这行:
glEnableClientState(GL_VERTEX_ARRAY);
注释掉 - 这是因为这条线将完全停止我的“地形”的所有渲染。我的渲染循环的其余部分纯粹包括设置 PROJECTION 和 MODELVIEW 矩阵并调用 clear() 和 swapbuffers() - (这一切都正常工作,因为我从一本书中获取信息并使用通用的多色三角形对其进行了测试) .
地形等级:
class Terrain
{
public:
Terrain(char* pFile){
if(!LoadTerrain(pFile))
{
OutputDebugString("Loading terain failed.\n");
}
};
~Terrain(){};
void Draw()
{
glPushMatrix();
//glEnableClientState(GL_VERTEX_ARRAY); // Uncommenting this causes me to see nothing at all
glBindBuffer(GL_ARRAY_BUFFER, mVBO);
glVertexPointer(3, GL_FLOAT, 0, 0);
GLenum a = glGetError(); // 1281
glPointSize(5.0f);
glDrawArrays(GL_POINTS, 0, mNumberPoints);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}
private:
GLuint mVBO;
int mWidth;
int mHeight;
int mNumberPoints;
bool LoadTerrain(char* pFile)
{
FILE* filePtr;
int error;
unsigned int count;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
int imageSize, i, j, k, index;
unsigned char* bitmapImage;
unsigned char height;
error = fopen_s(&filePtr, pFile, "rb");
if(error)
return false;
count = fread(&bfh, sizeof(BITMAPFILEHEADER), 1, filePtr);
if(count != 1)
return false;
count = fread(&bih, sizeof(BITMAPINFOHEADER), 1, filePtr);
if(count != 1)
return false;
mWidth = bih.biWidth;
mHeight = bih.biHeight;
mNumberPoints = mWidth * mHeight;
imageSize = mWidth * mHeight * 3; // 3 values * width * height = total data size
bitmapImage = new unsigned char[imageSize];
fseek(filePtr, bfh.bfOffBits, SEEK_SET);
count = fread(bitmapImage, 1, imageSize, filePtr);
if(count != imageSize)
return false;
error = fclose(filePtr);
if(error)
return false;
float* mapArray = new float[imageSize];
k = 0;
for(j = 0; j < mHeight; j++)
{
for(i = 0; i < mWidth; i++)
{
height = bitmapImage[k];
index = (mHeight * j) + i;
mapArray[k++] = 10*(float)i;
mapArray[k++] = (float)height;
mapArray[k++] = 10*(float)j;
/*OutputDebugString(convertInt(i).c_str());
OutputDebugString(",");
OutputDebugString(convertInt(height).c_str());
OutputDebugString(",");
OutputDebugString(convertInt(j).c_str());
OutputDebugString("\n");*/
}
}
// COPY MAP ARRAY INTO BUFFERS
glGenBuffers(1, &mVBO);
glBindBuffer(GL_ARRAY_BUFFER, mVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * imageSize, mapArray, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete [] bitmapImage;
bitmapImage = 0;
return true;
};
string convertInt(int number)
{
if (number == 0)
return "0";
string temp="";
string returnvalue="";
while (number>0)
{
temp+=number%10+48;
number/=10;
}
for (int i=0;i<temp.length();i++)
returnvalue+=temp[temp.length()-i-1];
return returnvalue;
}
};
注意:有些人可能会注意到这与我的上一个问题有关;但我的最后一个问题是正确回答的错误(并且我将其标记为这样),因此该线程没有受到太多关注。非常多的无意垃圾邮件。
编辑::我的渲染循环的其余部分::
// Set up projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1024.0/768.0, 1, 1000);
// Set up camera view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,20, -50,
0,0,0,
0,1,0);
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
编辑:我的更多代码:
主.CPP
#pragma once
#include <windows.h>
#include <gl/gl.h>
#include "Engine.h"
#include "Terrain.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL quit = FALSE;
float theta = 0.0f;
// register window class
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "PointCloudTerrainClass";
RegisterClass( &wc );
// create main window
hWnd = CreateWindow(
"PointCloudTerrainClass", "Point Cloud Terrain",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
0, 0, 1024, 768,
NULL, NULL, hInstance, NULL );
// enable OpenGL for the window
Engine mEngine = Engine(hWnd, &hDC, &hRC);
// Set shaders
glewInit();
Terrain t = Terrain("heightmap.bmp");
while ( !quit )
{
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if ( msg.message == WM_QUIT )
{
quit = TRUE;
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
// OpenGL STUFF
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45, 1024.0/768.0, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(cameraData[0],cameraData[1], cameraData[2],
// 0,0,0,
// 0,1,0);
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glUseProgram(program);
t.Draw();
// STOP RENDER STUFF
glFlush();
SwapBuffers( hDC );
}
}
mEngine.DisableOpenGL();
DestroyWindow( hWnd );
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
}
引擎.H:
#pragma once
#include <Windows.h>
#include <gl\GL.h>
#include <gl\GLU.h>
class Engine
{
public:
Engine(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
EnableOpenGL(hWnd, hDC, hRC);
}
~Engine()
{
}
void DisableOpenGL()
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( *mhRC );
ReleaseDC( mhWnd, *mhDC );
}
private:
HWND mhWnd;
HDC * mhDC;
HGLRC * mhRC;
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int format;
// get the device context (DC)
*hDC = GetDC( hWnd );
// set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( *hDC, &pfd );
SetPixelFormat( *hDC, format, &pfd );
// create and enable the render context (RC)
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
mhWnd = hWnd;
mhDC = hDC;
mhRC = hRC;
}
};