OpenGL Assimp导入的模型不呈现 [英] OpenGL Assimp imported model not rendering

查看:1199
本文介绍了OpenGL Assimp导入的模型不呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用assimp加载模型。我试图使用索引,但我的模型不工作。我的代码没有错误(只是解析由于某种原因无法正常工作),这是什么:

  void loadOBJ(const char * path,
int& numOfVertices,
int& numOfFaces,
int& numOfIndices,
std :: vector< unsigned int>& outIndices ,
std :: vector< float>& outVertices,
std :: vector< float>& outUVs,
std :: vector< float>& outNormals){

Assimp ::进口商;
const aiScene * scene = importer.ReadFile(path,aiProcessPreset_TargetRealtime_Fast);
aiMesh * mesh = scene-> mMeshes [0];

numOfFaces = mesh-> mNumFaces;
numOfIndices = numOfFaces * 3;
outIndices.resize(numOfIndices);

for(unsigned int i = 0; i< mesh-> mNumFaces; ++ i){
const aiFace& face = mesh-> mFaces [i]
assert(face.mNumIndices == 3);
outIndices [i * 3 + 0] = face.mIndice [0];
outIndices [i * 3 + 1] = face.mIndice [1];
outIndices [i * 3 + 2] = face.mIndices [2];
}

numOfVertices = mesh-> mNumVertices;
outVertices.resize(numOfVertices * 3);
outNormals.resize(numOfVertices * 3);
outUVs.resize(numOfVertices * 2);
for(unsigned int i = 0; i mNumVertices; ++ i){
if(mesh-> HasPositions()){
outVertices [i * 3 + 0] = mesh-> mVertices [i] .x;
outVertices [i * 3 + 1] = mesh-> mVertices [i] .y;
outVertices [i * 3 + 2] = mesh-> mVertices [i] .z;
}

if(mesh-> HasNormals()){
outNormals [i * 3 + 0] = mesh-> mNormals [i] .x;
outNormals [i * 3 + 1] = mesh-> mNormals [i] .x;
outNormals [i * 3 + 2] = mesh-> mNormals [i] .x;
}

if(mesh-> HasTextureCoords(0)){
outUVs [i * 2 + 0] = mesh-> mTextureCoords [0] [i]。 X;
outUVs [i * 2 + 1] = mesh-> mTextureCoords [0] [i] .y;
}
}
}

int main(int argc,char * argv []){
...
int numOfVertices;
int numOfFaces;
int numOfIndices;
std :: vector< unsigned int>指数;
std :: vector< float>顶点;
std :: vector< float> uvs;
std :: vector< float>法线
loadOBJ(../ src / cube.obj,numOfVertices,numOfFaces,numOfIndices,indices,vertices,uvs,normals);

GLuint elementBuffer;
gl :: GenBuffers(1,& elementBuffer);
gl :: BindBuffer(gl :: ELEMENT_ARRAY_BUFFER,elementBuffer);
gl :: BufferData(gl :: ELEMENT_ARRAY_BUFFER,indices.size()* sizeof(unsigned int),& indices [0],gl :: STATIC_DRAW);

GLuint vertexBuffer;
gl :: GenBuffers(1,& vertexBuffer);
gl :: BindBuffer(gl :: ARRAY_BUFFER,vertexBuffer);
gl :: BufferData(gl :: ARRAY_BUFFER,vertices.size()* sizeof(float),& vertices [0],gl :: STATIC_DRAW);

GLuint uvBuffer;
gl :: GenBuffers(1,& uvBuffer);
gl :: BindBuffer(gl :: ARRAY_BUFFER,uvBuffer);
gl :: BufferData(gl :: ARRAY_BUFFER,uvs.size()* sizeof(float),& uvs [0],gl :: STATIC_DRAW);

GLuint normalBuffer;
gl :: GenBuffers(1,& normalBuffer);
gl :: BindBuffer(gl :: ARRAY_BUFFER,normalBuffer);
gl :: BufferData(gl :: ARRAY_BUFFER,normals.size()* sizeof(float),& normals [0],gl :: STATIC_DRAW);

while(!glfwWindowShouldClose(window)){
...
gl :: ClearColor(0.0f,0.0f,0.0f,1.0f);
gl :: Clear(gl :: COLOR_BUFFER_BIT | gl :: DEPTH_BUFFER_BIT);

gl :: UseProgram(program);
gl :: BindBuffer(gl :: ARRAY_BUFFER,vertexBuffer);
gl :: EnableVertexAttribArray(0);
gl :: VertexAttribPointer(0,3,gl :: FLOAT,gl :: FALSE_,0,(void *)0);

gl :: BindBuffer(gl :: ARRAY_BUFFER,uvBuffer);
gl :: EnableVertexAttribArray(1);
gl :: VertexAttribPointer(1,2,gl :: FLOAT,gl :: FALSE_,0,(void *)0);

gl :: BindBuffer(gl :: ARRAY_BUFFER,normalBuffer);
gl :: EnableVertexAttribArray(2);
gl :: VertexAttribPointer(2,3,gl :: FLOAT,gl :: FALSE_,0,(void *)0);

gl :: BindBuffer(gl :: ELEMENT_ARRAY_BUFFER,elementBuffer);
gl :: DrawElements(gl :: ELEMENT_ARRAY_BUFFER,numOfIndices,gl :: UNSIGNED_INT,(void *)0);
...
}
...
}

