OpenGl Shader Program Linking error with uncertain reason - c++

I'm trying to make a framework that uses OpenGL.
Yet, having problem to reload shader program.
This is what I have right now.
I load and compile a vertex shader and a fragment shader(both contain main).
Than I link a program with them.
At first, it has no problem. No matter how much time I refresh shaders.
(If I press Refresh Shader, the application creates new shader, program resource and replaces original ones with them)
Than, if I load a mesh and preform some drawing calls(using VBO), This time Refresh Shader Fails with following message.
I have no idea how my draw calls or VBO function calls could possibly be related to Shader Linking...
I'm not even sure if that is the exact reason or not.
Shader class:
class Shader : public Named
{
// -------------------------------------------------------
// --------------- Defs ----------------------------------
public:
typedef void (*ErrFunc)( Shader* pShader, const char* const errMsg );
// -------------------------------------------------------
// --------------- Funcs ---------------------------------
public:
//
// Shader Controls
//
// pre: source is string contains source
Shader( const std::string& name, GLenum type);
~Shader( void );
// pre: file to loast source. Give nullptr to load from lastly loaded file
void ShaderSourceFromFile( const char* file );
void ShaderSource( const std::string& source );
void Compile( void );
void AttachTo( GLuint program );
void DetachFrom( GLuint program );
GLuint GetId( void );
void SetId( GLuint shaderId );
GLint GetType( void );
GLint GetCompileStatus( void );
const char* const GetShaderInfoLog( void );
//
// Err Control
//
public:
void Error ( const char* pErrMsg );
static ErrFunc SetErrFunc( ErrFunc fpNewErrFunc );
// -------------------------------------------------------
// ----------- Vars --------------------------------------
private:
// id of the shader
GLuint _shaderId;
// type of the shader
GLenum _type;
// error func
static ErrFunc s_fpErrFunc;
}; // class Shader
//
// Shader
//
Shader::ErrFunc Shader::s_fpErrFunc = nullptr;
Shader::Shader( const std::string& name, GLenum type) :
Named(name),
_shaderId(GL_INVALID_RESOURCE_ID),
_type(type)
{
// Create shader
GLint id = glCreateShader(type);
// Failed to create shader?
if ( id == GL_INVALID_RESOURCE_ID )
Error("(Shader::Shader) Failed to create shader resource");
// Set shader id
SetId(id);
}
Shader::~Shader( void )
{
// Delete shader
glDeleteShader(GetId());
// Error Check
if( glGetError() == GL_INVALID_VALUE )
Error("(Shader::~Shader) given id to delete was not shader");
}
void Shader::Compile( void )
{
// Compile shader
glCompileShader(_shaderId);
switch( glGetError() )
{
case GL_NO_ERROR:break;
case GL_INVALID_VALUE: Error("shader is not a value generated by OpenGL.");break;
case GL_INVALID_OPERATION: Error("shader is not a shader object.");break;
default:Error("Unkown Error");
}
// ErrorCheck
if( GetCompileStatus() == GL_FALSE )
Error("(Shader::Compile) Compilation Failed.");
}
void Shader::ShaderSourceFromFile( const char* file )
{
ShaderSource(ReadEntireFile(file));
}
// pre: source is string contains source
void Shader::ShaderSource( const std::string& source )
{
const GLchar* pSource = source.c_str();
glShaderSource( GetId(), // shader id
1, // count of source. only one at a time at the moment
&pSource, // buffer that source is stored
nullptr); // length is not specified, yet null terminated
switch( glGetError() )
{
case GL_NO_ERROR:
break;
case GL_INVALID_VALUE:
Error("invalid shader or bufsize is less than 0");
break;
case GL_INVALID_OPERATION:
Error("shader is not a shader object.");
break;
default:
Error("Unkown Error");
break;
}
}
void Shader::AttachTo( GLuint program )
{
glAttachShader(program, GetId());
if( glGetError() != GL_NO_ERROR )
{
Error("(Shader::AttachTo) Error Happend Performing glAttachShader");
}
}
void Shader::DetachFrom( GLuint program )
{
glDetachShader(program, GetId());
switch( glGetError() )
{
case GL_NO_ERROR:
break;
case GL_INVALID_VALUE:
Error("(Shader::DetachFrom)either program or shader is a value that was not generated by OpenGL.");
break;
case GL_INVALID_OPERATION:
Error("(Shader::DetachFrom)program is not a program object. or "
"shader is not a shader object. or "
"shader is not attached to program.");
break;
default:
Error("(Shader::DetachFrom)Unkown Error");
break;
}
}
GLuint Shader::GetId( void )
{
return _shaderId;
}
void Shader::SetId( GLuint shaderId )
{
_shaderId = shaderId;
}
GLint Shader::GetType( void )
{
return _type;
}
void Shader::Error ( const char* pErrMsg )
{
if( s_fpErrFunc )
s_fpErrFunc(this, pErrMsg);
}
Shader::ErrFunc Shader::SetErrFunc( ErrFunc fpNewErrFunc )
{
ErrFunc prev = s_fpErrFunc;
s_fpErrFunc = fpNewErrFunc;
return prev;
}
GLint Shader::GetCompileStatus( void )
{
GLint status;
glGetShaderiv(GetId(), GL_COMPILE_STATUS, &status );
GLint err = glGetError();
switch( err )
{
case GL_NO_ERROR:
break;
case GL_INVALID_ENUM:
Error("(Shader::GetCompileStatus) Invalid Enum passed to glGetShaderiv");
break;
case GL_INVALID_VALUE:
Error("(Shader::GetCompileStatus) Invalid Shader id passed to glGetShaderiv");
break;
case GL_INVALID_OPERATION:
Error("(Shader::GetCompileStatus) Invalid Shader id or shader does not support");
break;
default:
Error("(Shader::GetCompileStatus) Unkown Error");
break;
}
return status;
}
const char* const Shader::GetShaderInfoLog( void )
{
static const unsigned s_bufSize = 0x1000;
static GLchar s_buf[s_bufSize] = {0};
// Get InfoLog
glGetShaderInfoLog(GetId(), s_bufSize, nullptr, s_buf);
// Error Check
if( glGetError() != GL_NO_ERROR )
Error("(Shader::GetCompileStatus) There was Error performing glGetShaderInfoLog");
// return buffer
return s_buf;
}
Refreshing Function:
void GLShaderManager::Refresh( void )
{
// Gets current shader
Shader* pVertexPrev = _shaderMap["Vertex"];
Shader* pFragPrev = _shaderMap["Fragment"];
// Delete them(glDeleteShader call is included)
if( pVertexPrev && pFragPrev )
{
delete pVertexPrev;
delete pFragPrev;
}
// Loads shader
LoadShader("Vertex", GL_VERTEX_SHADER, s_vertexFile);
LoadShader("Fragment", GL_FRAGMENT_SHADER, s_fragmentFile);
// Delete Current Program
glDeleteProgram(_program);
// Create new Program
GLuint newProgram = glCreateProgram();
_program = newProgram;
// Attach Shaders
UseShader("Vertex");
UseShader("Fragment");
// Linking
glLinkProgram(_program);
const unsigned bufSize = 0x1000;
char buf[bufSize] = { '\0' };
GLint status = 0;
glGetProgramiv(_program, GL_LINK_STATUS, &status );
if( status )
Gui::Get().Output("Shader program linked successfully.");
glGetProgramInfoLog(_program, bufSize, nullptr, buf);
Gui::Get().Output(buf);
s_uniformErrHistory.clear();
}
void GLShaderManager::LoadShader( const std::string& name, GLenum type, const std::string& sourceFile )
{
Shader* pShader = _shaderMap[name] = new Shader(name, type);
if( pShader )
{
pShader->ShaderSourceFromFile(sourceFile.c_str());
pShader->Compile();
if( pShader->GetCompileStatus() )
Gui::Get().Output( (pShader->GetName() + " shader successfully compiled.").c_str());
Gui::Get().Output(pShader->GetShaderInfoLog());
}
}
void GLShaderManager::UseShader( const std::string& name )
{
Shader* pShader = _shaderMap[name];
if( pShader )
{
pShader->AttachTo(_program);
}
}

