I'm currently trying to draw a quadratic surface with openGL.When using a single window,my program can work well.Now I need a control panel so I create two windows,one is the frame window ,the other is the child window in which OpenGL runs.But the is something wrong with hidden-surface removal when openGL runs in the child window while this problem does not exist if I use single window.I didn't change the drawing function,just get the dc of child window and set the rc.Here is the code.Thanks for help.
#include <windows.h> //Windows header
#include <gl\glut.h> //glut
#include <gl\glaux.h> //glaux
#define hID 6310 //ID of child window
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK OpenProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szChildClass[] = TEXT ("OpenGL"); //child window class name
TCHAR szAppName[] = TEXT ("Frame"); //frame window class name
HWND hwndopen; //child window
handle
HWND hwnd; //frame window handle
MSG msg ; //message structure
HDC hdc = NULL; //device context used in child window
HGLRC hrc = NULL; //rendering context
HINSTANCE hInstance; //application instance
GLuint PixelFormat; //pixformat
BOOL active=TRUE;
BOOL keys[256];
float rquad[3]={0,0,0}; //angle of rotate
// pfd Tells Windows How We Want Things To Be
static PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR),
1,PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,0,0,0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
/* Here I draw a color cube and I draw black line in every edge
of the cube,the I draw 3 color lines to show x,y,z coordinate
axis*/
int DrawGLScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-10.0f);
glRotatef(rquad[0],1.0f,0.0f,0.0f);
glRotatef(rquad[1],0.0f,1.0f,0.0f);
glRotatef(rquad[2],0.0f,0.0f,1.0f);
glBegin(GL_QUADS);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0f,1.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( -1.0f, 1.0f, 1.0f);
glVertex3f( -1.0f, -1.0f, 1.0f);
glVertex3f( -1.0f, 1.0f, -1.0f);
glVertex3f( -1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 10.0f, 0.0f, 0.0f);
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 10.0f, 0.0f);
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 0.0f, 10.0f);
glEnd();
return TRUE;
}
BOOL InitGL(void) //init opengl
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(1.0f,0.0f,1.0f,0.5f);
glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
// resize the opengl scene in child window
void ReSizeGLScene(int width, int height)
{
if (height==0) //avoid zero to be the divisor
{
height=1;
}
glViewport(0,0,(int)width,(int)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(float)width/(float)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
WNDCLASS wndclass ;
BOOL flag=TRUE;
hInstance = GetModuleHandle(NULL);
InitGL();
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL,"窗口类注册失败","演示程序 ",MB_OK|MB_ICONINFORMATION);
return 0;
}
wndclass.lpfnWndProc = OpenProc ;
wndclass.cbWndExtra = sizeof (long) ;
wndclass.hIcon = NULL ;
wndclass.hbrBackground = NULL;
wndclass.lpszClassName = szChildClass ;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL,"子窗口类注册失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!(hwnd = CreateWindow (szAppName, TEXT ("Frisa"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL)))
{
MessageBox(NULL,"窗口创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return FALSE;
}
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (flag)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
if (!UnregisterClass(szChildClass,hInstance))
{
MessageBox(NULL,"子窗口类注销失败","演示程序",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
}
if (!UnregisterClass(szAppName,hInstance))
{
MessageBox(NULL,"窗口类注销失败","演示程序",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
}
flag=FALSE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if (active && !DrawGLScene()) // Active? Was There A Quit Received?
{
flag=FALSE; // ESC or DrawGLScene Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
SwapBuffers(hdc); // Swap Buffers (Double Buffering)
}
if(keys[VK_RIGHT]){rquad[0]+=0.12;}
if(keys[VK_LEFT]){rquad[0]=0;rquad[1]=0;rquad[2]=0;}
if(keys[VK_UP]){rquad[1]+=0.12;}
if(keys[VK_DOWN]){rquad[2]+=0.12;}
}
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int cxBlock, cyBlock;
switch (message)
{
case WM_CREATE :
if(!(hwndopen= CreateWindow (szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd,(HMENU)(hID),
(HINSTANCE)GetWindowLong (hwnd, GWL_HINSTANCE),
NULL)))
{
MessageBox(NULL,"子窗口创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(hdc=GetDC(hwndopen)))
{
MessageBox(NULL,"设备描述表创建失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(PixelFormat=ChoosePixelFormat(hdc,&pfd)))
{
MessageBox(NULL,"未找到匹配的像素格式","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!SetPixelFormat(hdc,PixelFormat,&pfd))
{
MessageBox(NULL,"设置像素格式失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if (!(hrc=wglCreateContext(hdc)))
{
MessageBox(NULL,"获取渲染描述表失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
if(!wglMakeCurrent(hdc,hrc))
{
MessageBox(NULL,"渲染描述表激活失败","演示程序",MB_OK|MB_ICONINFORMATION);
return 0;
}
return 0 ;
case WM_ACTIVATE: // Watch For Window Activate Message
// LoWord Can Be WA_INACTIVE, WA_ACTIVE, WA_CLICKACTIVE,
// The High-Order Word Specifies The Minimized State Of The Window Being Activated Or Deactivated.
// A NonZero Value Indicates The Window Is Minimized.
if ((LOWORD(wParam) != WA_INACTIVE) && !((BOOL)HIWORD(wParam)))
active=TRUE; // Program Is Active
else
active=FALSE; // Program Is No Longer Active
return 0; // Return To The Message Loop
case WM_SIZE :
cxBlock = LOWORD (lParam);
cyBlock = HIWORD (lParam);
MoveWindow (hwndopen,
5,5,
(int)(cxBlock*0.80),(int)(cyBlock*0.98), TRUE) ;
ReSizeGLScene((int)(cxBlock*0.80),(int)(cyBlock*0.97));
return 0 ;
case WM_LBUTTONDOWN :
MessageBeep (0) ;
return 0 ;
case WM_KEYDOWN:
keys[wParam] = TRUE;
return 0;
case WM_KEYUP:
keys[wParam] = FALSE;
return 0;
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY :
if (hrc)
{
if (!wglMakeCurrent(hdc,NULL))
{
MessageBox(NULL,"DC和RC关联解除失败","演示程序",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hrc))
{
MessageBox(NULL,"RC释放失败","演示程序",MB_OK | MB_ICONINFORMATION);
}
hrc=NULL;
}
if (!DestroyWindow(hwnd))
{
MessageBox(NULL,"窗口句柄释放失败","演示程序",MB_OK | MB_ICONINFORMATION);
hwnd=NULL;
}
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
LRESULT CALLBACK OpenProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
ADDITION
My aim is to paint a clolor cube in the child window with OpenGL.The size of the child window is about 0.8 times the frame window's size.I will add a control panel in the rest of area of the frame window. My program can draw a color cube .But the problem is I can see all the 6 faces,and all the 12 edges of the cube.I'm not sure but it looks like the hidden-surface removal failed.
Here I provide a link to the image of the result.
http://svgeqg.blu.livefilestore.com/y1p_TRCQ495hxOztZy3oi5qZiDPdN9hQil0KLTY9I-7fFfqCuVr_FiyJ-dIlflN5eHCMqZo5smpUwTaFDxAelq_rjO5hTU5kVzS/colorcube.JPG?psid=1
I find I have a Low-level errors committed.The initialization of OpenGL should be after the creation of the child window,but I put it at top,so it does not work.
Add CS_OWNDC to your windowclass, otherwise a embedded window will share its DC with its parent. OpenGL windows should always get their own DC, so for OpenGL Window class:
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
EDIT due to comment
I also don't see the PIXELFORMATDESCRIPTOR being actually set. Could you please show the code where you select the one PFD most closely resembling your request (API calls ChoosePixelFormat, DescribePixelFormat) and setting it on your window (SetPixelFormat API call). Also for debugging you should dump the PFD the system returned upon your request.
In addition to that, windows using OpenGL should be created with window styles WS_CLIPCHILDREN | WS_CLIPSIBLINGS
I have solved the problem,it's about the location of the OpenGL initialization.The initializationmust be after the creation of the child window in which OpenGL runs.In the above code,I init OpenGL at the beginning of winmain() function ,but the child window does not exist at that time.
Related
Consider I have used the OpenGL Control class as follows: (No need to read the code, I have just made slight changes to be able to use the code in more than one opengl window)
OpenGLControl.cpp
#include "stdafx.h"
#include "OpenGLControl.h"
COpenGLControl::COpenGLControl(void)
{
m_fPosX = 0.0f; // X position of model in camera view
m_fPosY = 0.0f; // Y position of model in camera view
m_fZoom = 10.0f; // Zoom on model in camera view
m_fRotX = 0.0f; // Rotation on model in camera view
m_fRotY = 0.0f; // Rotation on model in camera view
m_bIsMaximized = false;
}
COpenGLControl::~COpenGLControl(void)
{
}
BEGIN_MESSAGE_MAP(COpenGLControl, CWnd)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void COpenGLControl::OnPaint()
{
//CPaintDC dc(this); // device context for painting
ValidateRect(NULL);
}
void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
wglMakeCurrent(hdc, hrc);
CWnd::OnSize(nType, cx, cy);
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;
// Map the OpenGL coordinates.
glViewport(0, 0, cx, cy);
// Projection view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our current view perspective
gluPerspective(35.0f, (float)cx / (float)cy, 0.01f, 2000.0f);
// Model view
glMatrixMode(GL_MODELVIEW);
wglMakeCurrent(NULL, NULL);
}
int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
oglInitialize();
return 0;
}
void COpenGLControl::OnDraw(CDC *pDC)
{
wglMakeCurrent(hdc,hrc);
// If the current view is perspective...
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -m_fZoom);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
wglMakeCurrent(NULL, NULL);
}
void COpenGLControl::OnTimer(UINT nIDEvent)
{
wglMakeCurrent(hdc,hrc);
switch (nIDEvent)
{
case 1:
{
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
oglDrawScene();
// Swap buffers
SwapBuffers(hdc);
break;
}
default:
break;
}
CWnd::OnTimer(nIDEvent);
wglMakeCurrent(NULL, NULL);
}
void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
wglMakeCurrent(hdc,hrc);
int diffX = (int)(point.x - m_fLastX);
int diffY = (int)(point.y - m_fLastY);
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
// Left mouse button
if (nFlags & MK_LBUTTON)
{
m_fRotX += (float)0.5f * diffY;
if ((m_fRotX > 360.0f) || (m_fRotX < -360.0f))
{
m_fRotX = 0.0f;
}
m_fRotY += (float)0.5f * diffX;
if ((m_fRotY > 360.0f) || (m_fRotY < -360.0f))
{
m_fRotY = 0.0f;
}
}
// Right mouse button
else if (nFlags & MK_RBUTTON)
{
m_fZoom -= (float)0.1f * diffY;
}
// Middle mouse button
else if (nFlags & MK_MBUTTON)
{
m_fPosX += (float)0.05f * diffX;
m_fPosY -= (float)0.05f * diffY;
}
OnDraw(NULL);
CWnd::OnMouseMove(nFlags, point);
wglMakeCurrent(NULL, NULL);
}
void COpenGLControl::oglCreate(CRect rect, CWnd *parent,CString windowName)
{
CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_OWNDC, NULL, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL);
CreateEx(0, className,windowName, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0);
// Set initial variables' values
m_oldWindow = rect;
m_originalRect = rect;
hWnd = parent;
}
void COpenGLControl::oglInitialize(void)
{
// Initial Setup:
//
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24, // z-buffer depth
8,0,PFD_MAIN_PLANE, 0, 0, 0, 0,
};
// Get device context only once.
hdc = GetDC()->m_hDC;
// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
// Basic Setup:
//
// Set color to use when clearing the background.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
// Turn on backface culling
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// Send draw request
OnDraw(NULL);
wglMakeCurrent(NULL, NULL);
}
void COpenGLControl::oglDrawScene(void)
{
wglMakeCurrent(hdc, hrc);
// Wireframe Mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
// Front Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
// Bottom Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
wglMakeCurrent(NULL, NULL);
}
MyOpenGLTestDlg.h
COpenGLControl m_oglWindow;
COpenGLControl m_oglWindow2;
MyOpenGLTestDlg.cpp
// TODO: Add extra initialization here
CRect rect;
// Get size and position of the picture control
GetDlgItem(ID_OPENGL)->GetWindowRect(rect);
// Convert screen coordinates to client coordinates
ScreenToClient(rect);
// Create OpenGL Control window
CString s1("OPEN_GL");
m_oglWindow.oglCreate(rect, this,s1);
// Setup the OpenGL Window's timer to render
m_oglWindow.m_unpTimer = m_oglWindow.SetTimer(1, 1, 0);
CRect rect2;
GetDlgItem(ID_OPENGL2)->GetWindowRect(rect2);
ScreenToClient(rect2);
CString s2("OPEN_GL2");
m_oglWindow2.oglCreate(rect2, this,s2);
m_oglWindow2.m_unpTimer = m_oglWindow2.SetTimer(1, 1, 0);
The problem is when I only create one OpenGL window, the system shows:
physical memoey: 48%
CPU usage: 54%
and when I create two windows, it shows:
physical memoey: 48%
CPU usage: 95%
I'm concerned that, it is only for such simple geometries!!!
How will be the usage for two opengl windows showing textures??
Is there anyway to reduce the usage?
BTW: why is the usage so much as mensioned?
CPU usage doesn't actually indicate anything about the complexity of your application. If you draw in a tight loop, one frame after the other with no delay or VSYNC enabled you can achieve 100% CPU utilization. What this tells you is you are not GPU bound. The same way if your GPU usage (yes, you can measure this with vendor-specific APIs) is >95% then you are not CPU bound.
In short, you should expect to see very high CPU usage if the GPU is not doing anything particularly complicated :) You can always increase the sleep/timer interval to reduce CPU utilization. Remember that CPU utilization is measured as the time spent doing work versus the total time the OS gave a thread/process. Time spent working is inversely related to time spent waiting (for I/O, sleep, etc.). If you increase the time spent waiting, it will reduce the time spent working, and therefore your reported utilization.
You can also reduce the CPU usage just by enabling VSYNC. Since that will block the calling thread until the VBLANK interval comes around (often 16.666 ms).
It should also be noted that a 1 ms timer interval on your OpenGL timer is excessively low. I cannot think of a lot of applications that need to draw 1000 times a second :) Try something slightly below your target refresh rate (e.g. Monitor = 60 Hz, then try a 10-15 ms timer interval)
This needs more investigation but you may have problems with your main-loop.
This probably is not a problem with OpenGL, but with usage of WinApi. When you add textures, models, shaders... your cpu usage should be similar.
You use SetTimer(1, 1, 0); it means 1 millisecond of delay as I understand? Can you change it to 33 milliseconds (33 FPS)?
That way you will not kill your message pump in mfc app. Note that this timer is very imprecise.
link to [Basic MFC + OpenGL Message loop], (http://archive.gamedev.net/archive/reference/articles/article2204.html), using OnIdle()
Here is a great tutorial about MFC + opengl + threading - #songho
https://gamedev.stackexchange.com/questions/8623/a-good-way-to-build-a-game-loop-in-opengl - discussoion regarding mail loop in GLUT
I'm getting started with OpenGL. I need to do a project using glaux.h. My problem is that I'm running Mac OS X Lion, so I cannot use glaux.
I was searching on the web and I found some codes that try to replace glaux. Codes were fine, but they use Windows Api variables. So obviously I can't use them. Here is the code that I need to read using glaux:
#include <stdio.h> // Header File For Standard Input/Output
#include <stdlib.h>
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include "bmp.h"
#include <string.h>
const int W_WIDTH = 500; // PreselecciÛn del ancho de la ventana
const int W_HEIGHT = 500; // PreselecciÛn del alto de la ventana
bool keys[256]; // Array Used For The Keyboard Routine
bool active=1; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
bool fullscreen=0; // Fullscreen Flag Set To Fullscreen Mode By Default
GLuint texture[1]; // Storage For 1 Texture
GLuint box; // Storage For The Box Display List
GLuint top; // Storage For The Top Display List
GLuint xloop; // Loop For X Axis
GLuint yloop; // Loop For Y Axis
GLfloat xrot; // Rotates Cube On The X Axis
GLfloat yrot; // Rotates Cube On The Y Axis
static GLfloat boxcol[5][3]=
{
{1.0f,0.0f,0.0f},{1.0f,0.5f,0.0f},{1.0f,1.0f,0.0f},{0.0f,1.0f,0.0f},{0.0f,1.0f,1.0f}
};
static GLfloat topcol[5][3]=
{
{.5f,0.0f,0.0f},{0.5f,0.25f,0.0f},{0.5f,0.5f,0.0f},{0.0f,0.5f,0.0f},{0.0f,0.5f,0.5f}
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
// Build Cube Display Lists
GLvoid BuildLists()
{
box=glGenLists(2); // Generate 2 Different Lists
glNewList(box,GL_COMPILE); // Start With The Box List
glBegin(GL_QUADS);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
top=box+1; // Storage For "Top" Is "Box" Plus One
glNewList(top,GL_COMPILE); // Now The "Top" Display List
glBegin(GL_QUADS);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
}
AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image
{
FILE *File=NULL; // File Handle
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}
File=fopen(Filename,"r"); // Check To See If The File Exists
if (File) // Does The File Exist?
{
fclose(File); // Close The Handle
return new AUX_RGBImageRec(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=0; // Status Indicator
char ruta[100]="Data/Cube.bmp";
AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if (TextureImage[0]==LoadBMP(ruta))
{
Status=1; // Set The Status To TRUE
glGenTextures(1, &texture[0]); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); // Free The Texture Image Memory
}
free(TextureImage[0]); // Free The Image Structure
}
return Status; // Return The Status
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL() // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return 0; // If Texture Didn't Load Return FALSE
}
BuildLists(); // Jump To The Code That Creates Our Display Lists
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable(GL_COLOR_MATERIAL); // Enable Material Coloring
return 1; // Initialization Went OK
}
void DrawGLScene() // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear The Screen And The DepthB
glBindTexture(GL_TEXTURE_2D, texture[0]);
for (yloop=1;yloop<6;yloop++)
{
for (xloop=0;xloop<yloop;xloop++)
{
//Poner vuestro codigo no hace falta que se ve axactamente igual
}
}
// Vacia los buffers de dibujo
glutSwapBuffers();
glFlush();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitWindowPosition(100,100);
glutInitWindowSize (W_WIDTH, W_HEIGHT);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Ventana con el Visual C++ y glut");
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
// Funciones de inicializacion
InitGL();
glutMainLoop();
return 0;
}
Now that GLKit is available on OS X, I suggest you give that a look. Erik Buck's book Learning OpenGL ES for iOS is written around that framework, with an iOS focus, but he has a blog post and sample project showing a port to OS X 10.8.
Another idea, if you're allowed to step back from OpenGL, is to use SceneKit. It's a 10.8 only framework, not available on any platform other than Mac. It exposes most of the same controls that you have in OpenGL, but it is fundamentally an Objective-C, object-based design, and integrates well with Core Animation. Documentation is sparse but it's pretty easy to get things running. I found it much easier to wrap my brain around SceneKit than around OpenGL. Best intro is the WWDC 2012 video.
I tried a lot of examples for loading and displaying images in openGL using SOIL.
while running the source code below, it displays just a wite quad without an image.
I tried to open an image called: foto.
I placed the image-file in the folder of the program.
bool* keyStates = new bool[256];
GLuint texture[0];
void resize(int height, int width) {
const float ar = (float) width / (float) height;
glViewport(0, 10, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 90.0);
//gluLookAt(0, 2, 0, -1, 1, -3, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
void keyOperations (void) {
if (!keyStates['a']) {}
}
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"foto.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
// allocate a texture name
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glutSwapBuffers();
}
void keyPressed (unsigned char key, int x, int y) {
keyStates[key] = false;
}
void keyUp (unsigned char key, int x, int y) {
keyStates[key] = true;
}
int main(int argc, char **argv)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutCreateWindow("ugh fml");
glutReshapeFunc(resize);
glutDisplayFunc(Draw);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
/////////////////////////////////////
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutMainLoop();
}
You're using a relative path to access foto.png.
Make sure your working directory is where you expect.
Some IDEs like to change the working directory to someplace other than where the executable is.
I am writing a small program to simulate animation. I use QGLWidget to display a dynamic image to mimic picture animation. The basic idea is to use texture and update it through QGLFamebufferOject::blitFramebuffer. Each time, the image array will be changed and then frame buffer will be changed.
The code can run and the image can be moved forward, but image has chopping problem, or flicking, not smooth.
Following is the code for a class:
GLWidget::GLWidget(QWidget *parent) : QGLWidget(QGLFormat(), parent)
{
makeCurrent();
if (QGLFramebufferObject::hasOpenGLFramebufferBlit()) {
QGLFramebufferObjectFormat format;
render_fbo = new QGLFramebufferObject(640, 480, format);
texture_fbo = new QGLFramebufferObject(640, 480);
} else {
render_fbo = new QGLFramebufferObject(640, 480);
texture_fbo = render_fbo;
}
tile_list = glGenLists(1);
glNewList(tile_list, GL_COMPILE);
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
}
glEnd();
glEndList();
backbufferImg = new unsigned char[640 * 480 * sizeof(unsigned char) * 3];
}
GLWidget::~GLWidget()
{
}
void GLWidget::initializeGL()
{
}
void GLWidget::resizeGL(int width, int height)
{
}
void GLWidget::paintGL()
{
}
void GLWidget::saveGLState()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}
void GLWidget::restoreGLState()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
void GLWidget::changeTextureImage(int nextColumn, int direction)
{
// code about chaning backbufferImg
// ...
// call draw
draw();
}
void GLWidget::draw()
{
makeCurrent();
QPainter p(this); // used for text overlay
// save the GL state set for QPainter
saveGLState();
QPainter fbo_painter(render_fbo);
QImage renderImg(backbufferImg, 640, 480, QImage::Format_RGB888);
fbo_painter.begin(render_fbo);
QRect rect(640, 480);
fbo_painter.drawImage(rect, renderImg, rect);
fbo_painter.end();
if (render_fbo != texture_fbo) {
QGLFramebufferObject::blitFramebuffer(texture_fbo, rect, render_fbo, rect);
} else {
// qDebug() << "render_fbo == texture_fbo";
}
// draw into the GL widget
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, width(), height());
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, texture_fbo->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glScalef(1.0f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glCallList(tile_list);
glPopMatrix();
// restore the GL state that QPainter expects
restoreGLState();
glFinish();
}
Qt's QGLWidget expects that you perform all drawing operations from its overloaded paintGL function so that it iteracts nicely with Qt's double buffer management.
Also why are you taking that detour over a FBO to update a texture? This is highly inefficient and introduces a lot of synchronization points. Use a Pixel Buffer Object and update the texture with glTexSubImage2D.
Thank you very much! I have changed the code and put the drawing code inside paintGL and didn't use FBO's blit method. MUch better, but still need to improve the code. The following is the code:
GLWidget::GLWidget(QWidget *parent) :
QGLWidget(QGLFormat(), parent)
{
makeCurrent();
fbo = new QGLFramebufferObject(WIDTH, HEIGHT);
tile_list = glGenLists(1);
glNewList(tile_list, GL_COMPILE);
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
}
glEnd();
glEndList();
backbufferImg = new unsigned char[WIDTH * HEIGHT * sizeof(unsigned char) * 3];
}
GLWidget::~GLWidget()
{
glDeleteLists(tile_list, 1);
delete fbo;
delete backbufferImg;
}
void GLWidget::initializeGL()
{
}
void GLWidget::resizeGL(int width, int height)
{
}
void GLWidget::paintGL()
{
glViewport(0, 0, fbo->size().width(), fbo->size().height());
glMatrixMode(GL_MODELVIEW);
// render to the framebuffer object
fbo->bind();
glBindTexture(GL_TEXTURE_2D, refreshTexture);
glCallList(tile_list);
fbo->release();
//////////////////////////////////////////////////////////////////////
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, width(), height());
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, fbo->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glScalef(1.0f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glCallList(tile_list);
glPopMatrix();
// restore the GL state that QPainter expects
restoreGLState();
glFinish();
}
void GLWidget::saveGLState()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}
void GLWidget::restoreGLState()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
void GLWidget::refreshTextureImage(int nextColumn, int direction)
{
// upadte backbufferImg
// add code...
QImage renderImg(backbufferImg, WIDTH, HEIGHT, QImage::Format_RGB888);
refreshTexture = bindTexture(renderImg);
updateGL();
}
I will try the method you suggested. But I think framebuffer and pixel buffer in the same level. It means there is no much performance difference. For glTexSubImage2D, I am not quite sure, I need to check it.
Thank you so much.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Image loading using openGL, SOIL
while running the source code below, it displays just a wite quad without an image.
I tried to open an image called: foto.
I placed the image-file in the folder of the program.
bool* keyStates = new bool[256];
GLuint texture[0];
void resize(int height, int width) {
const float ar = (float) width / (float) height;
glViewport(0, 10, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 90.0);
//gluLookAt(0, 2, 0, -1, 1, -3, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
void keyOperations (void) {
if (!keyStates['a']) {}
}
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"foto.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
// allocate a texture name
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glutSwapBuffers();
}
void keyPressed (unsigned char key, int x, int y) {
keyStates[key] = false;
}
void keyUp (unsigned char key, int x, int y) {
keyStates[key] = true;
}
int main(int argc, char **argv)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutCreateWindow("ugh fml");
glutReshapeFunc(resize);
glutDisplayFunc(Draw);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
/////////////////////////////////////
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutMainLoop();
}
I get the same behavior if the image file (foto.png) is not located in the program's working directory. But when I add the image to the program's working directory, the quad is textured properly. Try either 1) adding the texture image to the program's working directory or 2) changing the program's working directory to the directory where the texture file is located.