loadOBJ函数似乎没有正确解析。

解决方案

  gl :: DrawElements(gl :: ELEMENT_ARRAY_BUFFER,numOfIndices,gl :: UNSIGNED_INT,(void *)0); 
^^^^^^^^^^^^^^^^^^^^^^^ h?

GL_ELEMENT_ARRAY_BUFFER glDrawElements() 。 / p>

尝试类似 GL_TRIANGLES

  // OpenGL 
#include< GL / glew.h>
#include< GLFW / glfw3.h>

// GLM
#include #include< glm / gtx / transform.hpp>
#include< glm / gtc / type_ptr.hpp>

// SOIL
#include< SOIL / SOIL.h>

// assimp
#include< assimp / Importer.hpp>
#include< assimp / scene.h>
#include< assimp / postprocess.h>

// STL
#include< iostream>
#include< cstdio>
#include< cstdlib>
#include< vector>

float deltaTime = 1.0f / 60.0f;

GLFWwindow * window;
int windowWidth = 640;
int windowHeight = 480;

GLuint程序;
GLuint mvpUniform;
glm :: mat4 modelMatrix;
glm :: mat4 viewMatrix;
glm :: mat4 projectionMatrix;

双鼠标X,鼠标Y;
float speed = 0.09f;
float mouseSpeed = 0.04f;

glm :: vec3 position = glm :: vec3(0,0,5);
glm :: vec3 direction,right,up;

float horizo​​ntalAngle = 3.14159f;
float verticalAngle = 0.0f;
float fov = 60.0f;

bool wKeyPressed;
bool sKeyPressed
bool aKeyPressed;
bool dKeyPressed;

void initialize()
{
//初始化GLFW
if(!glfwInit())
{
std :: cout ;& 错误:GLFW无法初始化。
return;
}

//创建窗口
window = glfwCreateWindow(windowWidth,windowHeight,OpenGL Hacks,NULL,NULL);
if(!window)
{
std :: cout< 错误:无法创建window.\\\
;
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);

//加载OpenGL函数
if(GLEW_OK!= glewInit())
{
std :: cout< 错误:无法加载OpenGL函数。
glfwTerminate();
return;
}
}

void windowSizeChange(GLFWwindow * window,int width,int height)
{
if(windowWidth!= width || windowHeight! = height)
{
windowWidth = width;
windowHeight = height;

projectionMatrix = glm :: perspective

fov,
(float)windowWidth / windowHeight,
0.1f,
100.0f
);

glUseProgram(program);
glUniformMatrix4fv(mvpUniform,1,GL_FALSE,glm :: value_ptr(projectionMatrix));
glUseProgram(0);

glViewport(0,0,(GLsizei)width,(GLsizei)height);
}
}

void handleKeyboardInput(GLFWwindow * window,int key,int scancode,int action,int mods)
{
if(key = = GLFW_KEY_ESCAPE&&&&&&&&&& amp; GIF}
else if(key == GLFW_KEY_W&&& action == GLFW_PRESS)
wKeyPressed = true;
else if(key == GLFW_KEY_S&&& action == GLFW_PRESS)
sKeyPressed = true;
else if(key == GLFW_KEY_A&&& action == GLFW_PRESS)
aKeyPressed = true;
else if(key == GLFW_KEY_D&&& action == GLFW_PRESS)
dKeyPressed = true;
else if(key == GLFW_KEY_W&& action == GLFW_RELEASE)
wKeyPressed = false;
else if(key == GLFW_KEY_S&&& action == GLFW_RELEASE)
sKeyPressed = false;
else if(key == GLFW_KEY_A&&& action == GLFW_RELEASE)
aKeyPressed = false;
else if(key == GLFW_KEY_D&&& action == GLFW_RELEASE)
dKeyPressed = false;
}

void getInput()
{
if(wKeyPressed)
position + = direction * deltaTime * speed;
if(sKeyPressed)
position - = direction * deltaTime * speed;
if(aKeyPressed)
position - = right * deltaTime * speed;
if(dKeyPressed)
position + = right * deltaTime * speed;

direction = glm :: vec3

std :: cos(verticalAngle)* std :: sin(horizo​​ntalAngle),
std :: sin(verticalAngle) ,
std :: cos(verticalAngle)* std :: cos(horizo​​ntalAngle)
);
right = glm :: vec3