Related

How to fix const char is incompatible with type char DirectX11

I know this is a dumb question, but I'm trying to compile this code for a project, but I run into an error. I didn't write the code, my project is to modify it to get a different outcome than what the code was originaly suppose to produce.
However, I can't even start the project because the given code won't compile: Severity Code Description Project File Line Suppression State
Error (active) E0167 argument of type "const char *" is incompatible with parameter of type "char *" Direct 3D Text c:\Visual Studio Programs\Direct 3D Text\Direct 3D Text\D3DTextDemo.cpp 30
Code where I get the error:
bool D3DTextDemo::LoadContent()
{
ID3DBlob* vsBuffer = 0;
bool compileResult = CompileD3DShader("TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling the vertex shader!");
return false;
}
HRESULT d3dResult;
d3dResult = d3dDevice_->CreateVertexShader(vsBuffer->GetBufferPointer(),
vsBuffer->GetBufferSize(), 0, &solidColorVS_);
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the vertex shader!");
if (vsBuffer)
vsBuffer->Release();
return false;
}
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);
d3dResult = d3dDevice_->CreateInputLayout(solidColorLayout, totalLayoutElements,
vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout_);
vsBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating the input layout!");
return false;
}
ID3DBlob* psBuffer = 0;
compileResult = CompileD3DShader("TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer);
if (compileResult == false)
{
DXTRACE_MSG("Error compiling pixel shader!");
return false;
}
d3dResult = d3dDevice_->CreatePixelShader(psBuffer->GetBufferPointer(),
psBuffer->GetBufferSize(), 0, &solidColorPS_);
psBuffer->Release();
if (FAILED(d3dResult))
{
DXTRACE_MSG("Error creating pixel shader!");
return false;
}
d3dResult = D3DX11CreateShaderResourceViewFromFile(d3dDevice_,
"font.dds", 0, 0, &colorMap_, 0);
if (FAILED(d3dResult))
{
DXTRACE_MSG("Failed to load the texture image!");
return false;
}
Thanks
A char* defined in double quotes -eg."TextureMap.fx"- is called a string literal and is per definition constant.
When you pass a constant value to a function that takes non-constant values, there is no guarantee that it won't be modified and thus won't compile.
I fixed this issue by defining the literal in a char[], which doesn't make it constant anymore:
char fxFile[] = "TextureMap.fx";
bool compileResult = CompileD3DShader(fxFile, "VS_Main", "vs_4_0", &vsBuffer);

Images and text not showing in SDL under Mac OSX

I got to compile, bundle and load resources under XCode 4.3 and SDL 1.2.15
I know resources are loading correctly because file handles are not null and no error is thrown.
I successfully load png's and ttf's, obtain and crop surfaces, and blit them.
But when I flip, the only thing I get to see are the lines I drew using SDL_Draw
I will put some bits of code, as I'm trying to keep an engine-ish structure so the code is everything but together.
Initialization:
void CEngine::Init() {
// Register SDL_Quit to be called at exit; makes sure things are cleaned up when we quit.
atexit( SDL_Quit );
// Initialize SDL's subsystems - in this case, only video.
if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
fprintf( stderr, "Unable to init SDL: %s\n", SDL_GetError() );
exit( 1 );
}
// Attempt to create a window with the specified height and width.
SetSize( m_iWidth, m_iHeight );
// If we fail, return error.
if ( m_pScreen == NULL ) {
fprintf( stderr, "Unable to set up video: %s\n", SDL_GetError() );
exit( 1 );
}
AdditionalInit();
}
and
void CTileEngine::AdditionalInit() {
SetTitle( "TileEngine - Loading..." );
PrintDebug("Initializing SDL_Image");
int flags = IMG_INIT_PNG;
int initted = IMG_Init( flags );
if( ( initted & flags ) != flags ) {
PrintDebug("IMG_Init: Failed to init required image support!");
PrintDebug(IMG_GetError());
// handle error
}
PrintDebug("Initializing SDL_TTF");
if( TTF_Init() == -1 ) {
PrintDebug("TTF_Init: Failed to init required ttf support!");
PrintDebug(TTF_GetError());
}
PrintDebug("Loading fonts");
font = TTF_OpenFont( OSXFileManager::GetResourcePath("Roboto-Regular.ttf"), 28 );
if( !font ) {
PrintDebug("Error loading fonts");
PrintDebug(TTF_GetError());
}
g_pGame = new CGame;
LoadGame( OSXFileManager::GetResourcePath( "test", "tmx") );
SetTitle( "TileEngine" );
PrintDebug("Finished AditionalInit()");
}
Main draw method
void CEngine::DoRender(){
++m_iFPSCounter;
if ( m_iFPSTickCounter >= 1000 ) {
m_iCurrentFPS = m_iFPSCounter;
m_iFPSCounter = 0;
m_iFPSTickCounter = 0;
}
SDL_FillRect( m_pScreen, 0, SDL_MapRGB( m_pScreen->format, 0, 0, 0 ) );
// Lock surface if needed
if ( SDL_MUSTLOCK( m_pScreen ) ){
if ( SDL_LockSurface( m_pScreen ) < 0 ){
return;
}
}
Render( GetSurface() );
// Render FPS
SDL_Color fpsColor = { 255, 255, 255 };
string fpsMessage = "FPS: ";
fpsMessage.append( SSTR(m_iCurrentFPS) );
SDL_Surface* fps = TTF_RenderText_Solid(font, fpsMessage.c_str(), fpsColor);
if( fps ) {
SDL_Rect destRect;
destRect.x = pDestSurface->w - fps->w;
destRect.y = pDestSurface->h - fps->h;
destRect.w = fps->w;
destRect.h = fps->h;
SDL_BlitSurface(fps, &fps->clip_rect, pDestSurface, &destRect);
SDL_FreeSurface(fps);
}
// Unlock if needed
if ( SDL_MUSTLOCK( m_pScreen ) )
SDL_UnlockSurface( m_pScreen );
// Tell SDL to update the whole gScreen
SDL_Flip( m_pScreen );
}
Image file loading
bool CEntity::VLoadImageFromFile( const string& sFile) {
if ( m_pSurface != 0 ){
SDL_FreeSurface( m_pSurface );
}
string nFile = string(OSXFileManager::APPNAME) + OSXFileManager::RESOURCEDIR + sFile;
SDL_Surface *pTempSurface;
pTempSurface = IMG_Load( nFile.c_str() );
m_sImage = sFile;
if ( pTempSurface == 0 ){
char czError[256];
sprintf( czError, "Image '%s' could not be opened. Reason: %s", nFile.c_str(), IMG_GetError() );
fprintf( stderr, "\nERROR: %s", czError );
return false;
} else {
pTempSurface = SDL_DisplayFormatAlpha(pTempSurface);
}
m_pSurface = pTempSurface;
return true;
}
Entity draw method
void CEntity::VRender( SDL_Surface *pDestSurface ) {
if ( ( m_pSurface == 0 ) || ( m_bVisible == false) || ( m_iAlpha == 0 ) ){
// If the surface is invalid or it's 100% transparent.
return;
}
SDL_Rect SDestRect;
SDestRect.x = m_iPosX;
SDestRect.y = m_iPosY;
SDestRect.w = m_pSurface->w;
SDestRect.h = m_pSurface->h;
if ( m_iAlpha != 255 )
SDL_SetAlpha( m_pSurface, SDL_SRCALPHA, m_iAlpha );
SDL_BlitSurface( m_pSurface, &m_pSurface->clip_rect, pDestSurface, &SDestRect );
}
I have checked and debugged million times and I don't get what's wrong here. As I told before, file loading seems to be OK.
But this part
void CTile::RenderGrid( SDL_Surface* pDestSurface ) {
Uint32 m_GridColor = SDL_MapRGB( pDestSurface->format, 0xFF, 0xFF, 0xFF );
Draw_Rect(pDestSurface, GetPosX(), GetPosY(), GetWidth(), GetHeight(), m_GridColor);
}
works like a charm.
I found out what was happening. Turns out that, from SDL version 1.1.18 SDL_Lock calls are recursive, so each lock must pair an unlock. That was not happening last time I used SDL, so I was not aware of it. Simply matching locks and unlocks did the job.

