OpenGL - 着色器加载但只能显示 2D 三角形
OpenGL - Shader loads but can only display 2D triangles
我完全运行没主意了。我正在尝试让我的着色器在 OpenGL 中工作,并已将我的代码带回超级基础以尝试这样做。
当我 运行 我的代码使用 glDrawArrays 时,我得到一个蓝色三角形,这告诉我我的着色器正在工作。我还可以在片段着色器中设置颜色以证明它可以修复颜色。
如您所见,我使用了我测试过的变量 'numOfVerts',任何低于 3 的值都不会像预期的那样绘制任何东西,但是任何高于 3 的值都会绘制相同的基本 2D 三角形而不是立方体。
其代码如下:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glUseProgram(myShader.handle()); // use the shader
GLuint matLocation = glGetUniformLocation(myShader.handle(), "ProjectionMatrix");
glUniformMatrix4fv(matLocation, 1, GL_FALSE, &ProjectionMatrix[0][0]);
//Draw code
glBindVertexArray(m_vaoID); // select VAO
glDrawArrays(GL_TRIANGLES, 0, numOfVerts); //draw some geometry
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the buffer
glBindVertexArray(0);
glUseProgram(0); //turn off the current shader
return TRUE; // Keep Going
}
我尝试绘制完整立方体的另一种绘制方法使用 glDrawElements,但是所有这一切都向我展示了一个空白的白屏:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glUseProgram(myShader.handle()); // use the shader
GLuint matLocation = glGetUniformLocation(myShader.handle(), "ProjectionMatrix");
glUniformMatrix4fv(matLocation, 1, GL_FALSE, &ProjectionMatrix[0][0]);
//draw objects
glBindVertexArray(m_vaoID); // select VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
// Done
glBindVertexArray(0); //unbind the vertex array object
return TRUE; // Keep Going
}
这是我的垂直着色器:
#version 150
uniform mat4 ProjectionMatrix;
in vec3 in_Position; // Position coming in
in vec3 in_Color; // colour coming in
out vec3 ex_Color; // colour leaving the vertex, this will be sent to the fragment shader
void main(void)
{
gl_Position = ProjectionMatrix * vec4(in_Position, 1.0);
ex_Color = in_Color;
}
这是我的片段着色器:
#version 150
in vec3 ex_Color; //colour arriving from the vertex
out vec4 out_Color; //colour for the pixel
void main(void)
{
out_Color = vec4(ex_Color,1.0);
}
以下代码是我为了使它正常工作而剥离我的程序的代码,并显示了我的 'drawTest' 方法以及所有相关的顶点和索引数组以及相关的设置代码。 drawTest 方法在我的初始化函数中被调用一次:
/**includes**/
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/wglew.h>
#include "boost\lexical_cast.hpp"
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include "Image_Loading/nvImage.h"
#include <map>
#include "MenuController.h"
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include "../glm/glm.hpp"
#include "../glm/gtc/matrix_transform.hpp"
#include "../glm/gtc/type_ptr.hpp"
#include "../glm/gtc/matrix_inverse.hpp"
#include <vector>
#include <algorithm> // std::reverse
#include <iostream>
#include "console.h"
#include "DistanceCalculator.h"
#include "Shader.h"
/* Variables*/
glm::mat4 ProjectionMatrix; // matrix for the orthographic projection
unsigned int m_vaoID; // vertex array object
unsigned int m_vboID[2]; // two VBOs - used for colours and vertex data
unsigned int ibo;
const int numOfVerts = 3;
const int numOfTris = 1;
float verts[9];
float cols[9];
Shader myShader; ///shader object
//index array to draw basic cube
GLubyte indicesTest5[] = {
0,1,2,2,3,0, // back
5,6,7,7,4,5, // front
1,2,7,7,6,1, // left
0,3,4,4,5,0, // right
0,1,6,6,5,0, // top
2,3,4,4,7,2 // bottom
};
/*Method to draw a simple cube using shaders*/
void drawTest(){
int dim = 20;
//8 vertices to define a basic cube
GLfloat verticesTest2[] = {
/*0*/dim, dim, -dim,
/*1*/-dim, dim, -dim,
/*2*/-dim, -dim, -dim,
/*3*/dim, -dim, -dim,
/*4*/dim, -dim, dim,
/*5*/dim, dim, dim,
/*6*/-dim, dim, dim,
/*7*/-dim, -dim, dim
};
//Create a vec3 array that will store the x,y,z of the 8 vertices more understandably
std::vector<glm::vec3 > cubeVerts;
for (int i = 0; i < 24; i += 3){ //verticesTest2 size of
glm::vec3 vert = glm::vec3(verticesTest2[i], verticesTest2[i+1], verticesTest2[i+2]);
cubeVerts.push_back(vert);
}
/*****THIS PART JUST BUILDS A VERT NORMALS LIST****/
//define a vector to store the x,y,z of each vertex normal (so 8 in total)
std::vector<glm::vec3 > vertNormals;
//loop for the amount of vertices that we have
for (int i = 0; i < cubeVerts.size(); i++){
//define tracking variables
int currentVertexIndex = i;
int faceCount = 0;
glm::vec3 faceNormalSum = glm::vec3(0, 0, 0);
//loop for all 36 indices within the index array
for (int j = 0; j < 36; j++){
//if the current vertex has been located in the index array
if (indicesTest5[j] == currentVertexIndex){
//calculate a modulo of the position to determine the vertex position in the index array (1st, 2nd or 3rd vertex of the triangle)
int positionMod = j % 3;
glm::vec3 v1, v2, v3;
//if the first vertex in a triangle, or the first array element
if (positionMod == 0 || j == 0){
v1 = cubeVerts.at(indicesTest5[j]);
v2 = cubeVerts.at(indicesTest5[j+1]);
v3 = cubeVerts.at(indicesTest5[j+2]);
}
//if second vertex in a triangle, or the second array element
else if (positionMod == 1 || j ==1){
v1 = cubeVerts.at(indicesTest5[j-1]);
v2 = cubeVerts.at(indicesTest5[j]);
v3 = cubeVerts.at(indicesTest5[j+1]);
}
//if third vertex in a triangle, or the third array element
else if (positionMod == 2 || j == 2){
v1 = cubeVerts.at(indicesTest5[j-2]);
v2 = cubeVerts.at(indicesTest5[j-1]);
v3 = cubeVerts.at(indicesTest5[j]);
}
//increment the amount of faces surrounding the current vertex
faceCount++;
/*calculate face normal*/
//calculate 2 vectors of the current triangle
glm::vec3 V = v2 - v1;
glm::vec3 W = v3 - v1;
//calculate the cross product of these vectors to get the face normal
glm::vec3 faceNormal = glm::cross(V,W);
//normalize the obtained face normal
faceNormal = glm::normalize(faceNormal);
//add this to the current sum of the facenormals values
faceNormalSum += faceNormal;
}
}
//Once all indices checked for the current vertex, divide each x,y,z value in the faceNormalSum by the amount of
//surrounding faces detected to give a mean value and therefore the normal for that vertex
vertNormals.push_back(glm::vec3(faceNormalSum.x / faceCount, faceNormalSum.y / faceCount, faceNormalSum.z / faceCount));
}
/*****END OF VERT NORMALS CREATION*****/
//Create a vector to store all the vertex normal values as floats (much like the vertices list)
vector<float> vertNormalVector;
vertNormalVector.clear();
for (int i = 0; i < vertNormals.size(); i++){
vertNormalVector.push_back(vertNormals.at(i).x);
vertNormalVector.push_back(vertNormals.at(i).y);
vertNormalVector.push_back(vertNormals.at(i).z);
}
//create a pointer for the vertexNormal vector
float* vertexNormal = &vertNormalVector[0];
vector<Vertex> vertices;
for (int x = 0; x < 8; x++){
Vertex vertStruct = Vertex();
vertStruct.position = cubeVerts.at(x);
vertStruct.normal = vertNormals.at(x);
vertices.push_back(vertStruct);
}
//By this point I simply have a vertices array, a vertex normal array and an array of indices.
//So I can set all the buffers shown below
// VAO allocation
glGenVertexArrays(1, &m_vaoID);
// First VAO setup
glBindVertexArray(m_vaoID);
glGenBuffers(2, m_vboID);
glBindBuffer(GL_ARRAY_BUFFER, m_vboID[0]);
//initialises data storage of vertex buffer object
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), verticesTest2, GL_STATIC_DRAW);
GLint vertexLocation = glGetAttribLocation(myShader.handle(), "in_Position");
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexLocation);
//storage of normals (will simply act as colours for this example)
glBindBuffer(GL_ARRAY_BUFFER, m_vboID[1]);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertexNormal, GL_STATIC_DRAW);
GLint colorLocation = glGetAttribLocation(myShader.handle(), "in_Color");
glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(colorLocation);
//index buffer for indices defined above
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(unsigned int), indicesTest5, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
/*Resize method to update projection matrix*/
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height == 0) // Prevent A Divide By Zero By
{
height = 1; // Making Height Equal One
}
glViewport(0, 0, width, height); // Reset The Current Viewport
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);*/
aspectRatio = (GLfloat)width / (GLfloat)height;
screenHeight = (GLfloat)height;
screenWidth = (GLfloat)width;
ProjectionMatrix = glm::perspective(60.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 1.0f, 200.0f);
}
/*Init to load shader and call drawTest defined above*/
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background
if (!myShader.load("BasicView", "../glslfiles/basic.vert", "../glslfiles/basic.frag"))
{
cout << "failed to load shader" << endl;
}
drawTest();
return TRUE; // Initialization Went OK
}
/*This code is where I set up my glew*/
/*AT THE END OF MY 'CreateGLWindow' METHOD*/
HGLRC tempContext = wglCreateContext(hDC);
wglMakeCurrent(hDC, tempContext);
glewExperimental = TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "glewInit failed, aborting." << std::endl;
}
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
};
if (wglewIsSupported("WGL_ARB_create_context") == 1)
{
hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
wglMakeCurrent(hDC, hRC);
}
else
{ //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before)
hRC = tempContext;
cout << " not possible to make context " << endl;
}
ShowWindow(hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
有人知道为什么我似乎不能渲染超过一个 2D 三角形吗?
我也没有 compile/runtime 以上代码的错误。
这已通过遵循 Reto Koradi 的评论建议解决,即确保在定义索引、将索引加载到缓冲区和绘制时使用相同的类型。
所以正确的工作代码如下:
要创建索引列表,将它们声明为 GLuint:
GLuint indicesTest5[] = {
0,1,2,2,3,0, // back
5,6,7,7,4,5, // front
1,2,7,7,6,1, // left
0,3,4,4,5,0, // right
0,1,6,6,5,0, // top
2,3,4,4,7,2 // bottom
};
确保在加载到缓冲区时使用 GLuint:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLuint), indicesTest5, GL_STATIC_DRAW);
确保绘图时使用GL_UNSIGNED_INT:
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
我完全运行没主意了。我正在尝试让我的着色器在 OpenGL 中工作,并已将我的代码带回超级基础以尝试这样做。
当我 运行 我的代码使用 glDrawArrays 时,我得到一个蓝色三角形,这告诉我我的着色器正在工作。我还可以在片段着色器中设置颜色以证明它可以修复颜色。 如您所见,我使用了我测试过的变量 'numOfVerts',任何低于 3 的值都不会像预期的那样绘制任何东西,但是任何高于 3 的值都会绘制相同的基本 2D 三角形而不是立方体。 其代码如下:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glUseProgram(myShader.handle()); // use the shader
GLuint matLocation = glGetUniformLocation(myShader.handle(), "ProjectionMatrix");
glUniformMatrix4fv(matLocation, 1, GL_FALSE, &ProjectionMatrix[0][0]);
//Draw code
glBindVertexArray(m_vaoID); // select VAO
glDrawArrays(GL_TRIANGLES, 0, numOfVerts); //draw some geometry
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the buffer
glBindVertexArray(0);
glUseProgram(0); //turn off the current shader
return TRUE; // Keep Going
}
我尝试绘制完整立方体的另一种绘制方法使用 glDrawElements,但是所有这一切都向我展示了一个空白的白屏:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glUseProgram(myShader.handle()); // use the shader
GLuint matLocation = glGetUniformLocation(myShader.handle(), "ProjectionMatrix");
glUniformMatrix4fv(matLocation, 1, GL_FALSE, &ProjectionMatrix[0][0]);
//draw objects
glBindVertexArray(m_vaoID); // select VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
// Done
glBindVertexArray(0); //unbind the vertex array object
return TRUE; // Keep Going
}
这是我的垂直着色器:
#version 150
uniform mat4 ProjectionMatrix;
in vec3 in_Position; // Position coming in
in vec3 in_Color; // colour coming in
out vec3 ex_Color; // colour leaving the vertex, this will be sent to the fragment shader
void main(void)
{
gl_Position = ProjectionMatrix * vec4(in_Position, 1.0);
ex_Color = in_Color;
}
这是我的片段着色器:
#version 150
in vec3 ex_Color; //colour arriving from the vertex
out vec4 out_Color; //colour for the pixel
void main(void)
{
out_Color = vec4(ex_Color,1.0);
}
以下代码是我为了使它正常工作而剥离我的程序的代码,并显示了我的 'drawTest' 方法以及所有相关的顶点和索引数组以及相关的设置代码。 drawTest 方法在我的初始化函数中被调用一次:
/**includes**/
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/wglew.h>
#include "boost\lexical_cast.hpp"
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include "Image_Loading/nvImage.h"
#include <map>
#include "MenuController.h"
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include "../glm/glm.hpp"
#include "../glm/gtc/matrix_transform.hpp"
#include "../glm/gtc/type_ptr.hpp"
#include "../glm/gtc/matrix_inverse.hpp"
#include <vector>
#include <algorithm> // std::reverse
#include <iostream>
#include "console.h"
#include "DistanceCalculator.h"
#include "Shader.h"
/* Variables*/
glm::mat4 ProjectionMatrix; // matrix for the orthographic projection
unsigned int m_vaoID; // vertex array object
unsigned int m_vboID[2]; // two VBOs - used for colours and vertex data
unsigned int ibo;
const int numOfVerts = 3;
const int numOfTris = 1;
float verts[9];
float cols[9];
Shader myShader; ///shader object
//index array to draw basic cube
GLubyte indicesTest5[] = {
0,1,2,2,3,0, // back
5,6,7,7,4,5, // front
1,2,7,7,6,1, // left
0,3,4,4,5,0, // right
0,1,6,6,5,0, // top
2,3,4,4,7,2 // bottom
};
/*Method to draw a simple cube using shaders*/
void drawTest(){
int dim = 20;
//8 vertices to define a basic cube
GLfloat verticesTest2[] = {
/*0*/dim, dim, -dim,
/*1*/-dim, dim, -dim,
/*2*/-dim, -dim, -dim,
/*3*/dim, -dim, -dim,
/*4*/dim, -dim, dim,
/*5*/dim, dim, dim,
/*6*/-dim, dim, dim,
/*7*/-dim, -dim, dim
};
//Create a vec3 array that will store the x,y,z of the 8 vertices more understandably
std::vector<glm::vec3 > cubeVerts;
for (int i = 0; i < 24; i += 3){ //verticesTest2 size of
glm::vec3 vert = glm::vec3(verticesTest2[i], verticesTest2[i+1], verticesTest2[i+2]);
cubeVerts.push_back(vert);
}
/*****THIS PART JUST BUILDS A VERT NORMALS LIST****/
//define a vector to store the x,y,z of each vertex normal (so 8 in total)
std::vector<glm::vec3 > vertNormals;
//loop for the amount of vertices that we have
for (int i = 0; i < cubeVerts.size(); i++){
//define tracking variables
int currentVertexIndex = i;
int faceCount = 0;
glm::vec3 faceNormalSum = glm::vec3(0, 0, 0);
//loop for all 36 indices within the index array
for (int j = 0; j < 36; j++){
//if the current vertex has been located in the index array
if (indicesTest5[j] == currentVertexIndex){
//calculate a modulo of the position to determine the vertex position in the index array (1st, 2nd or 3rd vertex of the triangle)
int positionMod = j % 3;
glm::vec3 v1, v2, v3;
//if the first vertex in a triangle, or the first array element
if (positionMod == 0 || j == 0){
v1 = cubeVerts.at(indicesTest5[j]);
v2 = cubeVerts.at(indicesTest5[j+1]);
v3 = cubeVerts.at(indicesTest5[j+2]);
}
//if second vertex in a triangle, or the second array element
else if (positionMod == 1 || j ==1){
v1 = cubeVerts.at(indicesTest5[j-1]);
v2 = cubeVerts.at(indicesTest5[j]);
v3 = cubeVerts.at(indicesTest5[j+1]);
}
//if third vertex in a triangle, or the third array element
else if (positionMod == 2 || j == 2){
v1 = cubeVerts.at(indicesTest5[j-2]);
v2 = cubeVerts.at(indicesTest5[j-1]);
v3 = cubeVerts.at(indicesTest5[j]);
}
//increment the amount of faces surrounding the current vertex
faceCount++;
/*calculate face normal*/
//calculate 2 vectors of the current triangle
glm::vec3 V = v2 - v1;
glm::vec3 W = v3 - v1;
//calculate the cross product of these vectors to get the face normal
glm::vec3 faceNormal = glm::cross(V,W);
//normalize the obtained face normal
faceNormal = glm::normalize(faceNormal);
//add this to the current sum of the facenormals values
faceNormalSum += faceNormal;
}
}
//Once all indices checked for the current vertex, divide each x,y,z value in the faceNormalSum by the amount of
//surrounding faces detected to give a mean value and therefore the normal for that vertex
vertNormals.push_back(glm::vec3(faceNormalSum.x / faceCount, faceNormalSum.y / faceCount, faceNormalSum.z / faceCount));
}
/*****END OF VERT NORMALS CREATION*****/
//Create a vector to store all the vertex normal values as floats (much like the vertices list)
vector<float> vertNormalVector;
vertNormalVector.clear();
for (int i = 0; i < vertNormals.size(); i++){
vertNormalVector.push_back(vertNormals.at(i).x);
vertNormalVector.push_back(vertNormals.at(i).y);
vertNormalVector.push_back(vertNormals.at(i).z);
}
//create a pointer for the vertexNormal vector
float* vertexNormal = &vertNormalVector[0];
vector<Vertex> vertices;
for (int x = 0; x < 8; x++){
Vertex vertStruct = Vertex();
vertStruct.position = cubeVerts.at(x);
vertStruct.normal = vertNormals.at(x);
vertices.push_back(vertStruct);
}
//By this point I simply have a vertices array, a vertex normal array and an array of indices.
//So I can set all the buffers shown below
// VAO allocation
glGenVertexArrays(1, &m_vaoID);
// First VAO setup
glBindVertexArray(m_vaoID);
glGenBuffers(2, m_vboID);
glBindBuffer(GL_ARRAY_BUFFER, m_vboID[0]);
//initialises data storage of vertex buffer object
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), verticesTest2, GL_STATIC_DRAW);
GLint vertexLocation = glGetAttribLocation(myShader.handle(), "in_Position");
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexLocation);
//storage of normals (will simply act as colours for this example)
glBindBuffer(GL_ARRAY_BUFFER, m_vboID[1]);
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertexNormal, GL_STATIC_DRAW);
GLint colorLocation = glGetAttribLocation(myShader.handle(), "in_Color");
glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(colorLocation);
//index buffer for indices defined above
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(unsigned int), indicesTest5, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
/*Resize method to update projection matrix*/
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height == 0) // Prevent A Divide By Zero By
{
height = 1; // Making Height Equal One
}
glViewport(0, 0, width, height); // Reset The Current Viewport
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);*/
aspectRatio = (GLfloat)width / (GLfloat)height;
screenHeight = (GLfloat)height;
screenWidth = (GLfloat)width;
ProjectionMatrix = glm::perspective(60.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 1.0f, 200.0f);
}
/*Init to load shader and call drawTest defined above*/
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background
if (!myShader.load("BasicView", "../glslfiles/basic.vert", "../glslfiles/basic.frag"))
{
cout << "failed to load shader" << endl;
}
drawTest();
return TRUE; // Initialization Went OK
}
/*This code is where I set up my glew*/
/*AT THE END OF MY 'CreateGLWindow' METHOD*/
HGLRC tempContext = wglCreateContext(hDC);
wglMakeCurrent(hDC, tempContext);
glewExperimental = TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "glewInit failed, aborting." << std::endl;
}
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
};
if (wglewIsSupported("WGL_ARB_create_context") == 1)
{
hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
wglMakeCurrent(hDC, hRC);
}
else
{ //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before)
hRC = tempContext;
cout << " not possible to make context " << endl;
}
ShowWindow(hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
有人知道为什么我似乎不能渲染超过一个 2D 三角形吗? 我也没有 compile/runtime 以上代码的错误。
这已通过遵循 Reto Koradi 的评论建议解决,即确保在定义索引、将索引加载到缓冲区和绘制时使用相同的类型。
所以正确的工作代码如下:
要创建索引列表,将它们声明为 GLuint:
GLuint indicesTest5[] = {
0,1,2,2,3,0, // back
5,6,7,7,4,5, // front
1,2,7,7,6,1, // left
0,3,4,4,5,0, // right
0,1,6,6,5,0, // top
2,3,4,4,7,2 // bottom
};
确保在加载到缓冲区时使用 GLuint:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLuint), indicesTest5, GL_STATIC_DRAW);
确保绘图时使用GL_UNSIGNED_INT:
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);