std :: sin(horizo​​ntalAngle - 3.14159f / 2.0f),
0.0f,
std :: cos - 3.14159f / 2.0f)
);
up = glm :: cross(right,direction);

glfwGetCursorPos(window,& mouseX,& mouseY);
glfwSetCursorPos(window,windowWidth / 2,windowHeight / 2);
horizo​​ntalAngle + = mouseSpeed * deltaTime * float(windowWidth / 2- mouseX);
//防止上下颠倒
if(!up.y> = -0.5f)
verticalAngle + = mouseSpeed * deltaTime * float(windowHeight / 2- mouseY);
else if(up.y == -1.0f)
up = glm :: vec3(up.x,1,up.z);
}

GLuint loadImage()
{
GLuint textureID;
glGenTextures(1,& textureID);
glBindTexture(GL_TEXTURE_2D,textureID);

unsigned char bytes [] =
{
255,0,0,
0,255,0,
0,0,255,
255,255,0
};

textureID = SOIL_create_OGL_texture

字节,
2,3,
textureID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
) ;

glBindTexture(GL_TEXTURE_2D,0);
if(textureID == 0)
printf(SOIL Loading Error:%s\\\
,SOIL_last_result());

返回textureID;
}

void loadOBJ

const char * path,
std :: vector< unsigned int>& outIndices,
std :: vector< float>& outVertices,
std :: vector< float>& outUVs,
std :: vector< float>& outNormals
){

Assimp ::进口商;
const aiScene * scene = importer.ReadFile(path,aiProcessPreset_TargetRealtime_Fast);
aiMesh * mesh = scene-> mMeshes [0];

int numOfFaces = mesh-> mNumFaces;
int numOfIndices = numOfFaces * 3;
outIndices.resize(numOfIndices);

for(unsigned int i = 0; i< mesh-> mNumFaces; ++ i){
const aiFace& face = mesh-> mFaces [i]
assert(face.mNumIndices == 3);
outIndices [i * 3 + 0] = face.mIndices [0];
outIndices [i * 3 + 1] = face.mIndices [1];
outIndices [i * 3 + 2] = face.mIndices [2];
}

int numOfVertices = mesh-> mNumVertices;
outVertices.resize(numOfVertices * 3);
outNormals.resize(numOfVertices * 3);
outUVs.resize(numOfVertices * 2);
for(unsigned int i = 0; i mNumVertices; ++ i){
if(mesh-> HasPositions()){
outVertices [i * 3 + 0] = mesh-> mVertices [i] .x;
outVertices [i * 3 + 1] = mesh-> mVertices [i] .y;
outVertices [i * 3 + 2] = mesh-> mVertices [i] .z;
}

if(mesh-> HasNormals()){
outNormals [i * 3 + 0] = mesh-> mNormals [i] .x;
outNormals [i * 3 + 1] = mesh-> mNormals [i] .x;
outNormals [i * 3 + 2] = mesh-> mNormals [i] .x;
}

if(mesh-> HasTextureCoords(0)){
outUVs [i * 2 + 0] = mesh-> mTextureCoords [0] [i]。 X;
outUVs [i * 2 + 1] = mesh-> mTextureCoords [0] [i] .y;
}
}
}

// GLSL着色器程序加载程序
struct Program
{
static GLuint Load * vert,const char * geom,const char * frag)
{
GLuint prog = glCreateProgram();
if(vert)AttachShader(prog,GL_VERTEX_SHADER,vert);
if(geom)AttachShader(prog,GL_GEOMETRY_SHADER,geom);
if(frag)AttachShader(prog,GL_FRAGMENT_SHADER,frag);
glLinkProgram(prog);
CheckStatus(prog);
return prog;
}

private:
static void CheckStatus(GLuint obj)
{
GLint status = GL_FALSE,len = 10;
if(glIsShader(obj))glGetShaderiv(obj,GL_COMPILE_STATUS,& status);
if(glIsProgram(obj))glGetProgramiv(obj,GL_LINK_STATUS,& status);
if(status == GL_TRUE)return;
if(glIsShader(obj))glGetShaderiv(obj,GL_INFO_LOG_LENGTH,& len);
if(glIsProgram(obj))glGetProgramiv(obj,GL_INFO_LOG_LENGTH,& len);
std :: vector< char> log(len,'X');
if(glIsShader(obj))glGetShaderInfoLog(obj,len,NULL和& log [0]);
if(glIsProgram(obj))glGetProgramInfoLog(obj,len,NULL,& log [0]);
std :: cerr<< & log [0]< std :: endl;
exit(-1);
}

