#c #visual-studio #opengl #glfw #soil
#c #visual-studio #opengl #glfw #soil
Вопрос:
Код отрисован правильно перед добавлением текстур. Я прекрасно могу использовать SOIL GLUT и eclipse, но только с Visual studios, похоже, ничего не работает.
Вот этот код:
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
#include <SOIL2.h>
#include <iostream>
// GLM Mathematics
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
int width, height;
const double PI = 3.14159;
const float toRadians = PI / 180.0f;
// Declare Input Callback Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void mouse_button_callback(GLFWwindow* window, int button, int action, int mode);
// Declare View Matrix
glm::mat4 viewMatrix;
// Camera Field of View
GLfloat fov = 45.0f;
void initiateCamera();
// Define Camera Attributes
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, 3.0f); // Move 3 units back in z towards screen
glm::vec3 target = glm::vec3(0.0f, 0.0f, 0.0f); // What the camera points to
glm::vec3 cameraDirection = glm::normalize(cameraPosition - target); // direction z
glm::vec3 worldUp = glm::vec3(0.0, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));// right vector x
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight)); // up vector y
glm::vec3 CameraFront = glm::vec3(0.0f, 0.0f, -1.0f); // 1 unit away from lense
// Camera Transformation Prototype
void TransformCamera();
// Boolean array for keys and mouse buttons
bool keys[1024], mouseButtons[3];
// Input state booleans
bool isPanning = false, isOrbiting = false;
// Pitch and Yaw
GLfloat radius = 3.0f, rawYaw = 0.0f, rawPitch = 0.0f, degYaw, degPitch;
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLfloat lastX = 320, lastY = 240, xChange, yChange; // Center mouse cursor
bool firstMouseMove = true;
// Draw Primitive(s)
void draw()
{
GLenum mode = GL_TRIANGLES;
GLsizei indices = 6;
glDrawElements(mode, indices, GL_UNSIGNED_BYTE, nullptr);
}
// Create and Compile Shaders
static GLuint CompileShader(const stringamp; source, GLuint shaderType)
{
// Create Shader object
GLuint shaderID = glCreateShader(shaderType);
const char* src = source.c_str();
// Attach source code to Shader object
glShaderSource(shaderID, 1, amp;src, nullptr);
// Compile Shader
glCompileShader(shaderID);
// Return ID of Compiled shader
return shaderID;
}
// Create Program Object
static GLuint CreateShaderProgram(const stringamp; vertexShader, const stringamp; fragmentShader)
{
// Compile vertex shader
GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);
// Compile fragment shader
GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// Create program object
GLuint shaderProgram = glCreateProgram();
// Attach vertex and fragment shaders to program object
glAttachShader(shaderProgram, vertexShaderComp);
glAttachShader(shaderProgram, fragmentShaderComp);
// Link shaders to create executable
glLinkProgram(shaderProgram);
// Delete compiled vertex and fragment shaders
glDeleteShader(vertexShaderComp);
glDeleteShader(fragmentShaderComp);
// Return Shader Program
return shaderProgram;
}
int main(void)
{
width = 640; height = 480;
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(width, height, "Main Window", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
// Set input callback functions
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetScrollCallback(window, scroll_callback);
/* Make the window's context current */
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK)
cout << "Error!" << endl;
GLfloat vertices[] = {
// Triangle 1
-0.5, -0.5, 0.0, // index 0
1.0, 0.0, 0.0, // red
0.0, 0.0, // UV (bl)
-0.5, 0.5, 0.0, // index 1
0.0, 1.0, 0.0, // green
0.0, 1.0, // UV (br)
0.5, -0.5, 0.0, // index 2
0.0, 0.0, 1.0, // blue
1.0, 0.0, // UV (tl)
// Triangle 2
0.5, 0.5, 0.0, // index 3
1.0, 0.0, 1.0, // purple
1.0, 1.0 // UV (tr)
};
// Define element indices
GLubyte indices[] = {
0, 1, 2,
1, 2, 3
};
// Plane Transforms
glm::vec3 planePositions[] = {
glm::vec3(0.0f, 0.0f, 0.5f),
glm::vec3(0.5f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, -0.5f),
glm::vec3(-0.5f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.5f, 0.0f),
glm::vec3(0.0f, -0.5f, 0.0f)
};
glm::float32 planeRotations[] = {
0.0f, 90.0f, 180.0f, -90.0f, -90.f, 90.f
};
// Setup some OpenGL options
glEnable(GL_DEPTH_TEST);
// Wireframe mode
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
GLuint cubeVBO, cubeEBO, cubeVAO, floorVBO, floorEBO, floorVAO;
glGenBuffers(1, amp;cubeVBO); // Create VBO
glGenBuffers(1, amp;cubeEBO); // Create EBO
glGenBuffers(1, amp;floorVBO); // Create VBO
glGenBuffers(1, amp;floorEBO); // Create EBO
glGenVertexArrays(1, amp;cubeVAO); // Create VOA
glGenVertexArrays(1, amp;floorVAO); // Create VOA
glBindVertexArray(cubeVAO);
// VBO and EBO Placed in User-Defined VAO
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); // Select VBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeEBO); // Select EBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Load indices
// Specify attribute location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindVertexArray(0); // Unbind VOA or close off (Must call VOA explicitly in loop)
glBindVertexArray(floorVAO);
glBindBuffer(GL_ARRAY_BUFFER, floorVBO); // Select VBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, floorEBO); // Select EBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Load indices
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
// Load texture maps
int crateTexWidth, crateTexHeight, gridTexWidth, gridTexHeight;
unsigned char* crateImage = SOIL_load_image("crate.png", amp;crateTexWidth, amp;crateTexHeight, 0, SOIL_LOAD_RGB);
unsigned char* gridImage = SOIL_load_image("grid.png", amp;gridTexWidth, amp;gridTexHeight, 0, SOIL_LOAD_RGB);
// Generate Textures
GLuint crateTexture; // for texture ID
glGenTextures(1, amp;crateTexture);// Generate texture id
glBindTexture(GL_TEXTURE_2D, crateTexture); // Activate texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, crateTexWidth, crateTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, crateImage); // Generate texture
glGenerateMipmap(GL_TEXTURE_2D); // Texture resolution managment
SOIL_free_image_data(crateImage); // Free imge from memory
glBindTexture(GL_TEXTURE_2D, 0); // Unbind or close texture object
GLuint gridTexture;
glGenTextures(1, amp;gridTexture);
glBindTexture(GL_TEXTURE_2D, gridTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gridTexWidth, gridTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, gridImage);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(gridImage);
glBindTexture(GL_TEXTURE_2D, 0);
// Vertex shader source code
string vertexShaderSource =
"#version 410 n"
"layout(location = 0) in vec3 vPosition;"
"layout(location = 1) in vec3 aColor;"
"layout(location = 2) in vec2 texCoord;"
"out vec3 oColor;"
"out vec2 oTexCoord;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main()n"
"{n"
"gl_Position = projection * view * model * vec4(vPosition.x, vPosition.y, vPosition.z, 1.0);"
"oColor = aColor;"
"oTexCoord = texCoord;"
"}n";
// Fragment shader source code
string fragmentShaderSource =
"#version 410 n"
"in vec3 oColor;"
"in vec2 oTexCoord;"
"out vec4 fragColor;"
"uniform sampler2D myTexture;"
"void main()n"
"{n"
"fragColor = texture(myTexture, oTexCoord);"
"}n";
// Creating Shader Program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
// Set frame time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// Resize window and graphics simultaneously
glfwGetFramebufferSize(window, amp;width, amp;height);
glViewport(0, 0, width, height);
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use Shader Program exe and select VAO before drawing
glUseProgram(shaderProgram); // Call Shader per-frame when updating attributes
// Declare transformations (can be initialized outside loop)
glm::mat4 projectionMatrix;
// Define LookAt Matrix
viewMatrix = glm::lookAt(cameraPosition, target, worldUp);
// Define projection matrix
projectionMatrix = glm::perspective(fov, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
// Get matrix's uniform location and set matrix
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glBindTexture(GL_TEXTURE_2D, crateTexture); // Apply crate texture (Auto detected by Uniform Sampler)
glBindVertexArray(cubeVAO); // User-defined VAO must be called before draw.
// Transform planes to form cube
for (GLuint i = 0; i < 6; i )
{
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, planePositions[i]);
modelMatrix = glm::rotate(modelMatrix, planeRotations[i] * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
if (i >= 4)
modelMatrix = glm::rotate(modelMatrix, planeRotations[i] * toRadians, glm::vec3(1.0f, 0.0f, 0.0f));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
// Draw primitive(s)
draw();
}
// Unbind Shader exe and VOA after drawing per frame
glBindVertexArray(0); //Incase different VAO wii be used after
glBindTexture(GL_TEXTURE_2D, gridTexture); // Apply grid texture
// Select and transform floor
glBindVertexArray(floorVAO);
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, glm::vec3(0.f, -.5f, 0.f));
modelMatrix = glm::rotate(modelMatrix, 90.f * toRadians, glm::vec3(1.0f, 0.0f, 0.0f));
modelMatrix = glm::scale(modelMatrix, glm::vec3(5.f, 5.f, 5.f));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
draw();
glBindVertexArray(0); //Incase different VAO will be used after
glUseProgram(0); // Incase different shader will be used after
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
// Poll Camera Transformations
TransformCamera();
}
//Clear GPU resources
glDeleteVertexArrays(1, amp;cubeVAO);
glDeleteBuffers(1, amp;cubeVBO);
glDeleteBuffers(1, amp;cubeEBO);
glDeleteVertexArrays(1, amp;floorVAO);
glDeleteBuffers(1, amp;floorVBO);
glDeleteBuffers(1, amp;floorEBO);
glfwTerminate();
return 0;
}
// Define input functions
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
// Display ASCII Key code
//std::cout <<"ASCII: "<< key << std::endl;
// Close window
if (key == GLFW_KEY_ESCAPE amp;amp; action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
// Assign true to Element ASCII if key pressed
if (action == GLFW_PRESS)
keys[key] = true;
else if (action == GLFW_RELEASE) // Assign false to Element ASCII if key released
keys[key] = false;
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
// Clamp FOV
if (fov >= 1.0f amp;amp; fov <= 55.0f)
fov -= yoffset * 0.01;
// Default FOV
if (fov < 1.0f)
fov = 1.0f;
if (fov > 55.0f)
fov = 55.0f;
}
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouseMove)
{
lastX = xpos;
lastY = ypos;
firstMouseMove = false;
}
// Calculate mouse offset (Easing effect)
xChange = xpos - lastX;
yChange = lastY - ypos; // Inverted cam
// Get current mouse (always starts at 0)
lastX = xpos;
lastY = ypos;
if (isOrbiting)
{
// Update raw yaw and pitch with mouse movement
rawYaw = xChange;
rawPitch = yChange;
// Conver yaw and pitch to degrees, and clamp pitch
degYaw = glm::radians(rawYaw);
degPitch = glm::clamp(glm::radians(rawPitch), -glm::pi<float>() / 2.f .1f, glm::pi<float>() / 2.f - .1f);
// Azimuth Altitude formula
cameraPosition.x = target.x radius * cosf(degPitch) * sinf(degYaw);
cameraPosition.y = target.y radius * sinf(degPitch);
cameraPosition.z = target.z radius * cosf(degPitch) * cosf(degYaw);
}
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mode)
{
// Assign boolean state to element Button code
if (action == GLFW_PRESS)
mouseButtons[button] = true;
else if (action == GLFW_RELEASE)
mouseButtons[button] = false;
}
// Define TransformCamera function
void TransformCamera()
{
// Orbit camera
if (keys[GLFW_KEY_LEFT_ALT] amp;amp; mouseButtons[GLFW_MOUSE_BUTTON_LEFT])
isOrbiting = true;
else
isOrbiting = false;
// Focus camera
if (keys[GLFW_KEY_F])
initiateCamera();
}
// Define
void initiateCamera()
{ // Define Camera Attributes
cameraPosition = glm::vec3(0.0f, 0.0f, 3.0f); // Move 3 units back in z towards screen
target = glm::vec3(0.0f, 0.0f, 0.0f); // What the camera points to
cameraDirection = glm::normalize(cameraPosition - cameraDirection); // direction z
worldUp = glm::vec3(0.0, 1.0f, 0.0f);
cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));// right vector x
cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight)); // up vector y
CameraFront = glm::vec3(0.0f, 0.0f, -1.0f); // 1 unit away from lense
}
Комментарии:
1. Почему вы не проверяете, что эти вызовы SOIL_load_image() возвращают действительные указатели на изображения и размеры изображения? Вы проверили, что рабочий каталог вашей программы соответствует вашим относительным путям?
2. Это исходный код моих учителей, кажется, он работает для всех остальных (это онлайн-класс, но я ничего не слышал о том, что он не работает в других системах) Я очень новичок в opengl, не могли бы вы подробнее рассказать об указателях на изображения. Пути родственников изначально были относительно связаны, но после сбоя с относительной связью я напрямую связал все библиотеки и файлы заголовков и включил SOIL во включаемый и в дополнительные каталоги с soil.lib
3. Когда я настроил его в eclipse с помощью mingw (для glfw3), и я получил целый список ошибок о неопределенных ссылках на функции soil, когда я загрузил его так же, как и с помощью glut, вот некоторые из них: b/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe : C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libglfw3.a(win32_monitor.c.obj):win32_monitor.c:(.text 0x8f): неопределенная ссылка на `__imp_CreateDCW’