问题
ok so this is the code I use to put the vertex array and buffers onto the graphics card.
void Mesh3D::InitializeBuffers(GLuint program) {
float largestPos = findLargestPosition(&col->vectorGeometry);
std::cout << "largestPos is: ";
std::cout << largestPos;
std::cout << "\n";
int loc;
vaos = new GLuint[nVectorGeometry];
glGenVertexArrays(nVectorGeometry, vaos);//The vertex array object stores the array of vertice indexes used to find the vertex in the buffer vertex buffer object..
vbosPosition = new GLuint[nVectorGeometry];
vbosNormal = new GLuint[nVectorGeometry];
vbosColor = new GLuint[nVectorGeometry];
glGenBuffers(nVectorGeometry, vbosPosition);
glGenBuffers(nVectorGeometry, vbosNormal);
glGenBuffers(nVectorGeometry, vbosColor);
// Configure VBOs to hold positions and normals for each geometry
for (int i = 0; i<nVectorGeometry; i++)//i used to iterate through the individual
{
glBindVertexArray(vaos[i]);
int size = col->vectorGeometry[i].map["POSITION"].size / 4;
float* scaledData = (float*)malloc(size*sizeof(float));
float* p = (float*)col->vectorGeometry[i].map["POSITION"].data;
for (int j = 0; j < size; j++)
{
*(scaledData+j)=*(p+j)/largestPos;
if (*(scaledData + j) < -0.5)
{
std::cout << "scaledData[j] is: ";
std::cout << *(scaledData + j);
std::cout << "\n";
}
}
// Set vertex coordinate data
glBindBuffer(GL_ARRAY_BUFFER, vbosPosition[i]);
glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["POSITION"].size, scaledData, GL_STATIC_DRAW);
free(scaledData);
loc = glGetAttribLocation(program, "in_coords");//get a GLuint for the attribute and put it into GLuint loc.
glVertexAttribPointer(loc, col->vectorGeometry[i].map["POSITION"].stride, col->vectorGeometry[i].map["POSITION"].type, GL_FALSE, 0, 0);//glVertexAttribPointer — loc specifies the index of the generic vertex attribute to be modified.
glEnableVertexAttribArray(0);
#ifdef Testing_Mesh3D
PrintGLVertex(vbosPosition[i], col->vectorGeometry[i].map["POSITION"].size / 4);
#endif // Set normal vector data
glBindBuffer(GL_ARRAY_BUFFER, vbosNormal[i]);
glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["NORMAL"].size, col->vectorGeometry[i].map["NORMAL"].data, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "in_normals");
glVertexAttribPointer(loc, col->vectorGeometry[i].map["NORMAL"].stride, col->vectorGeometry[i].map["NORMAL"].type, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
Material* material = col->mapGeometryUrlToMaterial2Effect[col->vectorGeometry[i].id];
if (material->effect1.size() > 0)
{
std::cout << "size of effect is: ";
std::cout << material->effect1.size();
std::cout << "\n";
Effect* effect1 = material->effect1[0];
if (effect1->type == enumEffectTypes::color)
{
glBindBuffer(GL_ARRAY_BUFFER, vbosColor[i]);
Color color = effect1->color;
//initialize a buffer array for the color with the color for all the geometry repeated over and over.
int vectorColorsSize = col->vectorGeometry[i].map["POSITION"].size;
float* vectorColors = (float*)malloc(vectorColorsSize*sizeof(float));
for (int j = 0; j <vectorColorsSize; j=j+4)
{
float* f = vectorColors + j;
for (int k = 0; k < color.stride; k++)
{
*(f + k) = *(color.values + k);
}
}
glBufferData(GL_ARRAY_BUFFER, vectorColorsSize*sizeof(float), vectorColors, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "in_colors");
glVertexAttribPointer(loc, color.stride , color.type, GL_FALSE, 0, 0);
}
else
{
}
}
glEnableVertexAttribArray(1);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
I know for a fact the array containing the floating point 4 float color data is fully initialized and contains a the same color repeated over and over for each vertex. However for some reason I am still only seeing a black color being drawn instead of the actual color the objects should be.
This is my vertex shader and fragment shader
#pragma once
#ifndef Included_shaders
#define Included_shaders
#include<stdio.h>
#include<iostream>
static std::string shaderVert = "#version 330\n"
"in vec3 in_coords;\n"
"in vec3 in_normals;\n"
"in vec4 in_colors; \n"//added by me
"out vec3 vertex_normal;\n"
"out vec4 vertex_color;\n"
"void main(void) {\n"
"vertex_normal = in_normals;\n"
"vertex_color = in_colors;\n"//added by me
"gl_Position = vec4(in_coords, 1.0);\n"
"}\n";
static std::string shaderFrag = "#version 330\n"
"in vec3 vertex_normal;\n"
"in vec4 vertex_color;\n"
"out vec4 output_color;\n"
"layout(std140) uniform LightParameters{\n"
"vec4 diffuse_intensity;\n"
"vec4 ambient_intensity;\n"
"vec4 light_direction;\n"
"};\n"
"uniform vec4 diffuse_color;\n"
"void main() {\n"
"/* Compute cosine of angle of incidence */\n"
"float cos_incidence = dot(vertex_normal, light_direction.xyz);\n"
"cos_incidence = clamp(cos_incidence, 0, 1);\n"
"/* Compute Blinn term */\n"
"vec3 view_direction = vec3(0, 0, 1);\n"
"vec3 half_angle = normalize(light_direction.xyz + view_direction);\n"
"float blinn_term = dot(vertex_normal, half_angle);\n"
"blinn_term = clamp(blinn_term, 0, 1);\n"
"blinn_term = pow(blinn_term, 1.0);\n"
"output_color=vertex_color\n;"
"}\n";
#endif
This is the function i call to draw
void Mesh3D::DrawToParent()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw elements of each mesh in the vector
for (int i = 0; i<nVectorGeometry; i++)
{
glBindVertexArray(vaos[i]);
glDrawElements(col->vectorGeometry[i].primitive/*This is 4 for GL_Triangles*/, col->vectorGeometry[i].index_count,
GL_UNSIGNED_SHORT, col->vectorGeometry[i].indices);
}
glBindVertexArray(0);
glutSwapBuffers();
}
I would really appreciate it if someone could figure out where I am going wrong. I am rather new to drawing 3d graphics with opengl but wanted to create my own classes to draw complicated 3d scenes. I have the objects vertices being drawn correctly but now im trying to add the color which I also read in from the COLLADA file.
回答1:
I believe the problem is that you glEnableVertexAttribArray(0);
twice and glEnableVertexAttribArray(1);
once. Instead you should enable the vertex attribute locations that you used to point to your data.
So, after each glVertexAttribPointer
call glEnableVertexAttribArray(loc);
Appendix: All the necessary steps for using a VBO (taken from some of my code) its in Go, but the functions work exactly the same.
Vbos[2].Bind(gl.ARRAY_BUFFER)
gl.BufferData(gl.ARRAY_BUFFER, size*4, texCoord, gl.STREAM_DRAW)
self.texcoordloc.AttribPointer(4, gl.FLOAT, false, 0, nil)
self.texcoordloc.EnableArray()
defer self.texcoordloc.DisableArray()
来源:https://stackoverflow.com/questions/30675949/having-trouble-drawing-coloured-vertices-using-shader-in-opengl-to-draw-data-rea