Abstract base class that defines a pure virtual function with a void* param. Derived class matching param is a pointer to some type

Revised, actual Base And Derived Class I am working with plus the function that instantiates it and uses the non virtual function call
ShaderClass.h
#ifndef SHADERCLASS_H
#define SHADERCLASS_H
#include <D3D11.h>
#include <D3DX10math.h>
#include <D3DX11async.h>
#include <fstream>
using namespace std;
class ShaderClass {
protected:
struct MatrixBufferType {
D3DXMATRIX world;
D3DXMATRIX view;
D3DXMATRIX projection;
};
ID3D11Device* m_pDevice;
ID3D11DeviceContext* m_pDeviceContext;
HWND m_hWnd;
ID3D11VertexShader* m_pVertexShader;
ID3D11PixelShader* m_pPixelShader;
ID3D11InputLayout* m_pLayout;
ID3D11Buffer* m_pMatrixBuffer;
ID3D11SamplerState* m_pSampleState;
WCHAR* m_vsFilename;
WCHAR* m_psFilename;
public:
ShaderClass();
//ShaderClass( const ShaderClass& other );
virtual ~ShaderClass();
bool initialize( ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, HWND hWnd, WCHAR* vsFilename, WCHAR* psFilename );
void shutdown();
bool render( int index, D3DXMATRIX view, D3DXMATRIX world, D3DXMATRIX projection, void* pData );
protected:
virtual bool initializeShader() = 0;
virtual void shutdownShader() = 0;
virtual bool setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, void* pData ) = 0;
virtual void renderShader( int index ) = 0;
void outputShaderErrorMessage( ID3D10Blob* pErrorMessage, WCHAR* shaderFilename );
}; // ShaderClass
#endif // SHADERCLASS_H
ShaderClass.cpp
#include "ShaderClass.h"
// ------------------------------------------------------------------------------------------
ShaderClass::ShaderClass() :
m_pVertexShader( nullptr ),
m_pPixelShader( nullptr ),
m_pLayout( nullptr ),
m_pMatrixBuffer( nullptr ),
m_pSampleState( nullptr ) {
} // ShaderClass
// ----------------------------------------------------------------------------
// ShaderClass::ShaderClass( const ShaderClass& other ) {
//} // ShaderClass
// ----------------------------------------------------------------------------
ShaderClass::~ShaderClass() {
} // ~ShaderClass
// ----------------------------------------------------------------------------
bool ShaderClass::initialize( ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, HWND hWnd, WCHAR* vsFilename, WCHAR* psFilename ) {
bool bResult;
if ( !pDevice ) {
return false;
}
m_pDevice = pDevice;
if ( !pDeviceContext ) {
return false;
}
m_pDeviceContext = pDeviceContext;
m_hWnd = hWnd;
m_vsFilename = vsFilename;
m_psFilename = psFilename;
// Initialize The Vertex And Pixel Shaders
bResult = initializeShader();
if ( !bResult ) {
return false;
}
return true;
} // initialize
// ----------------------------------------------------------------------------
void ShaderClass::shutdown() {
// Shutdown Individual Shader Contents
shutdownShader();
} // shutdown
// -----------------------------------------------------------------------------
bool ShaderClass::render( int indexCount, D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, void* pData ) {
bool bResult;
bResult = setShaderParameters( world, view, projection, pData );
if ( !bResult ) {
return false;
}
renderShader( indexCount );
return true;
} // render
// ----------------------------------------------------------------------------
void ShaderClass::outputShaderErrorMessage( ID3D10Blob* pErrorMessage, WCHAR* shaderFilename ) {
char* compileErrors;
unsigned long bufferSize, i;
ofstream fout;
// Get A Pointer To The Error Message Text Buffer
compileErrors = (char*)(pErrorMessage->GetBufferPointer());
// Get The Length Of The Message
bufferSize = pErrorMessage->GetBufferSize();
// Open A File To Write The Error Message
fout.open( "shader-error.txt" );
// Write Out The Error Message
for ( i = 0; i < bufferSize; i++ ) {
fout << compileErrors[i];
}
// Close The File
fout.close();
// Release The Error Message
pErrorMessage->Release();
pErrorMessage = nullptr;
// Pop A Message To Notify The User
MessageBox( m_hWnd, L"Error compiling shader. Check shader-error.txt for message", shaderFilename, MB_OK );
return;
} // outputShaderErrorMessage
LightMapShaderClass.h
#ifndef LIGHTMAPSHADERCLASS_H
#define LIGHTMAPSHADERCLASS_H
#include "ShaderClass.h"
class LightMapShaderClass : public ShaderClass {
public:
LightMapShaderClass();
//LightMapShaderClass( const LightMapShaderClass& other );
~LightMapShaderClass();
protected:
bool initializeShader();
void shutdownShader();
bool setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, ID3D11ShaderResourceView** pTextures );
void renderShader( int index );
}; // LightMapShaderCLASS
#endif // LIGHTMAPSHADERCLASS_H
LightMapShaderClass.cpp
#include "LightMapShaderClass.h"
// ----------------------------------------------------------------------------
LightMapShaderClass::LightMapShaderClass() : ShaderClass() {
} // LightMapShaderClass
// ----------------------------------------------------------------------------
//LightMapShaderClass::LightMapShaderClass( const LightMapShaderClass& other ) : ShaderClass( other ) {
//} // LightMapShaderClass
// ----------------------------------------------------------------------------
LightMapShaderClass::~LightMapShaderClass() {
} // ~LightMapShaderClass
// ----------------------------------------------------------------------------
bool LightMapShaderClass::initializeShader() {
HRESULT hr;
ID3D10Blob* pErrorMessage;
ID3D10Blob* pVertexShaderBuffer;
ID3D10Blob* pPixelShaderBuffer;
D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
unsigned int uiNumElements;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_SAMPLER_DESC samplerDesc;
// Initialize The Pointers
pErrorMessage = nullptr;
pVertexShaderBuffer = nullptr;
pPixelShaderBuffer = nullptr;
// Compile The Vertex Shader Code
hr = D3DX11CompileFromFile( m_vsFilename, NULL, NULL, "LightMapVertexShader", "vs_4_1", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &pVertexShaderBuffer, &pErrorMessage, NULL );
if ( FAILED( hr ) ) {
// If The Shader Failed To Compile It Should Have Written Something To The Error Message
if ( pErrorMessage ) {
outputShaderErrorMessage( pErrorMessage, m_vsFilename );
}
// If There Was Nothing In The Error Message It Could Not Find The Shader File
else {
MessageBox( m_hWnd, m_vsFilename, L"Missing Shader File", MB_OK );
}
return false;
}
// Compile The Pixel Shader Code
hr = D3DX11CompileFromFile( m_psFilename, NULL, NULL, "LightMapPixelShader", "ps_4_1", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &pPixelShaderBuffer, &pErrorMessage, NULL );
if ( FAILED( hr ) ) {
// If The Shader Failed To Compile It Should Have Written Something To The Error Message
if ( pErrorMessage ) {
outputShaderErrorMessage( pErrorMessage, m_psFilename );
}
// If There Was Nothing In The Error Message It Could Not Find The Shader File
else {
MessageBox( m_hWnd, m_psFilename, L"Missing Shader File", MB_OK );
}
return false;
}
// Create The Vertex Shader From The Buffer
hr = m_pDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), NULL, &m_pVertexShader );
if ( FAILED( hr ) ) {
return false;
}
// Create The Pixel Shader From The Buffer
hr = m_pDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(), pPixelShaderBuffer->GetBufferSize(), NULL, &m_pPixelShader );
if ( FAILED( hr ) ) {
return false;
}
// Create The Vertex Input Layout Description
// This Setup Needs To Match The VertexType Structure In The ModelClass And In The Shader Buffer
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[0].InputSlot = 0;
polygonLayout[0].AlignedByteOffset = 0;
polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[0].InstanceDataStepRate = 0;
polygonLayout[1].SemanticName = "TEXCOORD";
polygonLayout[1].SemanticIndex = 0;
polygonLayout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;
// Get A Count Of The Elements In The Layout
uiNumElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
// Create The Vertex Input Layout
hr = m_pDevice->CreateInputLayout( polygonLayout, uiNumElements, pVertexShaderBuffer->GetBufferPointer(), pVertexShaderBuffer->GetBufferSize(), &m_pLayout );
if ( FAILED( hr ) ) {
return false;
}
// Release The Vertex Shader Buffer And Pixel Shader Buffer Since They Are No Longer Needed
pVertexShaderBuffer->Release();
pVertexShaderBuffer = nullptr;
pPixelShaderBuffer->Release();
pPixelShaderBuffer = nullptr;
// Setup The Description Of The Matrix Dynamic Constant Buffer That Is In The Vertex Shader
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
matrixBufferDesc.MiscFlags = 0;
matrixBufferDesc.StructureByteStride = 0;
// Create The Matrix Constant Buffer Pointer So We Can Access The Vertex Shader Constant Buffer From Within This Class
hr = m_pDevice->CreateBuffer( &matrixBufferDesc, NULL, &m_pMatrixBuffer );
if ( FAILED( hr ) ) {
return false;
}
// Create A Texture Sampler State Description
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
// Create The Texture Sampler State
hr = m_pDevice->CreateSamplerState( &samplerDesc, &m_pSampleState );
if ( FAILED( hr ) ) {
return false;
}
return true;
} // initializeShader
// ----------------------------------------------------------------------------
void LightMapShaderClass::shutdownShader() {
// Release The Sampler State
if ( m_pSampleState ) {
m_pSampleState->Release();
m_pSampleState = nullptr;
}
// Release The Matrix Constant Buffer
if ( m_pMatrixBuffer ) {
m_pMatrixBuffer->Release();
m_pMatrixBuffer = nullptr;
}
// Release The Layout
if ( m_pLayout ) {
m_pLayout->Release();
m_pLayout = nullptr;
}
// Release The Pixel Shader
if ( m_pPixelShader ) {
m_pPixelShader->Release();
m_pPixelShader = nullptr;
}
// Release The Vertex Shader
if ( m_pVertexShader ) {
m_pVertexShader->Release();
m_pVertexShader = nullptr;
}
return;
} // shutdownShader
// ----------------------------------------------------------------------------
bool LightMapShaderClass::setShaderParameters( D3DXMATRIX world, D3DXMATRIX view, D3DXMATRIX projection, ID3D11ShaderResourceView** pTextures ) {
HRESULT hr;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* pData;
unsigned int uiBufferNumber;
// Transpose The Matrices To Prepare Them For The Shader
D3DXMatrixTranspose( &world, &world );
D3DXMatrixTranspose( &view, &view );
D3DXMatrixTranspose( &projection, &projection );
// Lock The Matrix Constant Buffer So It Can Be Written To
hr = m_pDeviceContext->Map( m_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource );
if ( FAILED( hr ) ) {
return false;
}
// Get A Pointer To The Data In The Constant Buffer
pData = (MatrixBufferType*)mappedResource.pData;
// Copy The Matrices Into The Constant Buffer
pData->world = world;
pData->view = view;
pData->projection = projection;
// Unlock The Matrix Constant Buffer
m_pDeviceContext->Unmap( m_pMatrixBuffer, 0 );
// Set The Position Of The Matrix Constant Buffer In The Vertex Shader
uiBufferNumber = 0;
// Now Set The Matrix Constant Buffer In The Vertex Shader With The Updated Values
m_pDeviceContext->VSSetConstantBuffers( uiBufferNumber, 1, &m_pMatrixBuffer );
// Set Shader Texture Array Resource In The Pixel Shader
m_pDeviceContext->PSSetShaderResources( 0, 2, pTextures );
return true;
} // setShaderParameters
// ----------------------------------------------------------------------------
void LightMapShaderClass::renderShader( int indexCount ) {
// Set The Vertex Input Layout
m_pDeviceContext->IASetInputLayout( m_pLayout );
// Set The Vertex And Pixel Shaders That Will Be Used To Render This Triangle
m_pDeviceContext->VSSetShader( m_pVertexShader, NULL, 0 );
m_pDeviceContext->PSSetShader( m_pPixelShader, NULL, 0 );
// Set The Sampler State In The Pixel Shader
m_pDeviceContext->PSSetSamplers( 0, 1, &m_pSampleState );
// Render The Triangles
m_pDeviceContext->DrawIndexed( indexCount, 0, 0 );
return;
} // renderShader
The Function that uses the base class
// ----------------------------------------------------------------------------
bool GraphicsClass::initialize( int iScreenWidth, int iScreenHeight, HWND hWnd ) {
bool bResult;
D3DXMATRIX baseViewMatrix;
// Create The Direct3D Object
m_pD3D = new D3DClass;
if ( !m_pD3D ) {
return false;
}
// Initialize The Direct3D Object
bResult = m_pD3D->initialize( iScreenWidth, iScreenHeight, VSYNC_ENABLED, hWnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR );
if ( !bResult ) {
MessageBox( hWnd, L"Could not initialize Direct3D", L"Error", MB_OK );
return false;
}
// Create The Camera Object
m_pCamera = new Camera;
if ( !m_pCamera ) {
return false;
}
// Initialize The Base View Matrix With The Camera For 2D User Interface Rendering
m_pCamera->setPosition( 0.0f, 0.0f, -1.0f );
m_pCamera->render();
m_pCamera->getViewMatrix( baseViewMatrix );
// Create The Model Object
m_pModel = new ModelClass;
if ( !m_pModel ) {
return false;
}
// Initialize The Model Object
bResult = m_pModel->initialize( m_pD3D->getDevice(), "../DX11Engine/data/square.txt", L"../DX11Engine/data/stone01.dds", L"../DX11Engine/data/light01.dds" );
if ( !bResult ) {
MessageBox( hWnd, L"Could not initialize the model object.", L"Error", MB_OK );
return false;
}
// Create The LightMapTextureShader Object
m_pShader = new LightMapShaderClass;
if ( !_pShader ) {
return false;
}
// Initialize The LightMapTextureShader Object
bResult = _pShader->initialize( _pD3D->getDevice(), _pD3D->getDeviceContext(), hWnd, L"../DX11Engine/lightmap.vs", L"../DX11Engine/lightmap.ps" );
if ( !bResult ) {
MessageBox( hWnd, L"Could not initialize the light map shader object.", L"Error", MB_OK );
return false;
}
return true;
} // initialize
Your doSomethingNotPureVirtual() has different signature in Base class and Derived class
in Base class
bool doSomethingNotPureVirtual( param1, param2, param3, param4, void* pData );
in Derived class
bool settingFunctionPureVirtual( param1, param2, param3, DataType** pMyTypes );
I see you are using C++11 as you use nullptr. try to add override in Drived class, compiler will tell you something
bool settingFunctionPureVirtual( param1, param2, param3, DataType** pMyTypes ) override;
In your psuedo code, your derived class has declared new versions of settingFunctionPureVirtual and doingSomethingPureVirtual rather than providing class specific implementations of the virtual functions that match the declarations in the base class.
The declarations in the your derived class are both missing virtual and they are private instead of protected.