static void AttachShader(GLuint程序,GLenum类型,const char * src)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader,1,& src,NULL);
glCompileShader(shader);
CheckStatus(shader);
glAttachShader(program,shader);
glDeleteShader(shader);
}
};
#define GLSL(version,shader)#version#version\\\
#shader

const char * vert = GLSL
,vec3中的
布局(位置= 0)position_modelspace中的vec2 uv中的
布局(位置= 1); vec3中的
布局(位置= 2)normal_modelspace;
$ b b out vec2 UV;
out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;

uniform mat4 mvp;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform vc3 lightPosition_worldspace;

void main()
{
gl_Position = mvp * vec4 position_modelspace,1.0f);

Position_worldspace =(modelMatrix * vec4(position_modelspace,1.0f))。xyz;

vec3 position_modelspaceCamera =(viewMatrix * modelMatrix * vec4(position_modelspace, 1.0f))。xyz;
EyeDirection_cameraspace = vec3(0,0,0) - position_modelspaceCamera;

vec3 lightPosition_worldspaceCamera =(viewMatrix * vec4(lightPosition_worldspace,1.0f))。xyz;
LightDirection_cameraspace = lightPosition_worldspaceCamera + EyeDirection_cameraspace;

Normal_cameraspace =(viewMatrix * modelMatrix * vec4(normal_modelspace,0.0f))。xyz;
UV = uv;
}
);

const char * frag = GLSL

330 core,
in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
在vec3 LightDirection_cameraspace;

out vec3 color;

uniform sampler2D textureSampler;
uniform mat4 modelViewMatrix;
uniform vec3 lightPosition_worldspace;

void main()
{
vec3 lightColor = vec3(1,1,1);
float lightPower = 50.0f;

vec3 materialDiffuseColor = texture2D(textureSampler,UV).rgb;
vec3 materialAmbientColor = vec3(0.1,0.1,0.1)* materialDiffuseColor;
vec3 materialSpecularColor = vec3(0.3,0.3, 0.3);

float distance = length(lightPosition_worldspace - Position_worldspace);

vec3 n = normalize(Normal_cameraspace);
vec3 l = normalize(LightDirection_cameraspace);

float cosTheta = clamp(dot(n,l),0,1);

vec3 eye = normalize(EyeDirection_cameraspace);
vec3 reflection = reflect(-l,n);

float cosAlpha = clamp(dot(eye,reflection),0,1);

color = materialAmbientColor +
materialDiffuseColor * lightColor * lightPower * cosTheta /(distance * distance)+
materialSpecularColor * lightColor * lightPower * pow(cosAlpha,5)距离);
}
);



int main(int argc,char * argv [])
{
initialize();
glfwSetWindowSizeCallback(window,windowSizeChange);
glfwSetKeyCallback(window,handleKeyboardInput);

// Z顺序缓冲
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

//顶点数组对象
GLuint vertexArrayObject;
glGenVertexArrays(1,& vertexArrayObject);
glBindVertexArray(vertexArrayObject);

program = Program :: Load(vert,NULL,frag);
mvpUniform = glGetUniformLocation(program,mvp);
GLuint modelMatrixUniform = glGetUniformLocation(program,modelMatrix);
GLuint viewMatrixUniform = glGetUniformLocation(program,viewMatrix);
GLuint lightPositionUniform = glGetUniformLocation(program,lightPosition_worldspace);

GLuint texture = loadImage();
GLuint textureSamplerUniform = glGetUniformLocation(program,textureSampler);

std :: vector< unsigned int>指数;
std :: vector< float>顶点;
std :: vector< float> uvs;
std :: vector< float>法线
loadOBJ(cube.obj,indices,vertices,uvs,normals);

GLuint elementBuffer;
glGenBuffers(1,& elementBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size()* sizeof(unsigned int),& indices [0],GL_STATIC_DRAW);

GLuint vertexBuffer;
glGenBuffers(1,& vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,vertices.size()* sizeof(aiVector3D),& vertices [0],GL_STATIC_DRAW);

GLuint uvBuffer;
glGenBuffers(1,& uvBuffer);
glBindBuffer(GL_ARRAY_BUFFER,uvBuffer);
glBufferData(GL_ARRAY_BUFFER,uvs.size()* sizeof(aiVector2D),& uvs [0],GL_STATIC_DRAW);

GLuint normalBuffer;
glGenBuffers(1,& normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER,normalBuffer);
glBufferData(GL_ARRAY_BUFFER,normals.size()* sizeof(aiVector3D),& normals [0],GL_STATIC_DRAW);

while(!glfwWindowShouldClose(window))
{
getInput();

projectionMatrix = glm :: perspective(fov,(float)windowWidth / windowHeight,0.1f,1000.0f);
viewMatrix = glm :: lookAt(position,position + direction,up);
modelMatrix = glm :: mat4(1.0f);

//这实际上是模型 - >视图 - >投影,而不是其他方式
glm :: mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

glfwPollEvents();

//清除屏幕
glClearColor(0.0f,0.0f,0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUseProgram(program);
glUniformMatrix4fv(mvpUniform,1,GL_FALSE,glm :: value_ptr(mvp));
glUniformMatrix4fv(modelMatrixUniform,1,GL_FALSE,glm :: value_ptr(modelMatrix));
glUniformMatrix 4fv(viewMatrixUniform,1,GL_FALSE,glm :: value_ptr(viewMatrix));

glm :: vec3 lightPosition = glm :: vec3(4,4,4);
glUniform3f(lightPositionUniform,lightPosition.x,lightPosition.y,lightPosition.z);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture);
glUniform1i(textureSamplerUniform,0);

glBindBuffer(GL_ARRAY_BUFFER,vertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void *)0);

glBindBuffer(GL_ARRAY_BUFFER,uvBuffer);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void *)0);

