My texture is not displaying

Hello all! This is my first post! I’ve been working with C++ and Visual C++ for about five years and have just made the leap into OpenGL.

Presently, I have a dialog box, created from various online examples, which is supposed to produce a texture on a rectangle. The rectangle appears, but the texture does not. Does anyone know why?

(Please note: The loadbitmap and texture function all return successfully. The bitmap exists in the appropriate directory)

// header file
// GraphicsEngineDlg.h : header file
//

#if !defined(AFX_GRAPHICSENGINEDLG_H__A779FD07_4258_11D1_88DD_A4B001C10000__INCLUDED_)
#define AFX_GRAPHICSENGINEDLG_H__A779FD07_4258_11D1_88DD_A4B001C10000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "resource.h"
#include <stdio.h>			// Header File For Standard Input/Output
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
#include <gl\glaux.h>		// Header File For The Glaux Library

/////////////////////////////////////////////////////////////////////////////
// GraphicsEngineDlg dialog


class GraphicsEngineDlg : public CDialog
{
// Construction
public:
	GraphicsEngineDlg(CWnd* pParent = NULL);	// standard constructor

	BOOL SetWindowPixelFormat(HDC hDC);
	BOOL CreateViewGLContext(HDC hDC);
	void RenderScene();


	BOOL m_Rotate;

	HGLRC m_hGLContext;
	int m_GLPixelIndex;

	float m_transY;
	float m_transX;
	float m_transZ;

	double m_angle1;
	double m_angle2;

	float	m_ScaleX;
	float m_ScaleY;
	float m_ScaleZ;

	GLdouble m_xRotate;
	GLdouble m_yRotate;

	int m_width;
	int m_height;
	int m_exp;

	float m_size;

	float m_z_zoom; 
	float m_max_z_zoom;
	float m_min_z_zoom;

	CPoint m_RightDownPos;
	CPoint m_LeftDownPos;
	BOOL m_RightButtonDown;
	BOOL m_LeftButtonDown;

	GLuint	filter;				// Which Filter To Use
	GLuint	texture[3];			// Storage For 3 Textures


// Dialog Data
	//{{AFX_DATA(GraphicsEngineDlg)
	enum { IDD = IDD_GRAPHICSENGINE_DIALOG };
	CButton m_Ok;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(GraphicsEngineDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	afx_msg void OnContextMenu(CWnd*, CPoint point);

	AUX_RGBImageRec* LoadBMP(char* Filename);
	int LoadGLTextures();

	// Generated message map functions
	//{{AFX_MSG(GraphicsEngineDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_GRAPHICSENGINEDLG_H__A779FD07_4258_11D1_88DD_A4B001C10000__INCLUDED_)
// Cpp file
// GraphicsEngineDlg.cpp : implementation file
//

#include "stdafx.h"
#include "GraphicsEngineDlg.h"

#include "math.h"
#include "mmsystem.h"
#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// GraphicsEngineDlg dialog

GraphicsEngineDlg::GraphicsEngineDlg(CWnd* pParent /*=NULL*/)
	: CDialog(GraphicsEngineDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(GraphicsEngineDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hGLContext = NULL;
	m_GLPixelIndex = 0;

	m_transX = 0.0f;
	m_transY = 0.0f;
	m_transZ = 0.0f;

	m_xRotate = 0;
	m_yRotate = 0;
	m_Rotate = FALSE;

	m_ScaleX = 1.0f;
	m_ScaleY = 1.0f;
	m_ScaleZ = 1.0f;

	m_z_zoom = 50.0f; 
	m_max_z_zoom = 100.0f;
	m_min_z_zoom = 0.0f;


	m_RightButtonDown = FALSE;
	m_LeftButtonDown = FALSE;

	filter = 0;
}

void GraphicsEngineDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(GraphicsEngineDlg)
	DDX_Control(pDX, IDOK, m_Ok);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(GraphicsEngineDlg, CDialog)
	ON_WM_CONTEXTMENU()
	//{{AFX_MSG_MAP(GraphicsEngineDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEWHEEL()
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// GraphicsEngineDlg message handlers

BOOL GraphicsEngineDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	CWnd* pDesktop = CWnd::GetDesktopWindow();
	CRect DesktopRect;
	pDesktop->GetWindowRect(&DesktopRect);
	MoveWindow(&DesktopRect);

	CRect ClientRect;
	GetClientRect(&ClientRect);
	ScreenToClient(&ClientRect);

	CRect rect = ClientRect;

	rect.top = rect.bottom - 36;
	rect.bottom -= 6;
  
	rect.right = ClientRect.right - 3;
	rect.left = ClientRect.right - 60;

	m_Ok.MoveWindow(&rect);

	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void GraphicsEngineDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	CDialog::OnSysCommand(nID, lParam);
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void GraphicsEngineDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	RenderScene();
	SwapBuffers(dc.m_ps.hdc);
	CDialog::OnPaint();
}

BOOL GraphicsEngineDlg::SetWindowPixelFormat(HDC hDC)
{
	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							
	};

	m_GLPixelIndex = ChoosePixelFormat(hDC,&pfd);
	if(m_GLPixelIndex==0) // Choose default
	{
		m_GLPixelIndex = 1;
		if(!DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pfd))
			return FALSE;
	}

