这是我的main.cpp,我想画一辆车,我从obj文件中获取数据,然后放入着色器。我将我的obj文件放入meshlab,它正确绘制 - > ,但在我的c ++中会喜欢这个 - >
#include "..\tinyobjloader\tiny_obj_loader.h"
#include <algorithm>
#include <iostream>
#include<glew.h>
#include <glut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <chrono>
#include<SOIL.h>
#include<math.h>
#include"Shader.h"
GLuint programHandle;
GLuint vShader, fShader;
static GLuint g_TexName;
GLuint vaoHandle;
std::vector<GLfloat> vertices;
std::vector<GLfloat> colorData;
std::vector<GLfloat> texCoords;
std::vector<unsigned int> elements;
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
GLuint vboHandles[4];
GLuint elementbuffer;
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
GLuint textureBufferHandle = vboHandles[2];
GLuint mvphandle = vboHandles[3];
unsigned char * data;
using namespace std;
float t = 0.0;
float maxs = 0;
void initShader(const char *VShaderFile, const char *FShaderFile)
{
//1、查看GLSL和OpenGL的版本
const GLubyte *renderer = glGetString(GL_RENDERER);
const GLubyte *vendor = glGetString(GL_VENDOR);
const GLubyte *version = glGetString(GL_VERSION);
const GLubyte *glslVersion =
glGetString(GL_SHADING_LANGUAGE_VERSION);
GLint major, minor;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
//cout << "GL Vendor :" << vendor << endl;
//cout << "GL Renderer : " << renderer << endl;
//cout << "GL Version (string) : " << version << endl;
//cout << "GL Version (integer) : " << major << "." << minor << endl;
//cout << "GLSL Version : " << glslVersion << endl;
vShader = glCreateShader(GL_VERTEX_SHADER);
if (0 == vShader)
{
cerr << "ERROR : Create vertex shader failed" << endl;
exit(1);
}
const GLchar *vShaderCode = textFileRead(VShaderFile);
const GLchar *vCodeArray[1] = { vShaderCode };
glShaderSource(vShader, 1, vCodeArray, NULL);
glCompileShader(vShader);
GLint compileResult;
glGetShaderiv(vShader, GL_COMPILE_STATUS, &compileResult);
if (GL_FALSE == compileResult)
{
GLint logLen;
glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0)
{
char *log = (char *)malloc(logLen);
GLsizei written;
glGetShaderInfoLog(vShader, logLen, &written, log);
cerr << "vertex shader compile log : " << endl;
cerr << log << endl;
free(log);
}
}
fShader = glCreateShader(GL_FRAGMENT_SHADER);
if (0 == fShader)
{
cerr << "ERROR : Create fragment shader failed" << endl;
exit(1);
}
const GLchar *fShaderCode = textFileRead(FShaderFile);
const GLchar *fCodeArray[1] = { fShaderCode };
glShaderSource(fShader, 1, fCodeArray, NULL);
glCompileShader(fShader);
glGetShaderiv(fShader, GL_COMPILE_STATUS, &compileResult);
if (GL_FALSE == compileResult)
{
GLint logLen;
glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0)
{
char *log = (char *)malloc(logLen);
GLsizei written;
glGetShaderInfoLog(fShader, logLen, &written, log);
cerr << "fragment shader compile log : " << endl;
cerr << log << endl;
free(log);
}
}
//GLuint programHandle = glCreateProgram();
programHandle = glCreateProgram();
if (!programHandle)
{
cerr << "ERROR : create program failed" << endl;
exit(1);
}
glAttachShader(programHandle, vShader);
glAttachShader(programHandle, fShader);
glLinkProgram(programHandle);
GLint linkStatus;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus);
if (GL_FALSE == linkStatus)
{
cerr << "ERROR : link shader program failed" << endl;
GLint logLen;
glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH,
&logLen);
if (logLen > 0)
{
char *log = (char *)malloc(logLen);
GLsizei written;
glGetProgramInfoLog(programHandle, logLen,
&written, log);
cerr << "Program log : " << endl;
cerr << log << endl;
}
}
else
{
glUseProgram(programHandle);
}
}
void LoadTexture(){
// Load texture
errno_t err;
// Data read from the header of the BMP file
unsigned char header[54];
unsigned int dataPos;
unsigned int imageSize;
//unsigned int width, height;
// Actual RGB data
int width, height, nrChannels;
//data = SOIL_load_image("wall.bmp", &width, &height, 0, SOIL_LOAD_RGB);
FILE * file;
const char imagepath[] = "Van.bmp";
if (err = fopen_s(&file, imagepath, "rb")){ printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); }
if (fread(header, 1, 54, file) != 54){
printf("Not a correct BMP file\n");
}
// A BMP files always begins with "BM"
if (header[0] != 'B' || header[1] != 'M'){
printf("Not a correct BMP file\n");
}
// Make sure this is a 24bpp file
if (*(int*)&(header[0x1E]) != 0) { printf("Not a correct BMP file\n"); }
if (*(int*)&(header[0x1C]) != 24) { printf("Not a correct BMP file\n"); }
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
printf("width : %d hight : %d\n", width, height);
data = new unsigned char[imageSize];
cout << imageSize << endl;
// Read the actual data from the file into the buffer
fread(data, 1, imageSize, file);
// Everything is in memory now, the file wan be closed
fclose(file);
GLuint textureID;
glGenTextures(1, &textureID);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, textureID);
// Give the image to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glUniform1i(glGetUniformLocation(programHandle, "tex"), 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
void initVBO()
{
glGenVertexArrays(1, &vaoHandle);
glBindVertexArray(vaoHandle);
glGenBuffers(3, vboHandles);
GLuint positionBufferHandle = vboHandles[0];
GLuint colorBufferHandle = vboHandles[1];
GLuint textureBufferHandle = vboHandles[2];
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, attrib.vertices.size(),&vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, attrib.colors.size(),&colorData[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, textureBufferHandle);
if (texCoords.size()>0)
glBufferData(GL_ARRAY_BUFFER, attrib.texcoords.size(),&texCoords[0], GL_STATIC_DRAW);
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, shapes[0].mesh.num_face_vertices.size() , &elements[0], GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size()*sizeof(unsigned int), &elements[0], GL_STATIC_DRAW);
cout << "element*sizeof(unsigned int) = " << elements.size()*sizeof(unsigned int) << endl;
glEnableVertexAttribArray(0); //頂點坐標
glEnableVertexAttribArray(1); //頂點顏色
glEnableVertexAttribArray(2); //texture
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, textureBufferHandle);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void init()
{
GLenum err = glewInit();
if (GLEW_OK != err)
{
std::cout << "Error initializing GLEW: " << glewGetErrorString(err) << std::endl;
}
initShader("vert.txt", "frag.txt");
initVBO();
LoadTexture();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glShadeModel(GL_SMOOTH);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//cout << "display--> " << endl;
//cout << vertices[0] << endl << vertices[1] << endl << vertices[2] << endl;
t += 0.0001f;
if (t >= 1)
t = 0;
// Set the camera
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 1.0f, 100.0f);
//glm::mat4 Projection = glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 0.0f, 10.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(2.5f, 2.0f, 3.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f)
);
glm::mat4 Model = glm::mat4(1.0f);
Model = glm::rotate(
Model,
glm::radians(360.0f*t),
glm::vec3(0.0f, 0.0f, 1.0f)
);
/*Model = glm::scale(
glm::translate(Model, glm::vec3(0, 0, 0)),
glm::vec3(2 / maxs, 2 / maxs, 2 / maxs)
);*/
GLuint MVP = glGetUniformLocation(programHandle, "mvp");
glm::mat4 mvp = Projection*View*Model;
glUniformMatrix4fv(MVP, 1, GL_FALSE, &mvp[0][0]);
glBindVertexArray(vaoHandle);
//glDrawArrays(GL_TRIANGLES, 0, attrib.vertices.size());
//glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
//glDrawElements(GL_TRIANGLES, attrib.vertices.size(), GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
//glBindVertexArray(0);
//cout << shapes[0].mesh.num_face_vertices.size() << endl;
glDrawElements(GL_TRIANGLES, elements.size() , GL_UNSIGNED_INT, (void*)0);
//glDrawElements(GL_QUADS, elements.size(), GL_UNSIGNED_INT, (void*)0);
glutSwapBuffers();
}
void Reshape(int w, int h)
{
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
//glOrtho(-25,25,-2,2,0.1,100);
glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
glDeleteShader(vShader);
glUseProgram(0);
exit(0);
break;
}
}
void normalize(){
std::vector<float> xVector, yVector, zVector;
float minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0;
// find out min and max value of X, Y and Z axis
for (int i = 0; i < attrib.vertices.size(); i++)
{
maxs = max(maxs, attrib.vertices.at(i));
if (i % 3 == 0)
{
xVector.push_back(attrib.vertices.at(i));
if (attrib.vertices.at(i) < minX)
{
minX = attrib.vertices.at(i);
}
if (attrib.vertices.at(i) > maxX)
{
maxX = attrib.vertices.at(i);
}
}
else if (i % 3 == 1)
{
yVector.push_back(attrib.vertices.at(i));
if (attrib.vertices.at(i) < minY)
{
minY = attrib.vertices.at(i);
}
if (attrib.vertices.at(i) > maxY)
{
maxY = attrib.vertices.at(i);
}
}
else if (i % 3 == 2)
{
zVector.push_back(attrib.vertices.at(i));
if (attrib.vertices.at(i) < minZ)
{
minZ = attrib.vertices.at(i);
}
if (attrib.vertices.at(i) > maxZ)
{
maxZ = attrib.vertices.at(i);
}
}*/
}
float offsetX = (maxX + minX) / 2;
float offsetY = (maxY + minY) / 2;
float offsetZ = (maxZ + minZ) / 2;
/*for (int i = 0; i < attrib.vertices.size(); i++)
{
if (offsetX != 0 && i % 3 == 0)
{
attrib.vertices.at(i) = attrib.vertices.at(i) - offsetX;
}
else if (offsetY != 0 && i % 3 == 1)
{
attrib.vertices.at(i) = attrib.vertices.at(i) - offsetY;
}
else if (offsetZ != 0 && i % 3 == 2)
{
attrib.vertices.at(i) = attrib.vertices.at(i) - offsetZ;
}
}
// Find out the greatest distance of three axis
float greatestAxis = maxX - minX;
float distanceOfYAxis = maxY - minY;
float distanceOfZAxis = maxZ - minZ;
if (distanceOfYAxis > greatestAxis)
{
greatestAxis = distanceOfYAxis;
}
if (distanceOfZAxis > greatestAxis)
{
greatestAxis = distanceOfZAxis;
}
greatestAxis = greatestAxis / 2;
for (int i = 0; i < attrib.vertices.size(); i++)
{
//std::cout << i << " = " << (double)(attrib.vertices.at(i) / greatestAxis) << std::endl;
attrib.vertices.at(i) = attrib.vertices.at(i) / greatestAxis;
vertices.push_back(attrib.vertices.at(i));
}
for (int i = 0; i < attrib.colors.size(); i++)
colorData.push_back(attrib.colors.at(i));
for (int i = 0; i < attrib.texcoords.size(); i++)
texCoords.push_back(attrib.texcoords.at(i));
for (int k = 0; k < shapes.size(); k++){
for (int i = 0; i < shapes[k].mesh.indices.size(); i++){
elements.push_back(shapes[k].mesh.indices[i].vertex_index);
//cout << i << " = " << shapes[0].mesh.indices[i].vertex_index<<endl;
//elements.push_back(shapes[0].mesh.indices[i].texcoord_index);
//elements.push_back(shapes[0].mesh.indices[i].normal_index);
}
}
cout << "shapes[0].mesh.indices.size() = " << shapes[0].mesh.indices.size() << endl;
//cout << "elements = " << elements[4750] << endl;
}
int main()
{
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, "..//tinyobjloader//models//Van.obj",
NULL, false);
normalize();
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("GLSL Test : Draw a triangle");
glutReshapeFunc(Reshape);
init();
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_LESS);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
这是我的vertex.shader,我使用着色器编译器,没有错误。
#version 400
in vec3 Color;
in vec2 texcoord;
out vec4 FragColor;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, vec2(texcoord.x,texcoord.y))*vec4(Color, 1.0);
//FragColor = vec4(1, 0, 0, 1);
//if(Color.x>=0)FragColor = vec4(Color, 1.0);
}
这是我的fragment.shader,我使用着色器编译器,没有错误。
#version 400
in vec3 Color;
in vec2 texcoord;
out vec4 FragColor;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, vec2(texcoord.x,texcoord.y))*vec4(Color, 1.0);
}
答案 0 :(得分:1)
我引用了上面kevin su的评论:
最后,我找到了答案。 attrib.vertices.size()应该更改为sizeof(顶点)。 attrib.vertices.size()是点数,sizeof(顶点)是(points * sizeof(unsign int))的数量。