I am getting 28
error LNK2001: unresolved external symbol
messages. I know for a fact, for example, that
glBindVertexArray
is in _int_gl_exts.h, and sure enough I am including it.
#include <glload\_int_gl_exts.h>
I don't know if this is a problem, but there are three underscore characters in my error message
symbol ___gleBindVertexArray
Whereas in the file, there is only two underscores before it. This is the exact line inside the include file
extern PFNGLBINDVERTEXARRAYPROC __gleBindVertexArray;
#define glBindVertexArray __gleBindVertexArray
I am pulling much of my stuff directly from a tutorial, and even when my includes and functions are the same, I still have problems. I'll post full code if necessary, but I am out of ideas after about 2 days stuck here.
EDIT: I do in fact have both
#pragma comment(lib, "opengl32.lib")
as well as I tried changing the Project Properties in Linker to add this to additional libraries.
My entire code is as follows. I understand there's a lot of other stuff that needs changed, but this is what I'm trying to get past first.
#include <algorithm>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <exception>
#include <stdexcept>
#include <string.h>
#include <glload/gl_3_3.h>
#include <glload/gll.hpp>
#include <glutil/Shader.h>
#include <GL/freeglut.h>
#include "framework.h"
#include "directories.h"
#include <glload/_int_gl_exts.h>
#ifdef LOAD_X11
#define APIENTRY
#endif
namespace Framework
{
GLuint LoadShader(GLenum eShaderType, const std::string &strShaderFilename)
{
std::string strFilename = FindFileOrThrow(strShaderFilename);
std::ifstream shaderFile(strFilename.c_str());
std::stringstream shaderData;
shaderData << shaderFile.rdbuf();
shaderFile.close();
try
{
return glutil::CompileShader(eShaderType, shaderData.str());
}
catch(std::exception &e)
{
fprintf(stderr, "%s\n", e.what());
throw;
}
}
GLuint CreateProgram(const std::vector<GLuint> &shaderList)
{
try
{
GLuint prog = glutil::LinkProgram(shaderList);
std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader);
return prog;
}
catch(std::exception &e)
{
std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader);
fprintf(stderr, "%s\n", e.what());
throw;
}
}
float DegToRad(float fAngDeg)
{
const float fDegToRad = 3.14159f * 2.0f / 360.0f;
return fAngDeg * fDegToRad;
}
std::string FindFileOrThrow( const std::string &strBasename )
{
std::string strFilename = LOCAL_FILE_DIR + strBasename;
std::ifstream testFile(strFilename.c_str());
if(testFile.is_open())
return strFilename;
strFilename = GLOBAL_FILE_DIR + strBasename;
testFile.open(strFilename.c_str());
if(testFile.is_open())
return strFilename;
throw std::runtime_error("Could not find the file " + strBasename);
}
}
void init();
void display();
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);
unsigned int defaults(unsigned int displayMode, int &width, int &height);
void APIENTRY DebugFunc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar* message, GLvoid* userParam)
{
std::string srcName;
switch(source)
{
case GL_DEBUG_SOURCE_API_ARB: srcName = "API"; break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: srcName = "Window System"; break;
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: srcName = "Shader Compiler"; break;
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: srcName = "Third Party"; break;
case GL_DEBUG_SOURCE_APPLICATION_ARB: srcName = "Application"; break;
case GL_DEBUG_SOURCE_OTHER_ARB: srcName = "Other"; break;
}
std::string errorType;
switch(type)
{
case GL_DEBUG_TYPE_ERROR_ARB: errorType = "Error"; break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: errorType = "Deprecated Functionality"; break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: errorType = "Undefined Behavior"; break;
case GL_DEBUG_TYPE_PORTABILITY_ARB: errorType = "Portability"; break;
case GL_DEBUG_TYPE_PERFORMANCE_ARB: errorType = "Performance"; break;
case GL_DEBUG_TYPE_OTHER_ARB: errorType = "Other"; break;
}
std::string typeSeverity;
switch(severity)
{
case GL_DEBUG_SEVERITY_HIGH_ARB: typeSeverity = "High"; break;
case GL_DEBUG_SEVERITY_MEDIUM_ARB: typeSeverity = "Medium"; break;
case GL_DEBUG_SEVERITY_LOW_ARB: typeSeverity = "Low"; break;
}
printf("%s from %s,\t%s priority\nMessage: %s\n",
errorType.c_str(), srcName.c_str(), typeSeverity.c_str(), message);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
int width = 500;
int height = 500;
unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
displayMode = defaults(displayMode, width, height);
glutInitDisplayMode (displayMode);
glutInitContextVersion (3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
#ifdef DEBUG
glutInitContextFlags(GLUT_DEBUG);
#endif
glutInitWindowSize (width, height);
glutInitWindowPosition (300, 200);
int window = glutCreateWindow (argv[0]);
glload::LoadFunctions();
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
if(!glload::IsVersionGEQ(3, 3))
{
printf("Your OpenGL version is %i, %i. You must have at least OpenGL 3.3 to run this tutorial.\n",
glload::GetMajorVersion(), glload::GetMinorVersion());
glutDestroyWindow(window);
return 0;
}
if(glext_ARB_debug_output)
{
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(DebugFunc, (void*)15);
}
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
#pragma comment(lib, "opengl32.lib")
#include <string>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <glload/gl_3_3.h>
#include <glload\_int_gl_exts.h>
#include <GL/freeglut.h>
#include <glload\_int_gl_1_5.h>
#include <glload\_int_gl_1_1_rem_3_1.h>
#include "../../framework/framework.h"
#define GL_GLEXT_PROTOTYPES
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
GLuint theProgram;
GLuint elapsedTimeUniform;
void InitializeProgram()
{
std::vector<GLuint> shaderList;
shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, "calcOffset.vert"));
shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "calcColor.frag"));
theProgram = Framework::CreateProgram(shaderList);
elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
GLuint fragLoopDurUnf = glGetUniformLocation(theProgram, "fragLoopDuration");
glUseProgram(theProgram);
glUniform1f(loopDurationUnf, 5.0f);
glUniform1f(fragLoopDurUnf, 10.0f);
glUseProgram(0);
}
const float vertexPositions[] = {
0.25f, 0.25f, 0.0f, 1.0f,
0.25f, -0.25f, 0.0f, 1.0f,
-0.25f, -0.25f, 0.0f, 1.0f,
};
GLuint positionBufferObject;
GLuint vao;
void createCube() {
glBegin(GL_LINES);
glLineWidth(99.0);
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5,0.5,0.5 );
glVertex3f( 0.5,0.5,-0.5 );
glVertex3f( 0.5,0.5,-0.5 );
glVertex3f( -0.5,0.5,-0.5 );
glVertex3f( -0.5,0.5,-0.5 );
glVertex3f( -0.5,0.5,0.5 );
glVertex3f( -0.5,0.5,0.5 );
glVertex3f( 0.5,0.5,0.5 );
glVertex3f( 0.5,-0.5,0.5 );
glVertex3f( 0.5,-0.5,-0.5 );
glVertex3f( 0.5,-0.5,-0.5 );
glVertex3f( -0.5,-0.5,-0.5 );
glVertex3f( -0.5,-0.5,-0.5 );
glVertex3f( -0.5,-0.5,0.5 );
glVertex3f( -0.5,-0.5,0.5 );
glVertex3f( 0.5,-0.5,0.5 );
glVertex3f( 0.5,0.5,0.5 );
glVertex3f( 0.5,-0.5,0.5 );
glVertex3f( -0.5,-0.5,-0.5 );
glVertex3f( -0.5,0.5,-0.5 );
glVertex3f( 0.5,0.5,-0.5 );
glVertex3f( 0.5,-0.5,-0.5 );
glVertex3f( -0.5,0.5,0.5 );
glVertex3f( -0.5,-0.5,0.5 );
glEnd();
}
void InitializeVertexBuffer()
{
glGenBuffers(1, &positionBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void init()
{
InitializeProgram();
InitializeVertexBuffer();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
//Called to update the display.
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(theProgram);
glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
createCube();
glColor3f(1.0,0.0,0.0);
glutSolidSphere(0.04,10,10);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glUseProgram(0);
glutSwapBuffers();
glutPostRedisplay();
}
//Called whenever the window is resized. The new window size is given, in pixels.
//This is an opportunity to call glViewport or glScissor to keep up with the change in size.
void reshape (int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
}
//Called whenever a key on the keyboard was pressed.
//The key is given by the ''key'' parameter, which is in ASCII.
//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to
//exit the program.
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
glutLeaveMainLoop();
return;
}
}
unsigned int defaults(unsigned int displayMode, int &width, int &height) {return displayMode;}
It would be good if you actually stated what library you were trying to link to. The only reason I know which one it is is because I recognize my own work ;)
In any case, the documentation makes it clear what library you should link to. If you're using the Premake4 build system, then you should just have UseLibs {"glload"} in your premake4.lua project. If you're using something else, then you need to manually link to glloadD or glload in debug and release respectively. On Windows, you need a .lib suffix; on Linux, you would use libglloadD and such.
Whether you link with a pragma or use the project settings is irrelevant.
Including the declarations is one thing; their definitions are another.
You must link against the OpenGL library when you build your executable.
Follow the instructions in your OpenGL book or reference, but typically you'll pass something like -lopengl32 to your build command; it looks like you might be using Visual Studio, which handles the specific build command for you, in which case you should add the OpenGL libraries to your project properties or use #pragma:
#pragma comment(lib, "opengl32.lib")
You probably didn't link the opengl lib file.
In your compiler settings, add to the list of included libraries "opengl32.lib".
Related
i'm working in this project (https://github.com/lupeeumeeu/WorldCraft), everything works fine, i can change the background color, but it doesn't render the triangle, i tried to set tons and tons of breakpoints, but couldn't find any problem, i think the problem should be around trhe triangle.cpp or the managers, i tried to follow the in2gpu's tutorial but i also modified a little bit.
An image link to explain just a bit:
https://imgur.com/a/HN7t2
Main.cpp:
#include "..\WorldCraft\Core\Init\Init.h"
#include "Core\Managers\Scene_Manager.h"
#include "Core\Render\Triangle.h"
using namespace Core;
using namespace Init;
int main(int argc, char **argv)
{
WindowConfig windowconfig(std::string("WorldCraft"), 800, 600, 400, 200, true);//name, x, y, w, h, reshape
OpenGLVersion version(4, 5, true);//M.m version opengl, msaa
BufferConfig bufferconfig(true, true, true, true); // Buffers
Core::Init::Init::Initialize(windowconfig, version, bufferconfig, argc, argv);
Core::Managers::Scene_Manager* mainMenu = new Core::Managers::Scene_Manager();
Core::Init::Init::SetListener(mainMenu);
Core::Render::Triangle* triangle = new Core::Render::Triangle();
triangle->SetProgram(Core::Managers::Shader_Manager::GetShader("CommonShader"));
triangle->Create();
mainMenu->GetModels_Manager()->SetModel("triangle", triangle);
Core::Init::Init::Run();
delete mainMenu;
return 0;
}
Scene_Manager.cpp:
#include "Scene_Manager.h"
using namespace Core;
using namespace Managers;
Scene_Manager::Scene_Manager()
{
glEnable(GL_DEPTH_TEST);
shader_manager = new Shader_Manager();
shader_manager->CreateProgram("CommonShader", "Core//Shaders//Common//Vertex_Shader.glsl"
, "Core//Shaders//Common//Fragment_Shader.glsl");
view_matrix = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 0.0f, 10.0f, 1.0f);
models_manager = new Models_Manager();
}
Scene_Manager::~Scene_Manager()
{
delete shader_manager;
delete models_manager;
}
void Scene_Manager::NotifyBeginFrame()
{
models_manager->Update();
}
void Scene_Manager::NotifyDisplayFrame()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
models_manager->Draw();
models_manager->Draw(projection_matrix, view_matrix);
}
void Scene_Manager::NotifyEndFrame()
{
}
void Scene_Manager::NotifyReshape(int width, int height, int previous_width, int previous_height)
{
float ar = (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT);
float angle = 45.0f, near1 = 0.1f, far1 = 2000.0f;
projection_matrix[0][0] = 1.0f / (ar * tan(angle / 2.0f));
projection_matrix[1][1] = 1.0f / tan(angle / 2.0f);
projection_matrix[2][2] = (-near1 - far1) / (near1 - far1);
projection_matrix[2][3] = 1.0f;
projection_matrix[3][2] = 2.0f * near1 * far1 / (near1 - far1);
}
Core::Managers::Models_Manager* Scene_Manager::GetModels_Manager()
{
return models_manager;
}
Scene_Manager.h:
#pragma once
#include "Models_Manager.h"
#include "Shader_Manager.h"
#include "../Init/FrameNotifier.h"
namespace Core
{
namespace Managers
{
class Scene_Manager : public Init::FrameNotifier
{
public:
Scene_Manager();
~Scene_Manager();
virtual void NotifyBeginFrame();
virtual void NotifyDisplayFrame();
virtual void NotifyEndFrame();
virtual void NotifyReshape(int width, int height, int previous_width, int previous_height);
Managers::Models_Manager* GetModels_Manager();
private:
Core::Managers::Shader_Manager* shader_manager;
Core::Managers::Models_Manager* models_manager;
glm::mat4 projection_matrix;
glm::mat4 view_matrix;
};
}
}
Models_Manager.cpp:
#include "Models_Manager.h"
using namespace Core::Managers;
using namespace Core::Render;
Models_Manager::Models_Manager()
{
Triangle* triangle = new Triangle();
triangle->SetProgram(Shader_Manager::GetShader("CommonShader"));
triangle->Create();
gameModelList_NDC["triangle"] = triangle;
}
Models_Manager::~Models_Manager()
{
for (auto model : gameModelList)
{
delete model.second;
}
gameModelList.clear();
for (auto model : gameModelList_NDC)
{
delete model.second;
}
gameModelList_NDC.clear();
}
void Models_Manager::Update()
{
for (auto model : gameModelList)
{
model.second->Update();
}
for (auto model : gameModelList_NDC)
{
model.second->Update();
}
}
void Models_Manager::Draw()
{
for (auto model : gameModelList_NDC)
{
model.second->Draw();
}
}
void Models_Manager::Draw(const glm::mat4& projection_matrix, const glm::mat4& view_matrix)
{
for (auto model : gameModelList)
{
model.second->Draw(projection_matrix, view_matrix);
}
}
void Models_Manager::DeleteModel(const std::string& gameModelName)
{
IGameObject* model = gameModelList[gameModelName];
model->Destroy();
gameModelList.erase(gameModelName);
}
void Models_Manager::DeleteModel_NDC(const std::string& gameModelName)
{
IGameObject* model = gameModelList_NDC[gameModelName];
model->Destroy();
gameModelList_NDC.erase(gameModelName);
}
const IGameObject& Models_Manager::GetModel(const std::string& gameModelName) const
{
return (*gameModelList.at(gameModelName));
}
const IGameObject& Models_Manager::GetModel_NDC(const std::string& gameModelName) const
{
return (*gameModelList_NDC.at(gameModelName));
}
void Models_Manager::SetModel(const std::string& gameObjectName, IGameObject* gameObject)
{
gameModelList[gameObjectName.c_str()] = gameObject;
}
Triangle.cpp:
#include "Triangle.h"
using namespace Core;
using namespace Render;
Triangle::Triangle(){}
Triangle::~Triangle(){}
static void PrintError(GLenum errorCode)
{
switch (errorCode)
{
case GL_NO_ERROR:
break;
case GL_INVALID_ENUM:
std::cout << "An unacceptable value is specified for an enumerated argument.";
break;
case GL_INVALID_VALUE:
std::cout << "A numeric argument is out of range.";
break;
default:
break;
}
}
void Triangle::Create()
{
GLuint vao;
GLuint vbo;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
std::vector<VertexFormat> vertices;
vertices.push_back(VertexFormat(glm::vec3(0.25, -0.25, -1.0), glm::vec4(1, 0, 0, 1)));
vertices.push_back(VertexFormat(glm::vec3(-0.25, -0.25, -1.0), glm::vec4(0, 1, 0, 1)));
vertices.push_back(VertexFormat(glm::vec3(0.25, 0.25, -1.0), glm::vec4(0, 0, 1, 1)));
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
PrintError(glGetError());
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexFormat) * 3, &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexFormat), (void*)(offsetof(VertexFormat, VertexFormat::color)));
glBindVertexArray(0);
this->vao = vao;
this->vbos.push_back(vbo);
}
void Triangle::Update() {}
void Triangle::Draw()
{
glUseProgram(program);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
I found the error, it was the duplicated triangle, without the camera configuration (view_matrix and projection_matrix)
I have problem understanding some opengl stuff using GLFW and GLEW.
i have 3 files shown below:
main.cpp:
#include "gamewindow.h"
int main() {
GameWindow *gameWindow = new GameWindow(1024, 768, "FirstOpenGLGame");
/* Loop until the user closes the window */
while (gameWindow->getRunning()) {
/* Render here */
gameWindow->render();
gameWindow->update();
gameWindow->setRunning();
}
delete gameWindow;
glfwTerminate();
return 0;
}
This is where the problem is, gamewindow.cpp:
#include "gamewindow.h"
GameWindow::GameWindow(int width, int height, const char* title) : _running(true), _height(1024), _width(1024 * (16/9))
{
/* Initialize the library */
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(width, height, title, NULL, NULL);
if(!window) {
glfwTerminate();
exit(0);
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if(!glewInit()){ // <-- problem is this
glfwTerminate();
exit(EXIT_FAILURE);
}
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
coordSettings();
}
void GameWindow::setRunning() {
_running = !glfwWindowShouldClose(window);
}
bool GameWindow::getRunning() {
return _running;
}
void GameWindow::render() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2d(0.0f, 0.0f);
glVertex2d(100.0f, 0.0f);
glVertex2d(100.0f, 800.0f);
glVertex2d(0.0f, 800.0f);
glEnd();
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
void GameWindow::update() {
}
void GameWindow::coordSettings() {
glViewport( 0, 0, _width, _height );
glMatrixMode(GL_PROJECTION);
glOrtho(0.0, _width, 0.0, _height, 0.0, -1.0);
glMatrixMode(GL_MODELVIEW);
}
and last the header file gamewindow.h:
#ifndef GAMEWINDOW_H
#define GAMEWINDOW_H
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class GameWindow
{
private:
GLFWwindow* window;
bool _running;
GLfloat _width;
GLfloat _height;
void coordSettings();
public:
GameWindow(int width, int height, const char* title);
void setRunning();
bool getRunning();
void render();
void update();
};
#endif // GAMEWINDOW_H
everything works fine, but then i try to call glewInit() (without really understanding is i need to, or when i need to) but then nothing works. the program starts, but there is no window with a quad in it, like before. why is this? how is GLEW even used, and do i need it?
I am trying to setup a little CUDA/GL interop example. I have looked around in the internet, so I found some tutorials with some helpful stuff.
All I want is, is to produce a texture in CUDA and draw it with OpenGL.
The source I have now is crashing my Macbook Pro every time I run it, so I thought that if somebody could take an eye on it, that would be really helpful.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef _WIN32
# define WINDOWS_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
#endif
// OpenGL Graphics includes
#include <GL/glew.h>
#if defined (__APPLE__) || defined(MACOSX)
#include <GLUT/glut.h>
#else
#include <GL/freeglut.h>
#endif
// includes, cuda
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
// Utilities and timing functions
#include <helper_functions.h> // includes cuda.h and cuda_runtime_api.h
#include <timer.h> // timing functions
// CUDA helper functions
#include <helper_cuda.h> // helper functions for CUDA error check
#include <helper_cuda_gl.h> // helper functions for CUDA/GL interop
#include <vector_types.h>
const unsigned int window_width = 512;
const unsigned int window_height = 512;
GLuint viewGLTexture;
cudaGraphicsResource_t viewCudaResource;
void initGLandCUDA() {
int argc = 0;
char** argv = NULL;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("CUDA GL Interop");
glewInit();
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &viewGLTexture);
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glBindTexture(GL_TEXTURE_2D, 0);
cudaGLSetGLDevice(gpuGetMaxGflopsDeviceId());
cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard);
}
__global__ void renderingKernel(cudaSurfaceObject_t image) {
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
uchar4 color = make_uchar4(0.f, 0.f, 0.f, .3f);
//if I write in 0, 0 and not x,y, the computer is not crashing, but there is no black pixel at 0,0
surf2Dwrite(color, image, x, y, cudaBoundaryModeClamp);
}
void callCUDAKernel(cudaSurfaceObject_t image) {
dim3 block(8, 1, 1);
dim3 grid(8, 1, 1);
renderingKernel<<< grid, block>>>(image);
}
void renderFrame() {
cudaGraphicsMapResources(1, &viewCudaResource);
{
cudaArray_t viewCudaArray;
checkCudaErrors(cudaGraphicsSubResourceGetMappedArray(&viewCudaArray, viewCudaResource, 0, 0));
cudaResourceDesc viewCudaArrayResourceDesc;
{
viewCudaArrayResourceDesc.resType = cudaResourceTypeArray;
viewCudaArrayResourceDesc.res.array.array = viewCudaArray;
}
cudaSurfaceObject_t viewCudaSurfaceObject;
checkCudaErrors(cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc));
callCUDAKernel(viewCudaSurfaceObject);
checkCudaErrors(cudaDestroySurfaceObject(viewCudaSurfaceObject));
}
checkCudaErrors(cudaGraphicsUnmapResources(1, &viewCudaResource));
checkCudaErrors(cudaStreamSynchronize(0));
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(+1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(+1.0f, +1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, +1.0f);
}
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
}
int main(int argc, char **argv)
{
initGLandCUDA();
glutDisplayFunc(renderFrame);
//glutKeyboardFunc(keyboard);
//glutMouseFunc(mouse);
glutMainLoop();
}
It seems like some kind of out-of-range error, but I am currently out of ideas (btw, this is cc 3.0, running to nVidia 650M).
Edit :
By crashing I mean : crashing. Computer freezes. I can't move my mouse and I have to reboot.
Yes, I have looked in all examples, they are not exactly what I want. Changing them to be want I want results in this problem. If there was any other help in the manual or anywhere else that would help me and I have found I would not bother asking for help. You need to link with cuda_runtime and glut libs
Below is a working version of your code. The issues in your code were:
Your kernel was depending on being launched with 512x512 threads, but you were only launching with 64x1 threads.
Your kernel was writing to unaligned addresses with surf2Dwrite().
You were setting up double buffering in OpenGL but you were not swapping the buffers. (glutSwapBuffers()).
You were initializing an uchar4 with floats.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef _WIN32
# define WINDOWS_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
#endif
// OpenGL Graphics includes
#include <GL/glew.h>
#if defined (__APPLE__) || defined(MACOSX)
#include <GLUT/glut.h>
#else
#include <GL/freeglut.h>
#endif
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
#include <vector_types.h>
const unsigned int window_width = 512;
const unsigned int window_height = 512;
GLuint viewGLTexture;
cudaGraphicsResource_t viewCudaResource;
#define check(ans) { _check((ans), __FILE__, __LINE__); }
inline void _check(cudaError_t code, char *file, int line)
{
if (code != cudaSuccess) {
fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), file, line);
exit(code);
}
}
void initGLandCUDA() {
int argc = 0;
char** argv = NULL;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("CUDA GL Interop");
glewInit();
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &viewGLTexture);
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
check(cudaGLSetGLDevice(0));
check(cudaGraphicsGLRegisterImage(&viewCudaResource, viewGLTexture, GL_TEXTURE_2D, cudaGraphicsRegisterFlagsWriteDiscard));
}
__global__ void renderingKernel(cudaSurfaceObject_t image) {
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
uchar4 color = make_uchar4(x / 2, y / 2, 0, 127);
surf2Dwrite(color, image, x * sizeof(color), y, cudaBoundaryModeClamp);
}
void callCUDAKernel(cudaSurfaceObject_t image) {
dim3 block(256, 1, 1);
dim3 grid(2, 512, 1);
renderingKernel<<<grid, block>>>(image);
check(cudaPeekAtLastError());
check(cudaDeviceSynchronize());
}
void renderFrame() {
check(cudaGraphicsMapResources(1, &viewCudaResource));
cudaArray_t viewCudaArray;
check(cudaGraphicsSubResourceGetMappedArray(&viewCudaArray, viewCudaResource, 0, 0));
cudaResourceDesc viewCudaArrayResourceDesc;
memset(&viewCudaArrayResourceDesc, 0, sizeof(viewCudaArrayResourceDesc));
viewCudaArrayResourceDesc.resType = cudaResourceTypeArray;
viewCudaArrayResourceDesc.res.array.array = viewCudaArray;
cudaSurfaceObject_t viewCudaSurfaceObject;
check(cudaCreateSurfaceObject(&viewCudaSurfaceObject, &viewCudaArrayResourceDesc));
callCUDAKernel(viewCudaSurfaceObject);
check(cudaDestroySurfaceObject(viewCudaSurfaceObject));
check(cudaGraphicsUnmapResources(1, &viewCudaResource));
check(cudaStreamSynchronize(0));
glBindTexture(GL_TEXTURE_2D, viewGLTexture);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(+1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(+1.0f, +1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, +1.0f);
}
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
}
int main(int argc, char **argv)
{
initGLandCUDA();
glutDisplayFunc(renderFrame);
//glutKeyboardFunc(keyboard);
//glutMouseFunc(mouse);
glutMainLoop();
}
Output:
I want to start working with OpenGL 3+ and 4 but I'm having problems getting Glew to work. I have tried to include the glew32.lib in the Additional Dependencies and I have moved the library, and .dll into the main folder so there shouldn't be any path problems. The errors I'm getting are:
Error 5 error LNK2019: unresolved external symbol __imp__glewInit referenced in function "void __cdecl init(void)" (?init##YAXXZ) C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 4 error LNK2019: unresolved external symbol __imp__glewGetErrorString referenced in function "void __cdecl init(void)" (?init##YAXXZ) C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 3 error LNK2001: unresolved external symbol __imp____glewGenBuffers C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 1 error LNK2001: unresolved external symbol __imp____glewBufferData C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 2 error LNK2001: unresolved external symbol __imp____glewBindBuffer C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
And here is most of my code:
#define NOMINMAX
#include <vector>
#include <memory>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <Windows.h>
#include <cstdio>
#include <time.h>
#include "GL\glew.h"
#include "glut.h"
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "opengl32.lib")
using namespace std;
GLsizei screen_width, screen_height;
float camera[3] = {0.0f, 10.0f, -15.0f};
float xPos = 0;
float yPos = 10;
float zPos = -15;
float orbitDegrees = 0;
clock_t sTime;
float fPS;
int fCount;
GLdouble* modelV;
GLdouble* projM;
GLint* vPort;
//Lights settings
GLfloat light_ambient[]= { 0.1f, 0.1f, 0.1f, 0.1f };
GLfloat light_diffuse[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_position[]= { 100.0f, 0.0f, -10.0f, 1.0f };
//Materials settings
GLfloat mat_ambient[]= { 0.5f, 0.5f, 0.0f, 0.0f };
GLfloat mat_diffuse[]= { 0.5f, 0.5f, 0.0f, 0.0f };
GLfloat mat_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_shininess[]= { 1.0f };
typedef struct Vectors {
float x;
float y;
float z;
}Vector;
typedef struct Polys {
Vector v;
Vector vt;
Vector vn;
int texture;
} Poly;
vector<Vector> vecs;
vector<Vector> normVecs;
vector<Vector> textVecs;
vector<Poly> polyList;
void loadModel(string filepath);
void createTex(string ref);
void render();
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
void render()
{
}
void createTex(string ref)
{
}
void loadModel(string filepath)
{
}
void resize (int p_width, int p_height)
{
if(screen_width==0 && screen_height==0) exit(0);
screen_width=p_width; // Obtain the new screen width values and store it
screen_height=p_height; // Height value
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear both the color and the depth buffer so to draw the next frame
glViewport(0,0,screen_width,screen_height); // Viewport transformation
glMatrixMode(GL_PROJECTION); // Projection transformation
glLoadIdentity(); // Initialize the projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,1.0f,10000.0f);
glutPostRedisplay(); // This command redraw the scene (it calls the same routine of glutDisplayFunc)
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This clear the background color to dark blue
glMatrixMode(GL_MODELVIEW); // Modeling transformation
glPushMatrix();
glLoadIdentity(); // Initialize the model matrix as identity
gluLookAt(xPos, yPos, zPos, /* look from camera XYZ */
0, yPos, 0, /* look at the origin */
0, 1, 0); /* positive Y up vector */
glRotatef(orbitDegrees, 0.f, 1.0f, 0.0f);
//glTranslatef(0.0,0.0,-20); // We move the object forward (the model matrix is multiplied by the translation matrix)
//rotation_x = 30;
//rotation_x = rotation_x + rotation_x_increment;
//rotation_y = rotation_y + rotation_y_increment;
//rotation_z = rotation_z + rotation_z_increment;
//if (rotation_x > 359) rotation_x = 0;
//if (rotation_y > 359) rotation_y = 0;
//if (rotation_z > 359) rotation_z = 0;
// glRotatef(rotation_x,1.0,0.0,0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices)
//glRotatef(rotation_y,0.0,1.0,0.0);
// glRotatef(rotation_z,0.0,0.0,1.0);
//if (objarray[0]->id_texture!=-1)
//{
// glBindTexture(GL_TEXTURE_2D, objarray[0]->id_texture); // We set the active texture
// glEnable(GL_TEXTURE_2D); // Texture mapping ON
// printf("Txt map ON");
//}
//else
// glDisable(GL_TEXTURE_2D); // Texture mapping OFF
glGetDoublev(GL_PROJECTION_MATRIX, modelV);
glGetDoublev(GL_PROJECTION_MATRIX, projM);
glGetIntegerv(GL_VIEWPORT, vPort);
if(clock() > sTime)
{
fPS = fCount;
fCount = 0;
sTime = clock() + CLOCKS_PER_SEC;
}
render();
glDisable(GL_LIGHTING);
GLdouble pos[3];
gluUnProject(100, yPos, -14, modelV, projM, vPort, &pos[0], &pos[1], &pos[2]);
char buffer2[255];
int pAmmount = sprintf(buffer2,"FPS: %.2f", fPS);
//glRasterPos3f(pos[0], pos[1], pos[2]);
for(int i = 0; i < pAmmount; i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buffer2[i]);
}
glEnable(GL_LIGHTING);
/*glPopMatrix();
glPushMatrix();
glTranslatef(5.0,0.0,-20.0);
objarray[1]->render();*/
glPopMatrix();
glFlush(); // This force the execution of OpenGL commands
glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer
fCount++;
}
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 'w':
yPos++;
break;
case 's':
yPos--;
break;
case 'a':
xPos--;
break;
case 'd':
xPos++;
break;
case 'q':
orbitDegrees--;
break;
case 'e':
orbitDegrees++;
break;
case 'z':
zPos--;
break;
case 'x':
zPos++;
break;
}
}
void initWindow(GLsizei screen_width, GLsizei screen_height)
{
glClearColor(0.0, 0.0, 0.0, 0.0); // Clear background color to black
// Viewport transformation
glViewport(0,0,screen_width,screen_height);
// Projection transformation
glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations
glLoadIdentity(); // We initialize the projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,1.0f,10000.0f); // We define the "viewing volume"
gluLookAt(camera[0], camera[1], camera[2], /* look from camera XYZ */
0, 0, 0, /* look at the origin */
0, 1, 0); /* positive Y up vector */
try
{
//loadModel("Goku habit dechiré.obj");
loadModel("Flooring.obj");;
}
catch(string& filepath)
{
cerr << "Model could not be loaded: " << filepath << endl;
filepath = "Model could not be loaded: " + filepath;
wostringstream sString;
sString << filepath.c_str();
MessageBox(HWND_DESKTOP, sString.str().c_str(), L"Error: loadModel(string filepath)", MB_OK);
}
//Lights initialization and activation
glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_specular);
glLightfv (GL_LIGHT1, GL_POSITION, light_position);
glEnable (GL_LIGHT1);
glEnable (GL_LIGHTING);
//Materials initialization and activation
glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_specular);
glMaterialfv (GL_FRONT, GL_POSITION, mat_shininess);
//Other initializations
glShadeModel(GL_SMOOTH); // Type of shading for the polygons
//glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Texture mapping perspective correction
//glEnable(GL_TEXTURE_2D); // Texture mapping ON
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
glEnable(GL_CULL_FACE); // Enable the back face culling
glEnable(GL_DEPTH_TEST); // Enable the depth test
glEnable(GL_NORMALIZE);
/*float* matrix = new float[16];
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
for(int i = 0; i < 4; i++)
{
cout << matrix[0] << " " << matrix[1] << " " << matrix[2] << " " << matrix[3] << endl;
matrix += 3;
}*/
modelV = new GLdouble[16];
projM = new GLdouble[16];
vPort = new GLint[4];
sTime = clock() + CLOCKS_PER_SEC;
}
void init()
{
GLenum GlewInitResult;
GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) {
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
}
int main(int argc, char **argv)
{
screen_width = 800;
screen_height = 800;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_width,screen_height);
glutInitWindowPosition(0,0);
glutCreateWindow("ModelLoader");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc (resize);
glutKeyboardFunc(keyboard);
//glutKeyboardFunc(keyboard);
//glutSpecialFunc(keyboard_s);
initWindow(screen_width, screen_height);
init();
glutMainLoop();
return 0;
}
You have a linkage problem. You are not providing to the linker the correct path to the glew lib file. For this reason the linker is not able to find the compiled code of the functions you are calling.
From your log it seems you are working on Windows. If you are using Visual Studio, right click on you project. Select Linker, and then Input. Verify that Additional dependencies contains the path to glew lib.
Notice that the dll is not required at linking time. This will be loaded only at run time (remember to put it in the same folder as your executable or in a path listed in your system path).
This has been fixed. The problem was only represented on the machine I was using in University. The problem was that the machine had an older .dll which was conflicting with the .dll that I had in the solution files. It was installed in the System files of the machine. As such it was producing these errors.
I should probably check for such a thing next time.
Not sure how it will help you but, you might give a try and statically link your project to a ".a" library. or it's .lib on windows. If there are unresolved symbol it means it tried to link to a library and not really to a dll.
If it was using the dll, it would probably fail at runtime.
I am currently using the Code::Blocks IDE, c++, opengl and SDL to make a game- and I have hit a severe block in road, if you will. I am using SDL_image to load these jpg images for the textures, but they just will not load. Currently, I have tried placing them in every folder in the project, even places where it would supposedly make no difference. I have tried running both the debug and release versions from the IDE, by double-clicking the executable, and by running the executable from the command line. They all produce the same error: Could not load image: "the path to my image". I have tried using full paths, I have tried using relative paths, I have tried just about everything. I have tried various image formats, to no success. Other useful information may be: I am using ubuntu 11.04, I am using GIMP to create the images, and this is my code in complete (I'm sure most of it is irrelevant, but I am just putting it all down just-in-case):
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <Cg/cg.h>// NEW: Cg Header
#include <Cg/cgGL.h>// NEW: Cg OpenGL Specific Header
#include <iostream>
#include <math.h>
#include <string>
#include "../include/Camera.h"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Keydown booleans
bool key[321];
Uint8 *keystate;
float fogDensity = 0.02f;
static float fog_color[] = { 0.8f, 0.8f, 0.8f, 1.0f };
// Process pending events
bool events()
{
SDL_Event event;
if( !SDL_PollEvent(&event) ){
return true;
}
switch( event.type )
{
case SDL_KEYDOWN : key[ event.key.keysym.sym ]=true; break;
case SDL_KEYUP : key[ event.key.keysym.sym ]=false; break;
case SDL_QUIT : return false; break; //one-per-keypress
}
keystate = SDL_GetKeyState(NULL); //continuous
return true;
}
// Initialze OpenGL perspective matrix
void setup(int width, int height)
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glEnable( GL_DEPTH_TEST );
gluPerspective( 45, (float)width/height, 0.1, 100 );
glMatrixMode( GL_MODELVIEW );
}
Camera* cam = new Camera();
GLuint rocktexture; // This is a handle to our texture object
GLuint earthtexture;
//add some default materials here
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 0.0f, 1.0f, 0.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
void MouseUpdate() {
int x, y;
SDL_GetMouseState(&x,&y);
SDL_WarpMouse(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
cam->yaw+=(x-WINDOW_WIDTH/2)*0.2;
cam->pitch+=(y-WINDOW_HEIGHT/2)*0.2;
if(cam->pitch<-90) {
cam->pitch=-90;
}
if(cam->pitch>90) {
cam->pitch=90;
}
}
static void display(void)
{
while(events())
{
MouseUpdate();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(cam->pitch,1.0,0.0,0.0); //rotate our camera on the x-axis (left and right)
glRotatef(cam->yaw,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(cam->camx,cam->camy,cam->camz); //translate the screen to the position of our camera
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);
//glColor4f(1,1,1,0.5);
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
//glDisable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D, rocktexture);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2i(0,0);glVertex3f(-32,0,32);
glTexCoord2i(1,0);glVertex3f(32,0,32);
glTexCoord2i(1,1);glVertex3f(32,0,-32);
glTexCoord2i(0,1);glVertex3f(-32,0,-32);
glEnd();
//glEnable(GL_CULL_FACE);
glPopMatrix();
/*glPushMatrix();
GLUquadric* earth = gluNewQuadric();
gluQuadricTexture(earth, true);
gluQuadricDrawStyle(earth, GLU_FILL);
gluQuadricNormals(earth, GLU_SMOOTH);
gluQuadricOrientation(earth, GLU_OUTSIDE);
gluSphere(earth, 1, 16, 16);
gluDeleteQuadric(earth);
glPopMatrix();*/
glFlush();
SDL_GL_SwapBuffers();
if (key[SDLK_ESCAPE] || key[SDLK_q])
{
std::cout<<"Game Ended."<<std::endl;
exit(0);
}
if (keystate[SDLK_w])
{
cam->camx-=sin(cam->yaw*M_PI/180)/4;
cam->camz+=cos(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_s])
{
cam->camx+=sin(cam->yaw*M_PI/180)/4;
cam->camz-=cos(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_a])
{
cam->camx+=cos(cam->yaw*M_PI/180)/4;
cam->camz+=sin(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_d])
{
cam->camx-=cos(cam->yaw*M_PI/180)/4;
cam->camz-=sin(cam->yaw*M_PI/180)/4;
}
}
}
// Load the OpenGL texture
GLuint loadImage(std::string path, GLuint tx,SDL_Surface* sur)
{
GLenum texture_format;
GLint nOfColors;
if ((sur = SDL_LoadBMP(path.c_str())))
{
// Check that the image's width is a power of 2
if ((sur->w & (sur->w - 1)) != 0)
{
printf("warning: image's width is not a power of 2\n");
}
// Also check if the height is a power of 2
if ((sur->h & (sur->h - 1)) != 0)
{
printf("warning: image's height is not a power of 2\n");
}
// get the number of channels in the SDL surface
nOfColors = sur->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (sur->format->Rmask == 0x000000ff)
{
texture_format = GL_RGBA;
}
else
{
texture_format = GL_BGRA;
}
}
else if (nOfColors == 3) // no alpha channel
{
if (sur->format->Rmask == 0x000000ff)
{
texture_format = GL_RGB;
}
else
{
texture_format = GL_BGR;
}
}
else
{
printf("warning: the image is not truecolor.. this will probably break\n");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &tx );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, tx );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, 3, sur->w, sur->h, 0, GL_BGR, GL_UNSIGNED_BYTE, sur->pixels);
//build mip-maps
gluBuild2DMipmaps(tx, 3, sur->w, sur->h, texture_format, GL_UNSIGNED_BYTE, sur->pixels);
}
else
{
printf("SDL could not load image: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// Free the SDL_Surface only if it was successfully created
if (sur)
{
SDL_FreeSurface(sur);
}
delete &texture_format;
delete &nOfColors;
return tx;
}
/* Program entry point */
int main(int argc, char *argv[])
{
cam->camz=-5;
cam->camy=-1;
if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
{
std::cout<<"Unable to initialize SDL: %s\n"<<SDL_GetError()<<std::endl;
return 1;
}
const SDL_VideoInfo* info = SDL_GetVideoInfo();
int vidFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
if (info->hw_available) {vidFlags |= SDL_HWSURFACE;}
else {vidFlags |= SDL_SWSURFACE;}
//int bpp = info->vfmt->BitsPerPixel;
SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, vidFlags);
SDL_WM_SetCaption( "Treason", NULL);
SDL_WarpMouse(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
gluLookAt(cam->camx,cam->camy,cam->camz,0,0,0,0,1,0);
glClearColor(0, 0, 0, 0);//background color white
float lmodel_ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
float local_view[] = { 0.0f };
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_DITHER);
//glHint(GL_PHONG_HINT_WIN, GL_NICEST);
glShadeModel(GL_SMOOTH);//GL_PHONG_WIN
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
/* glEnable(GL_FOG);
glHint(GL_FOG_HINT, GL_NICEST);
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP);
glFogf(GL_FOG_DENSITY, fogDensity);
glFogfv(GL_FOG_COLOR, fog_color);*/
// glEnable(GL_STENCIL_TEST);
//glStencilFunc(GL_KEEP, GL_KEEP, GL_INCR);
SDL_Surface *rocktexsur;
rocktexture = loadImage("rock.jpg", rocktexture, rocktexsur);
SDL_Surface *earthtexsur;
earthtexture = loadImage("earth.jpg", earthtexture, earthtexsur);
setup(WINDOW_WIDTH, WINDOW_HEIGHT);
display();
glDeleteTextures(1, &rocktexture);
glDeleteTextures(1, &earthtexture);
return 0;
}
So if you find anything or know any reason why it would return an "SDL could not load image" Error, please respond! I can't continue on my project until this is resolved because it produces a segfault.
SDL by itself can only load BMP images, and it will return an error if you load anything but a BMP in using the function SDL_LoadBMP(). In order to load JPEGs, you need to use the supplemental library SDL_image, which is available at http://www.libsdl.org/projects/SDL_image/ . As JJG answered, the prototype for the function you have to use is:
SDL_Surface *IMG_Load( const char* );
rather than SDL_LoadBMP().
Not an expert on SDL or C++. But I just spent a minute looking over my tiny program I made a while back. I used:
some_image = IMG_Load( "someimage.jpg" );