glBindBuffer(GL_ARRAY_BUFFER,normalBuffer);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void *)0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementBuffer);
glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_INT,(void *)0);
$ b $ g glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2)

glfwSwapBuffers(window);
}

glDeleteProgram(program);
glDeleteBuffers(1,& vertexBuffer);
glDeleteBuffers(1,& uvBuffer);
glDeleteBuffers(1,& normalBuffer);
glDeleteTextures(1,& texture);
glDeleteVertexArrays(1,& vertexArrayObject);

glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

cube.obj:

 #Blender3D v249 OBJ档案:untitled.blend 
#www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl Material_ray.png
s off
f 5/1 / 1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6 / 4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5 / 1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13 / 8
f 1/2/8 3/13/8 4/14/8


I'm trying to load a model using assimp. I'm trying to use indexing, but my model isn't working. My code has no errors (just that the parsing isn't working right for some reason) and this is what it is:

void loadOBJ(const char *path,
    int &numOfVertices,
    int &numOfFaces,
    int &numOfIndices,
    std::vector<unsigned int> &outIndices,
    std::vector<float> &outVertices,
    std::vector<float> &outUVs,
    std::vector<float> &outNormals) {

    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile(path, aiProcessPreset_TargetRealtime_Fast);
    aiMesh* mesh = scene->mMeshes[0];

    numOfFaces = mesh->mNumFaces;
    numOfIndices = numOfFaces * 3;
    outIndices.resize(numOfIndices);

    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        const aiFace &face = mesh->mFaces[i];
        assert(face.mNumIndices == 3);
        outIndices[i * 3 + 0] = face.mIndices[0];
        outIndices[i * 3 + 1] = face.mIndices[1];
        outIndices[i * 3 + 2] = face.mIndices[2];
    }

    numOfVertices = mesh->mNumVertices;
    outVertices.resize(numOfVertices * 3);
    outNormals.resize(numOfVertices * 3);
    outUVs.resize(numOfVertices * 2);
    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
        if (mesh->HasPositions()) {
            outVertices[i * 3 + 0] = mesh->mVertices[i].x;
            outVertices[i * 3 + 1] = mesh->mVertices[i].y;
            outVertices[i * 3 + 2] = mesh->mVertices[i].z;
        }

        if (mesh->HasNormals()) {
            outNormals[i * 3 + 0] = mesh->mNormals[i].x;
            outNormals[i * 3 + 1] = mesh->mNormals[i].x;
            outNormals[i * 3 + 2] = mesh->mNormals[i].x;
        }

        if (mesh->HasTextureCoords(0)) {
            outUVs[i * 2 + 0] = mesh->mTextureCoords[0][i].x;
            outUVs[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
        }
    }
}

