Я загружаю карту высот и пытаюсь отобразить результаты в виде серии 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);
РЕДАКТИРОВАТЬ: Еще больше моего кода:
main.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 );
}
}
Engine.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;
}
};
Задача ещё не решена.
Других решений пока нет …