map::insert is breaking

My map::insert method is breaking, without giving me a lot of useful information.
typedef map<wstring, int> IndexLookupMap;
static IndexLookupMap indexLookup;
static vector<LPDIRECT3DTEXTURE9> textures;
extern "C" void EXPORT_API LoadTexture(const wchar_t* file, int* index, unsigned char* data) {
wstring key(file);
if(indexLookup.size() > 0)
{
IndexLookupMap::iterator it = indexLookup.find(key);
if(it == indexLookup.end())
{
//not found, load it
LPDIRECT3DTEXTURE9 pTexture;
D3DXCreateTextureFromFile(g_D3D9Device, file, &pTexture);
textures.push_back(pTexture);
*index = textures.size() - 1;
D3DLOCKED_RECT locked;
pTexture->LockRect(0, &locked, NULL, 0);
data = reinterpret_cast<unsigned char*>(locked.pBits);
pTexture->UnlockRect(0);
indexLookup.insert(IndexLookupMap::value_type(key, *index));
}
else
{
//found, get it
*index = it->second;
textures.at(*index);
}
}
else
{
//not found, load it
LPDIRECT3DTEXTURE9 pTexture;
D3DXCreateTextureFromFile(g_D3D9Device, file, &pTexture);
textures.push_back(pTexture);
*index = textures.size() - 1;
D3DLOCKED_RECT locked;
pTexture->LockRect(0, &locked, NULL, 0);
data = reinterpret_cast<unsigned char*>(locked.pBits);
pTexture->UnlockRect(0);
indexLookup.insert(IndexLookupMap::value_type(key, *index)); //breaks here
}
}
It is breaking on:
indexLookup.insert(IndexLookupMap::value_type(key, *index));
The actual break occurs in xtree:
_Nodeptr _Trynode = _Root();
Based on the minimal information provided I suspect that LoadTexture is being called before your map is constructed, causing it to be in an invalid state.