int main(int argc, char *argv[]) {
    ...
    int numOfVertices;
    int numOfFaces;
    int numOfIndices;
    std::vector<unsigned int> indices;
    std::vector<float> vertices;
    std::vector<float> uvs;
    std::vector<float> normals;
    loadOBJ("../src/cube.obj", numOfVertices, numOfFaces, numOfIndices, indices, vertices, uvs, normals);

    GLuint elementBuffer;
    gl::GenBuffers(1, &elementBuffer);
    gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, elementBuffer);
    gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], gl::STATIC_DRAW);

    GLuint vertexBuffer;
    gl::GenBuffers(1, &vertexBuffer);
    gl::BindBuffer(gl::ARRAY_BUFFER, vertexBuffer);
    gl::BufferData(gl::ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], gl::STATIC_DRAW);

    GLuint uvBuffer;
    gl::GenBuffers(1, &uvBuffer);
    gl::BindBuffer(gl::ARRAY_BUFFER, uvBuffer);
    gl::BufferData(gl::ARRAY_BUFFER, uvs.size() * sizeof(float), &uvs[0], gl::STATIC_DRAW);

    GLuint normalBuffer;
    gl::GenBuffers(1, &normalBuffer);
    gl::BindBuffer(gl::ARRAY_BUFFER, normalBuffer);
    gl::BufferData(gl::ARRAY_BUFFER, normals.size() * sizeof(float), &normals[0], gl::STATIC_DRAW);

    while (!glfwWindowShouldClose(window)) {
        ...
        gl::ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

        gl::UseProgram(program);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertexBuffer);
        gl::EnableVertexAttribArray(0);
        gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE_, 0, (void*)0);

        gl::BindBuffer(gl::ARRAY_BUFFER, uvBuffer);
        gl::EnableVertexAttribArray(1);
        gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE_, 0, (void*)0);

        gl::BindBuffer(gl::ARRAY_BUFFER, normalBuffer);
        gl::EnableVertexAttribArray(2);
        gl::VertexAttribPointer(2, 3, gl::FLOAT, gl::FALSE_, 0, (void*)0);

        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, elementBuffer);
        gl::DrawElements(gl::ELEMENT_ARRAY_BUFFER, numOfIndices, gl::UNSIGNED_INT, (void*)0);
        ...
    }
    ...
}

The loadOBJ function doesn't seem to be parsing right.

解决方案

gl::DrawElements(gl::ELEMENT_ARRAY_BUFFER, numOfIndices, gl::UNSIGNED_INT, (void*)0);
                 ^^^^^^^^^^^^^^^^^^^^^^^^ huh?

GL_ELEMENT_ARRAY_BUFFER has never been a valid argument to glDrawElements().

Try something like GL_TRIANGLES:

// OpenGL
#include <GL/glew.h>
#include <GLFW/glfw3.h>

// GLM
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>

// SOIL
#include <SOIL/SOIL.h>

// assimp
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

// STL
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>

float deltaTime = 1.0f / 60.0f;

GLFWwindow *window;
int windowWidth = 640;
int windowHeight = 480;

GLuint program;
GLuint mvpUniform;
glm::mat4 modelMatrix;
glm::mat4 viewMatrix;
glm::mat4 projectionMatrix;

double mouseX, mouseY;
float speed = 0.09f;
float mouseSpeed = 0.04f;

glm::vec3 position = glm::vec3(0, 0, 5);
glm::vec3 direction, right, up;

float horizontalAngle = 3.14159f;
float verticalAngle = 0.0f;
float fov = 60.0f;

bool wKeyPressed;
bool sKeyPressed;
bool aKeyPressed;
bool dKeyPressed;

void initialize() 
{
    // Initialize GLFW
    if (!glfwInit()) 
    {
        std::cout << "Error: GLFW failed to initialize.\n";
        return;
    }

    // Create window
    window = glfwCreateWindow(windowWidth, windowHeight, "OpenGL Hacks", NULL, NULL);
    if (!window) 
    {
        std::cout << "Error: Failed to create window.\n";
        glfwTerminate();
        return;
    }
    glfwMakeContextCurrent(window);

    // Load OpenGL functions
    if( GLEW_OK != glewInit() )
    {
        std::cout << "Error: Failed to load OpenGL functions.\n";
        glfwTerminate();
        return;
    }
}

void windowSizeChange(GLFWwindow *window, int width, int height) 
{
    if (windowWidth != width || windowHeight != height)
    {
        windowWidth = width;
        windowHeight = height;

        projectionMatrix = glm::perspective
            (
            fov,
            (float)windowWidth / windowHeight,
            0.1f,
            100.0f
            );

        glUseProgram(program);
        glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
        glUseProgram(0);

        glViewport(0, 0, (GLsizei)width, (GLsizei)height);
    }
}

void handleKeyboardInput(GLFWwindow *window, int key, int scancode, int action, int mods) 
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, 1);
    else if (key == GLFW_KEY_W && action == GLFW_PRESS)
        wKeyPressed = true;
    else if (key == GLFW_KEY_S && action == GLFW_PRESS)
        sKeyPressed = true;
    else if (key == GLFW_KEY_A && action == GLFW_PRESS)
        aKeyPressed = true;
    else if (key == GLFW_KEY_D && action == GLFW_PRESS)
        dKeyPressed = true;
    else if (key == GLFW_KEY_W && action == GLFW_RELEASE)
        wKeyPressed = false;
    else if (key == GLFW_KEY_S && action == GLFW_RELEASE)
        sKeyPressed = false;
    else if (key == GLFW_KEY_A && action == GLFW_RELEASE)
        aKeyPressed = false;
    else if (key == GLFW_KEY_D && action == GLFW_RELEASE)
        dKeyPressed = false;
}

