I am learning opengl for the first time, and i am trying to make a simple program. My program runs in two threads, one thread renders the program on the screen, while the other thread updates the data of the program. However, sometimes when i try to close my program i get a nasty error message. I don't understand why, although i feel like it is a concurrency error. Here is my code.
Main.cpp
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#define GLX_GLXEXT_LEGACY
#include <windows.h>
#include "glwindow.h"
#include "example.h"
#include "util.h"
void updateThread(Example* example);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
{
const int windowWidth = 1024;
const int windowHeight = 768;
const int windowBPP = 16;
const int windowFullscreen = false;
GLWindow programWindow(hInstance);
Example example;
programWindow.attachExample(&example);
if (!programWindow.create(windowWidth, windowHeight, windowBPP, windowFullscreen))
{
MessageBox(NULL, "Unable to create the OpenGL Window", "An error occurred", MB_ICONERROR | MB_OK);
programWindow.destroy();
return 1;
}
if (!example.init())
{
MessageBox(NULL, "Could not initialize the application", "An error occurred", MB_ICONERROR | MB_OK);
programWindow.destroy();
return 1;
}
HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) updateThread, &example, 0, 0);
example.setThread(&thread);
while(programWindow.isRunning())
{
programWindow.processEvents();
example.render();
programWindow.swapBuffers();
}
example.shutdown();
programWindow.destroy();
return 0;
}
void updateThread(Example* example)
{
setFPS(2000);
while(true)
{
example->update();
sync();
}
}
Util.cpp
#include "util.h"
int fps;
long timeThen;
void sync()
{
while(fps == 0);
long gapTo = 1000 / fps + timeThen;
long timeNow = time(nullptr);
while (gapTo > timeNow)
{
timeNow = time(nullptr);
}
timeThen = timeNow;
}
void setFPS(int FPS)
{
fps = FPS;
}
glwindow.cpp
#include <ctime>
#include <iostream>
#include <windows.h>
#include <GL/gl.h>
#include "wglext.h"
#include "glwindow.h"
#include "example.h"
typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int*);
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
GLWindow::GLWindow(HINSTANCE hInstance):
m_isRunning(false),
m_example(NULL),
m_hinstance(hInstance),
m_lastTime(0)
{
}
bool GLWindow::create(int width, int height, int bpp, bool fullscreen)
{
DWORD dwExStyle;
DWORD dwStyle;
m_isFullscreen = fullscreen;
m_windowRect.left = (long)0;
m_windowRect.right = (long)width;
m_windowRect.top = (long)0;
m_windowRect.bottom = (long)height;
m_windowClass.cbSize = sizeof(WNDCLASSEX);
m_windowClass.style = CS_HREDRAW | CS_VREDRAW;
m_windowClass.lpfnWndProc = GLWindow::StaticWndProc;
m_windowClass.cbClsExtra = 0;
m_windowClass.cbWndExtra = 0;
m_windowClass.hInstance = m_hinstance;
m_windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
m_windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
m_windowClass.hbrBackground = NULL;
m_windowClass.lpszMenuName = NULL;
m_windowClass.lpszClassName = "GLClass";
m_windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
if(!RegisterClassEx(&m_windowClass))
{
return false;
}
if(m_isFullscreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bpp;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
MessageBox(NULL, "Display mode failed", NULL, MB_OK);
m_isFullscreen = false;
}
}
if (m_isFullscreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
ShowCursor(false);
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
}
AdjustWindowRectEx(&m_windowRect, dwStyle, false, dwExStyle);
m_hwnd = CreateWindowEx(NULL, "GLClass", "BOGLGP - Chapter 2 - Simple OpenGL Application", dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, m_windowRect.right - m_windowRect.left, m_windowRect.bottom - m_windowRect.top, NULL, NULL, m_hinstance, this);
if (!m_hwnd)
{
MessageBox(NULL, "Window Creation Failed", NULL, MB_OK);
return 1;
}
m_hdc = GetDC(m_hwnd);
ShowWindow(m_hwnd, SW_SHOW);
UpdateWindow(m_hwnd);
m_lastTime = GetTickCount() / 1000.0f;
return true;
}
void GLWindow::destroy()
{
if (m_isFullscreen)
{
ChangeDisplaySettings(NULL, 0);
ShowCursor(true);
}
}
void GLWindow::attachExample(Example* example)
{
m_example = example;
}
bool GLWindow::isRunning()
{
return m_isRunning;
}
void GLWindow::processEvents()
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void GLWindow::setupPixelFormat(void)
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_SUPPORT_OPENGL |
PFD_DRAW_TO_WINDOW |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0,
};
pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
SetPixelFormat(m_hdc, pixelFormat, &pfd);
}
LRESULT GLWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
m_hdc = GetDC(hWnd);
setupPixelFormat();
int attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 0,
0};
HGLRC tmpContext = wglCreateContext(m_hdc);
wglMakeCurrent(m_hdc, tmpContext);
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
if (!wglCreateContextAttribsARB)
{
MessageBox(NULL, "Open GL 3.0 Is Not Supported", NULL, MB_OK);
m_hglrc = tmpContext;
DestroyWindow(hWnd);
return 0;
}
else
{
m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribs);
wglDeleteContext(tmpContext);
}
wglMakeCurrent(m_hdc, m_hglrc);
m_isRunning = true;
}
break;
case WM_DESTROY:
case WM_CLOSE:
wglMakeCurrent(m_hdc, NULL);
wglDeleteContext(m_hglrc);
m_isRunning = false;
PostQuitMessage(0);
return 0;
break;
case WM_SIZE:
{
int height = HIWORD(lParam);
int width = LOWORD(lParam);
getAttachedExample()->onResize(width, height);
}
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
DestroyWindow(m_hwnd);
}
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK GLWindow::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
GLWindow* window = NULL;
if(uMsg == WM_CREATE)
{
window = (GLWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)window);
}
else
{
window = (GLWindow*)GetWindowLongPtr(hWnd, GWL_USERDATA);
if(!window)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
return window->WndProc(hWnd, uMsg, wParam, lParam);
}
float GLWindow::getElapsedSeconds()
{
float currentTime = float(GetTickCount()) / 1000.0f;
float seconds = float(currentTime - m_lastTime);
m_lastTime = currentTime;
return seconds;
}
example.cpp
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "example.h"
Example::Example()
{
m_rotationAngle = 0.0f;
}
bool Example::init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
return true;
}
void Example::update()
{
const float SPEED = 15.0f;
m_rotationAngle += SPEED;
if (m_rotationAngle > 360.0f)
{
m_rotationAngle -= 360.0f;
}
}
void Example::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(m_rotationAngle, 0, 0, 1);
glBegin(GL_TRIANGLES);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -0.5f, -4.0f);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -0.5f, -4.0f);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.5f, -4.0f);
glEnd();
}
void Example::shutdown()
{
TerminateThread(thread, 0);
}
void Example::onResize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, float(width) / float(height), 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
EDIT
I am convinced that my problem is in the threading with example.cpp and main.cpp however i included all of the code to give more context to the situation.
Here is the error i get.
I don't see how your thread can exit cleanly.
In your while loop you should have something like
while (true) {
...
if (IShouldExit()) break;
}
That can be something simple like a bool or similar.
Then in your main you can set the flag then simply join with your thread, to give it time to exit cleanly.
Related
When I call GLClear without swapping the buffer, it is causing memory leak.
I am not sure if this is a driver issue or if I am doing something wrong.
If anyone can give it a try or have any idea, please tell me.
TL;DR, this is the code summarized. You can find all the code after this block
static bool CloseFlag = false;
LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
switch(uMsg)
{
case WM_SIZE:
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
//Handle input....
return 0;
case WM_CLOSE:
CloseFlag = true;
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
HWND CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
//Create window (with double buffer) and register it...
}
int main ()
{
hWnd = CreateOpenGLWindow("minimal", 0, 0, 256, 256, PFD_TYPE_RGBA, 0);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
gladLoadWGL(hDC)
gladLoadGL()
ShowWindow(hWnd, SW_SHOW);
while(!CloseFlag)
{
//Handles input
while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
glClear(GL_COLOR_BUFFER_BIT);
}
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
return 0;
}
Here's a minimum code for reproducing it that uses Win32.
#ifndef UNICODE
#define UNICODE
#define _UNICODE
#endif
#include <windows.h> /* must include this before GL/gl.h */
#include "glad/glad.h"
#include "glad/glad_wgl.h"
#include "wglext.h"
#include <string>
static bool CloseFlag = false;
void display(HDC hDC)
{
/* rotate a triangle around */
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2i(0, 1);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2i(-1, -1);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2i(1, -1);
glEnd();
glFlush();
SwapBuffers(hDC);
}
void JustClear()
{
glClear(GL_COLOR_BUFFER_BIT);
}
LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
switch(uMsg)
{
case WM_SIZE:
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam)
{
case 27: /* ESC key */
//PostQuitMessage(0);
CloseFlag = true;
break;
}
return 0;
case WM_CLOSE:
CloseFlag = true;
//PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
HWND CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int pf;
HDC hDC;
HWND hWnd;
WNDCLASS wc;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;
/* only register the window class once - use hInstance as a flag. */
if (!hInstance) {
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"OpenGL";
if (!RegisterClass(&wc)) {
return NULL;
}
}
std::wstring className = L"OpenGL";
hWnd = CreateWindow(className.c_str(), className.c_str(), WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);
if (hWnd == NULL) {
return NULL;
}
hDC = GetDC(hWnd);
/* there is no guarantee that the contents of the stack that become
the pfd are zeroed, therefore _make sure_ to clear these bits. */
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | flags;
pfd.iPixelType = type;
pfd.cColorBits = 32;
pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0) {
return 0;
}
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
return 0;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
ReleaseDC(hWnd, hDC);
return hWnd;
}
int main ()
{
HDC hDC; /* device context */
HGLRC hRC; /* opengl context */
HWND hWnd; /* window */
MSG msg; /* message */
hWnd = CreateOpenGLWindow("minimal", 0, 0, 256, 256, PFD_TYPE_RGBA, 0);
if (hWnd == NULL)
exit(1);
hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
if(!gladLoadWGL(hDC))
{
return -1;
}
if (!gladLoadGL()) //Load Glad
{
return -1;
}
ShowWindow(hWnd, SW_SHOW);
while(!CloseFlag)
{
//Handles input
while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//Render
//display(hDC);
JustClear();
}
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
return 0;
}
wglext.h is from here
Here's the OpenGL glad config
/*
OpenGL loader generated by glad 0.1.36 on Fri Oct 28 11:12:34 2022.
Language/Generator: C/C++
Specification: gl
APIs: gl=3.3
Profile: compatibility
Extensions:
Loader: True
Local files: False
Omit khrplatform: False
Reproducible: False
Commandline:
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions=""
Online:
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3
*/
and Glad wgl 1.0 with all the extensions
and here's the CMake I used
cmake_minimum_required(VERSION 3.14)
set (CMAKE_CXX_STANDARD 11)
# For Clang to do parsing
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# set the project name
project(Example)
add_executable(EXAMPLE_EXE ${CMAKE_CURRENT_LIST_DIR}/Src/main.cpp)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/External/glad_v0.1.36")
find_package(OpenGL REQUIRED)
target_include_directories(EXAMPLE_EXE PUBLIC "${CMAKE_CURRENT_LIST_DIR}/External/wglExt")
target_link_libraries(EXAMPLE_EXE PUBLIC OpenGL::GL glad)
I created a program. When I run it, a window with a gray background, and must create a yellow background with a triangle. What is the problem?
I have been programming based on the book "Gornakova - DirectX programming Lessons"
#include <windows.h>
#include <d3d9.h>
LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVershin = NULL;
struct CUSTOMVERTEX
{
FLOAT x,y,z,rhw;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
HRESULT InitialBufferVershin()
{
CUSTOMVERTEX Vershin[] =
{
{300.0f, 300.0f, 0.5f, 1.0f, 0x00000fff, },
{150.0f, 300.0f, 0.5f, 1.0f, 0x00000fff, },
{150.0f, 150.0f, 0.5f, 1.0f, 0x00000fff, },
};
if(FAILED(pDirect3DDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &pBufferVershin, NULL)))
return E_FAIL;
VOID* pBV;
if(FAILED(pBufferVershin->Lock(0, sizeof(Vershin), (void**)&pBV, 0)))
return E_FAIL;
memcpy(pBV, Vershin, sizeof(Vershin));
pBufferVershin->Unlock();
return S_OK;
}
void DeleteDirect3D()
{
if(pBufferVershin != NULL)
pBufferVershin->Release();
if(pDirect3DDevice != NULL)
pDirect3DDevice->Release();
if(pDirect3D != NULL)
pDirect3D->Release();
}
void RenderingDirect3D()
{
if(pDirect3DDevice == NULL)
return;
pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,0), 1.0f, 0);
pDirect3DDevice->BeginScene();
pDirect3DDevice->SetStreamSource(0, pBufferVershin, 0, sizeof(CUSTOMVERTEX));
pDirect3DDevice ->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
pDirect3DDevice->EndScene();
}
LRESULT IntailDirect3D(HWND hwnd)
{
if(NULL == (pDirect3D = Direct3DCreate9(D3D9b_SDK_VERSION)))
return E_FAIL;
D3DDISPLAYMODE Display;
if(FAILED(pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Display)))
return E_FAIL;
D3DPRESENT_PARAMETERS Direct3DParametr;
ZeroMemory(&Direct3DParametr, sizeof(Direct3DParametr));
Direct3DParametr.Windowed = TRUE;
Direct3DParametr.SwapEffect = D3DSWAPEFFECT_DISCARD;
Direct3DParametr.BackBufferFormat = Direct3DParametr.BackBufferFormat;
if(FAILED(pDirect3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&Direct3DParametr, &pDirect3DDevice)))
return E_FAIL;
return S_OK;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
RenderingDirect3D();
ValidateRect(hwnd, NULL);
break;
case WM_DESTROY:
DeleteDirect3D();
PostQuitMessage(0);
return 0;
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE pPrevInstance, LPSTR lCmdLine, int nCmdShow)
{
WNDCLASSEX wEx;
MSG msg;
wEx.cbSize = sizeof(WNDCLASSEX);
wEx.style = CS_VREDRAW || CS_HREDRAW || CS_OWNDC || CS_DBLCLKS;
wEx.lpfnWndProc = MainWndProc;
wEx.cbClsExtra = 0;
wEx.cbWndExtra = 0;
wEx.hInstance = hInstance;
wEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wEx.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wEx.lpszMenuName = NULL;
wEx.lpszClassName = "WINDOWCLASS";
wEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wEx);
HWND hwnd;
if(!(hwnd = CreateWindowEx(NULL,
"WINDOWCLASS",
"Базовое окно для DirectX",
WS_OVERLAPPED||CW_USEDEFAULT,
0,0,
500,400,
NULL,
NULL,
hInstance,
NULL)))
{
return 0;
}
if(SUCCEEDED((IntailDirect3D(hwnd))))
{
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{RenderingDirect3D();}
}
}
return 0;
}
It doesn't look the code is drawing anything, perhaps it's part one of a tutorial
A few obvious errors:
change the logical OR to bitwise OR: || to |
wEx.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
change WS_OVERLAPPED||CW_USEDEFAULT to WS_OVERLAPPED, again it should be logical OR, and CW_USEDEFAULT doesn't belong there anyway.
This says the style is a combination of all the above flags (sort of like + operator)
Remove this whole section:
case WM_PAINT:
RenderingDirect3D();
ValidateRect(hwnd, NULL);
break;
WM_PAINT must be handled properly with BeginPaint/EndPaint or not handled at all.
Edit:
#include <windows.h>
#include <d3d9.h>
LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVershin = NULL;
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
HRESULT InitialBufferVershin()
{
CUSTOMVERTEX Vershin[] =
{
{ 300.0f, 300.0f, 0.5f, 1.0f, 0x00000fff, },
{ 150.0f, 300.0f, 0.5f, 1.0f, 0x00000fff, },
{ 150.0f, 150.0f, 0.5f, 1.0f, 0x00000fff, },
};
if (FAILED(pDirect3DDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX), 0,
D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pBufferVershin, NULL)))
return E_FAIL;
VOID* pBV;
if (FAILED(pBufferVershin->Lock(0, sizeof(Vershin), (void**)&pBV, 0)))
return E_FAIL;
memcpy(pBV, Vershin, sizeof(Vershin));
pBufferVershin->Unlock();
return S_OK;
}
void DeleteDirect3D()
{
if (pBufferVershin) pBufferVershin->Release();
if (pDirect3DDevice) pDirect3DDevice->Release();
if (pDirect3D) pDirect3D->Release();
}
void RenderingDirect3D()
{
if (pDirect3DDevice == NULL)
return;
pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 0), 1.0f, 0);
pDirect3DDevice->BeginScene();
pDirect3DDevice->SetStreamSource(0, pBufferVershin, 0, sizeof(CUSTOMVERTEX));
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
pDirect3DDevice->EndScene();
pDirect3DDevice->Present(NULL, NULL, NULL, NULL);//****changed
}
LRESULT IntailDirect3D(HWND hwnd)
{
if (NULL == (pDirect3D = Direct3DCreate9(D3D9b_SDK_VERSION)))
return E_FAIL;
D3DDISPLAYMODE Display;
if (FAILED(pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Display)))
return E_FAIL;
D3DPRESENT_PARAMETERS Direct3DParametr;
ZeroMemory(&Direct3DParametr, sizeof(Direct3DParametr));
Direct3DParametr.Windowed = TRUE;
Direct3DParametr.SwapEffect = D3DSWAPEFFECT_DISCARD;
Direct3DParametr.BackBufferFormat = Direct3DParametr.BackBufferFormat;
if (FAILED(pDirect3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&Direct3DParametr, &pDirect3DDevice)))
return E_FAIL;
return S_OK;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
DeleteDirect3D();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
WNDCLASSEX wEx = { sizeof(WNDCLASSEX) };
wEx.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
wEx.lpfnWndProc = MainWndProc;
wEx.hInstance = hInstance;
wEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wEx.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wEx.lpszClassName = "WINDOWCLASS";
RegisterClassEx(&wEx);
HWND hwnd = CreateWindowEx(NULL, "WINDOWCLASS", "TEST",
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (!hwnd)
return 0;
if (SUCCEEDED((IntailDirect3D(hwnd))))
{
InitialBufferVershin();//****changed
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
RenderingDirect3D();
}
}
}
return 0;
}
I have followed a tutorial (i am newbie in opengl) and for some reason the triangle didn't show... I would appreciate any suggestions:).
It compiles with no warnings, glClearColor works if I change it, but no triangle is displayed.
#include "GphEditorWindow.h"
#include "gl\GL.h"
#include "gl\GLU.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR plCmdLine, int nCmdShow)
{
POINT windowPos = { 100, 100 };
POINT windowSize = { 800, 600 };
if (!editorWindow.Init(hInstance, windowPos, windowSize))
{
MessageBox(NULL, "EditorWindow init failed", "Graphite Editor", MB_OK | MB_ICONERROR);
return ERROR_APP_INIT_FAILURE;
}
else
{
return editorWindow.Run();
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return editorWindow.WndProc(hWnd, message, wParam, lParam);
}
LRESULT EditorWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
RECT rect;
GetClientRect(hWnd, &rect);
workspaceWth = rect.right - rect.left;
workspaceHgh = rect.bottom - rect.top;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}
LRESULT EditorWindowGL::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
long result = EditorWindow::WndProc(hWnd, message, wParam, lParam);
switch (message)
{
case WM_CREATE:
if (!InitWGL(hWnd))
{
MessageBox(NULL, "Rendering Context Creation Failed!", "Graphite Editor", MB_OK | MB_ICONERROR);
return ERROR_APP_INIT_FAILURE;
}
SceneSetup(false);
ShowTitleBarInfo(hWnd);
break;
case WM_DESTROY:
DeleteWGL();
break;
case WM_SIZE:
SceneSetup(false);
break;
case WM_PAINT:
DrawScene();
ValidateRect(hWnd, NULL);
break;
}
return result;
}
bool EditorWindow::Init(HINSTANCE editorHandler, POINT editorWindowPos, POINT editorWindowSize)
{
char editorWindowName[] = "Graphite Editor";
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = editorHandler;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = editorWindowName;
if (RegisterClassExA(&wc) == 0)
{
DWORD blah = GetLastError();
return false;
}
editorWindowHandler = CreateWindow(editorWindowName, editorWindowName, WS_OVERLAPPEDWINDOW, editorWindowPos.x, editorWindowPos.y, editorWindowSize.x, editorWindowSize.y, NULL, NULL, editorHandler, NULL);
if (editorWindowHandler == NULL)
return false;
ShowWindow(editorWindowHandler, SW_SHOW);
UpdateWindow(editorWindowHandler);
return true;
}
WPARAM EditorWindow::Run()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
bool EditorWindowGL::PixelFormatSet(HDC dcHandler) const
{
PIXELFORMATDESCRIPTOR pixelFormatDesc;
ZeroMemory(&pixelFormatDesc, sizeof(pixelFormatDesc));
pixelFormatDesc.nVersion = 1;
pixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
pixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
pixelFormatDesc.cColorBits = 32;
pixelFormatDesc.cDepthBits = 32;
pixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
int pixelFormat = ChoosePixelFormat(dcHandler, &pixelFormatDesc);
if (pixelFormat == 0)
return false;
if (!SetPixelFormat(dcHandler, pixelFormat, &pixelFormatDesc))
return false;
return true;
}
bool EditorWindowGL::InitWGL(HWND windowHandler)
{
dcHandler = ::GetDC(windowHandler);
if (!PixelFormatSet(dcHandler))
return false;
rcHandler = wglCreateContext(dcHandler);
if (rcHandler == NULL)
return false;
if (!wglMakeCurrent(dcHandler, rcHandler))
return false;
return true;
}
void EditorWindowGL::DeleteWGL()
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(rcHandler);
::ReleaseDC(editorWindowHandler, dcHandler);
}
void EditorWindowGL::ShowTitleBarInfo(HWND windowHandler)
{
char buffer[256];
GetWindowText(windowHandler, buffer, 256);
const GLubyte* version = glGetString(GL_VERSION);
strcat_s(buffer, " | OpenGL");
strcat_s(buffer, (char*)version);
const GLubyte* vendor = glGetString(GL_VENDOR);
strcat_s(buffer, " | ");
strcat_s(buffer, (char*)vendor);
const GLubyte* gpu = glGetString(GL_RENDERER);
strcat_s(buffer, " | "); strcat_s(buffer, (char*)gpu);
SetWindowText(windowHandler, buffer);
}
void EditorWindowGL::SceneSetup(bool isometric)
{
glViewport(0, 0, workspaceWth, workspaceHgh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
float aspect = workspaceHgh / (float)workspaceWth;
if (!isometric)
glFrustum(-1.0f, 1.0f, aspect * -1.0f, aspect * 1.0f, 1.0f, 10.0f);
else
glOrtho(-1.0f, 1.0f, aspect * -1.0f, aspect * 1.0f, 1.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void EditorWindowGL::DrawScene()
{
const float x0 = 1.0f;
const float y0 = 1.0f;
const float z0 = 1.0f;
glClearColor(0.125f, 0.125f, 0.125f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-x0, -y0, 0.0f);
glVertex3f(x0, -y0, 1.0f);
glVertex3f(x0, y0, 0.0f);
glEnd();
SwapBuffers(dcHandler);
}
I use gluPerspective to mainly increase the draw distance, but it doesn't seem to work.
This is how it shows in my code:
gluPerspective(0, 70/70, 0, 4333);
ratio: The window Width and Height is both 700 and they are constant, in case of wondering.
fovy: I put 0 because, "they" say that using 45 is very nice to draw, but it stops drawing on the screen.
This is the full code:
#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>
WNDCLASSEX wclass;
MSG msg;
HWND hwnd;
HDC hdc;
HDC p_hdc;
float t;
int red, green, blue, x, y, z;
void update()
{
RECT rec;
GetClientRect(hwnd, &rec);
InvalidateRect(hwnd, &rec, false);
UpdateWindow(hwnd);
t += 0.5f;
}
void game()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
gluPerspective(45, 70/70, 0.01f, 4333);
glPopMatrix();
SwapBuffers(hdc);
}
HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{
wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = 0;
wclass.lpfnWndProc = WinProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = "CLASS";
wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wclass))
{
MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
0, 0, 700, 700,
HWND_DESKTOP, NULL, hInstance, NULL
);
EnableOpenGL(hwnd, &hdc, &hrc);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
if(hwnd == NULL)
{
MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_TIMER:
game();
update();
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC win;
win = BeginPaint(hwnd, &ps);
p_hdc = win;
game();
EndPaint(hwnd, &ps);
break;
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC(hwnd);
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;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
What to do?
EDIT: THE NEW CODE
#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>
WNDCLASSEX wclass;
MSG msg;
HWND hwnd;
HDC hdc;
HDC p_hdc;
float t;
int red, green, blue, x, y, z;
float cx, cy, cz;
void handle_resize()
{
RECT rec;
GetClientRect(hwnd, &rec);
long width = rec.right - rec.left;
long height = rec.top - rec.bottom;
float aspect = (float)width/(float)height;
glViewport(0, 0, 700, 700);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 0.01f, 99999);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void update()
{
RECT rec;
GetClientRect(hwnd, &rec);
InvalidateRect(hwnd, &rec, false);
UpdateWindow(hwnd);
t += 0.5f;
cz = -3;
}
void game()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
glPopMatrix();
SwapBuffers(hdc);
}
HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{
wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = 0;
wclass.lpfnWndProc = WinProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = "CLASS";
wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wclass))
{
MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
0, 0, 700, 700,
HWND_DESKTOP, NULL, hInstance, NULL
);
EnableOpenGL(hwnd, &hdc, &hrc);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
if(hwnd == NULL)
{
MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_TIMER:
game();
update();
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC win;
win = BeginPaint(hwnd, &ps);
p_hdc = win;
game();
EndPaint(hwnd, &ps);
break;
case WM_SIZE:
handle_resize();
break;
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC(hwnd);
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;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
gluPerspective(0, 70/70, 0, 4333);
^ nope ^ nope
fovy and zNear must both be positive and non-zero.
Try this:
gluPerspective( 45, 70/70, 0.1, 4333 );
EDIT: Push your camera back a bit too:
#include <GL/glut.h>
float t = 0;
void timer( int val )
{
t += 0.5f;
glutTimerFunc( 10, timer, 0 );
glutPostRedisplay();
}
void display()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective( 45, w / h, 0.1, 4333.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0, 0, -5 );
float norm = 1;
float z = 0;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
As-per our comments, I made a few changes to your code that are necessary to properly deal with the perspective projection matrix and window sizing. There are still a number of things about this code that I do not like, such as drawing using a timer but this should at least address the small things.
New code:
void handle_resize (void)
{
RECT rec;
GetClientRect(hwnd, &rec);
long width = rec.right - rec.left;
long height = rec.top - rec.bottom;
float aspect = (float)width/(float)height;
glViewport (0, 0, width, height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, aspect, 0.01f, 4333);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
void game()
{
glClearColor(0, 0, 0, 0); // Do this first
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3ub(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3ub(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
//gluPerspective(45, 70/70, 0.01f, 4333); // GET THIS OUT OF HERE!!!
glPopMatrix();
SwapBuffers(hdc);
}
Changes to your window message handler:
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
// NEW EVENT: Handle window size change
case WM_SIZE:
handle_resize ();
break;
Other things to note:
glColor3f clamps the floating-point value to the range [0.0,1.0], you were using values of 255 which is only appropriate if you use glColor3ub, which is essentially the same thing as glColor3f (1.0f, 1.0f, 1.0f).
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have an opengl c++ code for reading .ply file. I want to read keyboard arrow keys(up,down,right,left) for move a point on the screen. I used glutKeyboardFunc function but i have an error:
Unhandled exception at 0x1000bb1e in opengl3.exe: 0xC0000005: Access violation reading location 0x00000070.
On this line:
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);
}
The program you posted lacks a call to glutInit().
Furthermore you're doing all of the platform-specific window management and context creation that GLUT is supposed abstract away.
Bottom line: If you want to use GLUT, use GLUT. If you want to use Win32, use Win32. Don't try to mix-and-match.