glCreateShader returns 0

I have a windows build environment using cygwin and GCC, and am linking to the libraries for GLEE, GLUT, and opengl32. This is a Win32 build.
All calls to glCreateShader are returning 0, yet I'm not picking up any errors. The following is based on the Lighthouse tutorials for GLUT and GLSL, so the sequence of GL operations should be correct.
Here's the relevant code..
#define WIN32
#include <stdio.h>
#include <GL/GLee.h>
#include <GL/glut.h>
#include "SampleUtils.h"
#include "LineShaders.h"
GLint lineVertexHandle = 0;
unsigned int lineShaderProgramID;
...
int main(int argc, char **argv) {
// init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Lighthouse3D Tutorials");
// register callbacks
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
// initialize the shaders
init();
// enter GLUT event processing cycle
glutMainLoop();
return 0;
}
void init() {
glClearColor( 0.0, 0.0, 0.0, 1.0 ); /* Set the clear color */
lineShaderProgramID = SampleUtils::createProgramFromBuffer(lineMeshVertexShader,lineFragmentShader);
lineVertexHandle = glGetAttribLocation(lineShaderProgramID,"vertexPosition");
}
SampleUtils is a utility class w/ the following methods for shader handling. The shaders lineMeshVertexShader and lineFragmentShader are defined in LineShaders.h.
unsigned int SampleUtils::createProgramFromBuffer(const char* vertexShaderBuffer, const char* fragmentShaderBuffer) {
checkGlError("cPFB");
// scroll down for initShader() - we never get past this point.
GLuint vertexShader = initShader(GL_VERTEX_SHADER, vertexShaderBuffer);
if (!vertexShader)
return 0;
GLuint fragmentShader = initShader(GL_FRAGMENT_SHADER,
fragmentShaderBuffer);
if (!fragmentShader)
return 0;
GLuint program = glCreateProgram();
if (program)
{
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, fragmentShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength)
{
char* buf = (char*) malloc(bufLength);
if (buf)
{
glGetProgramInfoLog(program, bufLength, NULL, buf);
LOG("Could not link program: %s", buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
unsigned int
SampleUtils::initShader(unsigned int shaderType, const char* source)
{
checkGlError("initShader");
//GLuint shader = glCreateShader((GLenum)shaderType);
/* trying explicit enum, just in case - shader is still always 0 */
GLuint shader = glCreateShader(GL_VERTEX_SHADER);
LOG("SHADER %i", shader);
if (shader)
{
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen)
{
char* buf = (char*) malloc(infoLen);
if (buf)
{
glGetShaderInfoLog(shader, infoLen, NULL, buf);
LOG("Could not compile shader %d: %s",
shaderType, buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
void SampleUtils::checkGlError(const char* operation) {
for (GLint error = glGetError(); error; error = glGetError())
LOG("after %s() glError (0x%x)", operation, error);
}
I'm wondering if the context isn't fully initialized when glCreateShader is called. But I've tried calling init() within the callbacks as well, with no effect. My searches on this issue have turned up the advice to build a known-good example, to confirm the availability of glCreateShader - if anyone has one for C++, pls advise.
UPDATE:
Based on the feedback here I'd checked my OpenGL support using the glewinfo utility and it's reporting that this system is limited to 1.1. - https://docs.google.com/document/d/1LauILzvvxgsT3G2KdRXDTOG7163jpEuwtyno_Y2Ck78/edit?hl=en_US
e.g.
---------------------------
GLEW Extension Info
---------------------------
GLEW version 1.6.0
Reporting capabilities of pixelformat 2
Running on a GDI Generic from Microsoft Corporation
OpenGL version 1.1.0 is supported
GL_VERSION_1_1: OK
---------------
GL_VERSION_1_2: MISSING
---------------
etc.
What's strange is that with GLEE I was able to compile these extensions, though they apparently don't work. I've checked my gl.h and glext.h header files and they are current - the extensions are there. So how is this dealt with on Windows? How do you set up and link your environment so that you can develop w/ more than 1.1 using cygwin and Eclipse?
The solution to this question was provided in the comments, and I'm highlighting it here in order to close this question.
All that was required was a driver upgrade to a version that supports the extensions that I'm using. So I installed NVidia's OpenGL driver, which can be obtained here - http://developer.nvidia.com/opengl-driver
It appears that my system's original NVidia driver was subverted so that the native windows OpenGL driver was being used. This only supports OpenGL 1.1. But I'd mistakenly thought that a GL_VERSION of 1.1.0 was normal on Windows - based on some bad advice I'd gotten. And the fact that I was able to compile and execute this code without errors led me to assume that the extensions were present. They were not.
I have had the same problem, but it was a silly C++ language trick : my shader was compiled in a global / static variable (which was a wrapper class to use program shader), which was so initialized before having a GL context. Hope it can help...