void getInput() 
{
    if (wKeyPressed)
        position += direction * deltaTime * speed;
    if (sKeyPressed)
        position -= direction * deltaTime * speed;
    if (aKeyPressed)
        position -= right * deltaTime * speed;
    if (dKeyPressed)
        position += right * deltaTime * speed;

    direction = glm::vec3
        (
        std::cos(verticalAngle) * std::sin(horizontalAngle),
        std::sin(verticalAngle),
        std::cos(verticalAngle) * std::cos(horizontalAngle)
        );
    right = glm::vec3
        (
        std::sin(horizontalAngle - 3.14159f / 2.0f),
        0.0f,
        std::cos(horizontalAngle - 3.14159f / 2.0f)
        );
    up = glm::cross(right, direction);

    glfwGetCursorPos(window, &mouseX, &mouseY);
    glfwSetCursorPos(window, windowWidth / 2, windowHeight / 2);
    horizontalAngle += mouseSpeed * deltaTime * float(windowWidth / 2 - mouseX);
    // Prevent from going upside down
    if (!up.y >= -0.5f)
        verticalAngle += mouseSpeed * deltaTime * float(windowHeight / 2 - mouseY);
    else if (up.y == -1.0f)
        up = glm::vec3(up.x, 1, up.z);
}

GLuint loadImage()
{
    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);

    unsigned char bytes[] = 
    {
        255, 0, 0,
        0, 255, 0,
        0, 0, 255,
        255, 255, 0
    };

    textureID = SOIL_create_OGL_texture
        (
        bytes, 
        2, 2, 3,
        textureID,
        SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
        );

    glBindTexture(GL_TEXTURE_2D, 0);
    if (textureID == 0)
        printf("SOIL Loading Error: %s\n", SOIL_last_result());

    return textureID;
}

void loadOBJ
    (
    const char *path,
    std::vector<unsigned int> &outIndices,
    std::vector<float> &outVertices,
    std::vector<float> &outUVs,
    std::vector<float> &outNormals
    ) {

    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile(path, aiProcessPreset_TargetRealtime_Fast);
    aiMesh* mesh = scene->mMeshes[0];

    int numOfFaces = mesh->mNumFaces;
    int numOfIndices = numOfFaces * 3;
    outIndices.resize(numOfIndices);

    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        const aiFace &face = mesh->mFaces[i];
        assert(face.mNumIndices == 3);
        outIndices[i * 3 + 0] = face.mIndices[0];
        outIndices[i * 3 + 1] = face.mIndices[1];
        outIndices[i * 3 + 2] = face.mIndices[2];
    }

    int numOfVertices = mesh->mNumVertices;
    outVertices.resize(numOfVertices * 3);
    outNormals.resize(numOfVertices * 3);
    outUVs.resize(numOfVertices * 2);
    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
        if (mesh->HasPositions()) {
            outVertices[i * 3 + 0] = mesh->mVertices[i].x;
            outVertices[i * 3 + 1] = mesh->mVertices[i].y;
            outVertices[i * 3 + 2] = mesh->mVertices[i].z;
        }

        if (mesh->HasNormals()) {
            outNormals[i * 3 + 0] = mesh->mNormals[i].x;
            outNormals[i * 3 + 1] = mesh->mNormals[i].x;
            outNormals[i * 3 + 2] = mesh->mNormals[i].x;
        }

        if (mesh->HasTextureCoords(0)) {
            outUVs[i * 2 + 0] = mesh->mTextureCoords[0][i].x;
            outUVs[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
        }
    }
}

// GLSL shader program loader
struct Program
{
    static GLuint Load( const char* vert, const char* geom, const char* frag )
    {
        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE, len = 10;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
        std::vector< char > log( len, 'X' );
        if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
        if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
        std::cerr << &log[0] << std::endl;
        exit( -1 );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};
#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL
(
    330 core,
    layout (location = 0) in vec3 position_modelspace;
    layout (location = 1) in vec2 uv;
    layout (location = 2) in vec3 normal_modelspace;

    out vec2 UV;
    out vec3 Position_worldspace;
    out vec3 Normal_cameraspace;
    out vec3 EyeDirection_cameraspace;
    out vec3 LightDirection_cameraspace;

    uniform mat4 mvp;
    uniform mat4 viewMatrix;
    uniform mat4 modelMatrix;
    uniform vec3 lightPosition_worldspace;

    void main() 
    {
        gl_Position = mvp * vec4(position_modelspace, 1.0f);

        Position_worldspace = (modelMatrix * vec4(position_modelspace, 1.0f)).xyz;

        vec3 position_modelspaceCamera = (viewMatrix * modelMatrix * vec4(position_modelspace, 1.0f)).xyz;
        EyeDirection_cameraspace = vec3(0, 0, 0) - position_modelspaceCamera;

        vec3 lightPosition_worldspaceCamera = (viewMatrix * vec4(lightPosition_worldspace, 1.0f)).xyz;
        LightDirection_cameraspace = lightPosition_worldspaceCamera + EyeDirection_cameraspace;

        Normal_cameraspace = (viewMatrix * modelMatrix * vec4(normal_modelspace, 0.0f)).xyz;
        UV = uv;
    }
);

const char* frag = GLSL
(
    330 core,
    in vec2 UV;
    in vec3 Position_worldspace;
    in vec3 Normal_cameraspace;
    in vec3 EyeDirection_cameraspace;
    in vec3 LightDirection_cameraspace;

    out vec3 color;

    uniform sampler2D textureSampler;
    uniform mat4 modelViewMatrix;
    uniform vec3 lightPosition_worldspace;

    void main()
    {
        vec3 lightColor = vec3(1, 1, 1);
        float lightPower = 50.0f;

        vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb;
        vec3 materialAmbientColor = vec3(0.1, 0.1, 0.1) * materialDiffuseColor;
        vec3 materialSpecularColor = vec3(0.3, 0.3, 0.3);

        float distance = length(lightPosition_worldspace - Position_worldspace);

        vec3 n = normalize(Normal_cameraspace);
        vec3 l = normalize(LightDirection_cameraspace);

        float cosTheta = clamp(dot(n, l), 0, 1);

        vec3 eye = normalize(EyeDirection_cameraspace);
        vec3 reflection = reflect(-l, n);

        float cosAlpha = clamp(dot(eye, reflection), 0, 1);

        color = materialAmbientColor +
                materialDiffuseColor * lightColor * lightPower * cosTheta / (distance * distance) +
                materialSpecularColor * lightColor * lightPower * pow(cosAlpha, 5) / (distance * distance);
    }
);



int main(int argc, char *argv[]) 
{
    initialize();
    glfwSetWindowSizeCallback(window, windowSizeChange);
    glfwSetKeyCallback(window, handleKeyboardInput);

    // Z order buffering
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    // Vertex Array Object
    GLuint vertexArrayObject;
    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);

    program = Program::Load( vert, NULL, frag );
    mvpUniform = glGetUniformLocation(program, "mvp");
    GLuint modelMatrixUniform = glGetUniformLocation(program, "modelMatrix");
    GLuint viewMatrixUniform = glGetUniformLocation(program, "viewMatrix");
    GLuint lightPositionUniform = glGetUniformLocation(program, "lightPosition_worldspace");

    GLuint texture = loadImage();
    GLuint textureSamplerUniform = glGetUniformLocation(program, "textureSampler");

    std::vector<unsigned int> indices;
    std::vector<float> vertices;
    std::vector<float> uvs;
    std::vector<float> normals;
    loadOBJ("cube.obj", indices, vertices, uvs, normals);

    GLuint elementBuffer;
    glGenBuffers(1, &elementBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(aiVector3D), &vertices[0], GL_STATIC_DRAW);

    GLuint uvBuffer;
    glGenBuffers(1, &uvBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
    glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(aiVector2D), &uvs[0], GL_STATIC_DRAW);

    GLuint normalBuffer;
    glGenBuffers(1, &normalBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
    glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(aiVector3D), &normals[0], GL_STATIC_DRAW);

    while (!glfwWindowShouldClose(window))
    {
        getInput();

        projectionMatrix = glm::perspective(fov, (float)windowWidth / windowHeight, 0.1f, 1000.0f);
        viewMatrix = glm::lookAt(position, position + direction, up);
        modelMatrix = glm::mat4(1.0f);

        // This is actually model -> view -> projection, not the other way around
        glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

        glfwPollEvents();

        // Clear screen
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(program);
        glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
        glUniformMatrix4fv(modelMatrixUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix));
        glUniformMatrix4fv(viewMatrixUniform, 1, GL_FALSE, glm::value_ptr(viewMatrix));

        glm::vec3 lightPosition = glm::vec3(4, 4, 4);
        glUniform3f(lightPositionUniform, lightPosition.x, lightPosition.y, lightPosition.z);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glUniform1i(textureSamplerUniform, 0);

        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

        glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

        glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);

        glfwSwapBuffers(window);
    }

    glDeleteProgram(program);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteBuffers(1, &uvBuffer);
    glDeleteBuffers(1, &normalBuffer);
    glDeleteTextures(1, &texture);
    glDeleteVertexArrays(1, &vertexArrayObject);

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

cube.obj:

# Blender3D v249 OBJ File: untitled.blend
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl Material_ray.png
s off
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8

这篇关于OpenGL Assimp导入的模型不呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