	if(!SetPixelFormat(hDC,m_GLPixelIndex,&pfd))
		return FALSE;
	
	return TRUE;
}


BOOL GraphicsEngineDlg::CreateViewGLContext(HDC hDC)
{
	m_hGLContext = wglCreateContext(hDC);

	if(m_hGLContext==NULL)
		return FALSE;

	if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)
		return FALSE;
	return TRUE;
}



int GraphicsEngineDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!LoadGLTextures())						
	{
		return FALSE;							
	}

	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);			

	HWND hWnd = GetSafeHwnd();
	HDC hDC = ::GetDC(hWnd);

	if(SetWindowPixelFormat(hDC)==FALSE)
		return 0;
	
	if(CreateViewGLContext(hDC)==FALSE)
		return 0;

	return 0;
}
	

void GraphicsEngineDlg::OnDestroy() 
{

	CDialog::OnDestroy();

	if(wglGetCurrentContext() != NULL)
		wglMakeCurrent(NULL,NULL);

	if(m_hGLContext != NULL)
	{
		wglDeleteContext(m_hGLContext);
		m_hGLContext = NULL;
	}
	
}

void GraphicsEngineDlg::OnSize(UINT nType, int width, int height) 
{
	CDialog::OnSize(nType, width, height);
	
	if (height==0)							
	{
		height=1;							
	}

	glViewport(0, 0, width, height);		

   
	glMatrixMode(GL_PROJECTION);			
	glLoadIdentity();						

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,150.0f);

	glMatrixMode(GL_MODELVIEW);				
	glLoadIdentity();						


	// Lights, material properties
	GLfloat	ambientProperties[]  = {0.7f, 0.7f, 0.7f, 1.0f};
	GLfloat	diffuseProperties[]  = {0.8f, 0.8f, 0.8f, 1.0f};
	GLfloat	specularProperties[] = {1.0f, 1.0f, 1.0f, 1.0f};
	
	glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties);
	glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties);
	glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties);

	// Default : lighting
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
}

void GraphicsEngineDlg::RenderScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	glTranslated(m_transX,m_transY,-8.0 + m_transZ - m_z_zoom);

	glBindTexture(GL_TEXTURE_2D, texture[0]);
	glBegin(GL_QUADS);

		// top left vertex
		glTexCoord2f(0.0f, 1.0f);
		glVertex3d( 0.0f, 1.0f, 0.0f );

		// bottom left vertex
		glTexCoord2f(0.0f, 0.0f);
		glVertex3d( 0.0f , 0.0f , 0.0f );

		// bottom right vertex
		glTexCoord2f(1.0f, 0.0f);
		glVertex3d( 1.0f, 0.0f, 0.0f );

		// top right vertex
		glTexCoord2f(1.0f, 1.0f);
		glVertex3d( 1.0f, 1.0f, 0.0f );
	glEnd();
}

void GraphicsEngineDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	m_LeftButtonDown = TRUE;
	m_LeftDownPos = point;
	CDialog::OnLButtonDown(nFlags, point);
}

void GraphicsEngineDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	m_LeftButtonDown = FALSE;
	
	CDialog::OnLButtonUp(nFlags, point);
}

void GraphicsEngineDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	if(m_LeftButtonDown)
	{
		CSize translate = m_LeftDownPos - point;
		m_LeftDownPos = point;
		m_transX -= ((float)translate.cx)/25;
		m_transY += ((float)translate.cy)/25;
		m_transZ -= 2*((float)translate.cy)/25;
		InvalidateRect(NULL,FALSE);
	}
	
	CDialog::OnMouseMove(nFlags, point);
}

void GraphicsEngineDlg::OnContextMenu(CWnd*, CPoint point)
{

}

void GraphicsEngineDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch(nChar)
		{
		case VK_UP:
			m_ScaleX *= 1.1f;
			m_ScaleY *= 1.1f;
			m_ScaleZ *= 1.1f;
			InvalidateRect(NULL,FALSE);
			break;
		case VK_DOWN:
			m_ScaleX /= 1.1f;
			m_ScaleY /= 1.1f;
			m_ScaleZ /= 1.1f;
			InvalidateRect(NULL,FALSE);
			break;
		default :
			{}

		}
	CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL GraphicsEngineDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	float zoom = -zDelta;
	
	m_z_zoom += zoom/25;

	if(m_z_zoom < m_min_z_zoom)
	{
		m_z_zoom = m_min_z_zoom;
	}
	if(m_z_zoom > m_max_z_zoom)
	{
		m_z_zoom = m_max_z_zoom;
	}
	InvalidateRect(NULL,FALSE);

	return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}

AUX_RGBImageRec* GraphicsEngineDlg::LoadBMP(char* Filename)	
{
	FILE* File=NULL;									

	if (!Filename)										
	{
		return NULL;									
	}

	File=fopen(Filename,"r");							

	if (File)											
	{
		fclose(File);									
		return auxDIBImageLoad(Filename);				
	}

	return NULL;										
}

int GraphicsEngineDlg::LoadGLTextures()	
{
	int Status=FALSE;					

	AUX_RGBImageRec* TextureImage[1];	

	memset(TextureImage,0,sizeof(void*)*1);

	if (TextureImage[0] = LoadBMP("res/floor.bmp"))
	{
		Status=TRUE;

		glGenTextures(3, &texture[0]);

		// Create Nearest Filtered Texture
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// Create Linear Filtered Texture
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// Create MipMapped Texture
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
	}

	if (TextureImage[0])								
	{
		if (TextureImage[0]->data)						
		{
			free(TextureImage[0]->data);				
		}

		free(TextureImage[0]);							
	}

	return Status;										
}

Are the dimensions of the image a power of 2 e.g. 8x16, 32x128, etc? If not then that’ll explain why you don’t see it. Texture images need to be a power of 2 in width & height - unless you use an OpenGL extension but I don’t think you’re doing that.

Your GraphicsEngineDlg::OnCreate is incorrect. All OGL functions require existing OGL context or they will fail. You need to call the CreateViewGLContext() before any gl* function.

The bitmap is 48 x 48. “floor.bmp 48 x 48 Bitmap Image,” says the file in the res directory. It has been saved in 24-bit format.
Should the SetWindowPixelFormat function say 24 instead of 16?

I rearranged the OnCreate function, but it still does not work! :frowning:

int GraphicsEngineDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	HWND hWnd = GetSafeHwnd();
	HDC hDC = ::GetDC(hWnd);

	if(SetWindowPixelFormat(hDC)==FALSE)
		return 0;

	if(CreateViewGLContext(hDC)==FALSE)
		return 0;

	if (!LoadGLTextures())						
	{
		return 0;							
	}

	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);			

	return 0;
}

48 isn’t an integer power of 2 - either 32(2^5) or 64(2^6)

Oh, my mistake. I misunderstood. It works now. Thanks a lot! :slight_smile: