该代码粘贴在下面。它什么也没画。triple
是点的数组。
program = InitShader("vshader.glsl", "fshader.glsl");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triple), triple, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, n_triple / 3);
顶点着色器(vshader.glsl)
#version 400
layout (location = 0) in vec3 vPosition; //In my previous code this varible was named VertexPosition.
void main()
{
gl_Position = vec4(vPosition, 1.0);
}
但是如果我只是删除顶点着色器的链接并将绘图方法更改为
glVertexPointer(3, GL_FLOAT, 0, triple);
它工作正常。即使启用了片段着色器。着色器也可以正常工作。
我只是不知道怎么了。
完整的代码粘贴在下面:
#include "stdafx.h"
#include <windows.h>
#include <cmath>
#include<cstdlib>
#include <GL/glew.h>
#include<GL/wglew.h>
#include <GL/glut.h>
#include<iostream>
#include <cstdio>
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))
//#pragma comment (lib, "glut32.lib")
using namespace std;
GLuint program, loc;
int w, h;
inline void point3(GLfloat points[], GLfloat x, GLfloat y, GLfloat z, int &i) {
points[i++] = x;
points[i++] = y;
points[i++] = z;
}
inline char* readShaderSource(char* shader)
{
FILE *fp;// = fopen(shader, "r");
fopen_s(&fp, shader, "r");
if (!fp)
exit(1);
fseek(fp, 0, SEEK_END);
unsigned long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = new char [size+1];
fread_s(buf, size + 1, sizeof(char), size / sizeof(char), fp);
buf[size] = ' ';
fclose(fp);
return buf;
}
GLuint InitShader(char* vertexShader, char* fragmentShader) {
glewInit();
char* vertexSource = readShaderSource(vertexShader), *fragmentSource = readShaderSource(fragmentShader);
GLuint program;
program = glCreateProgram();
GLuint vshader = glCreateShader(GL_VERTEX_SHADER), fshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vshader, 1, (const GLchar **)&vertexSource, NULL);
glCompileShader(vshader);
glShaderSource(fshader, 1, (const GLchar **) &fragmentSource, NULL);
glCompileShader(fshader);
GLint compiled;
glGetShaderiv(fshader, GL_COMPILE_STATUS, &compiled);
printf("%d", compiled);
GLint length;
glGetShaderiv(fshader, GL_INFO_LOG_LENGTH, &length);
char *msg = new char[length];
glGetShaderInfoLog(fshader, length, NULL, msg);
printf("\n%s\n", msg);
//glAttachShader(program, vshader);
glAttachShader(program, fshader);
GLint linked;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linked);
printf("%d", linked);
glUseProgram(program);
return program;
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WCHAR lpszClassName[] = L"Window";
WCHAR lpszTitle[] = L"Win32 Project";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = lpszClassName;
if (!RegisterClass(&wndclass))
{
MessageBeep(0);
return FALSE;
}
HWND hwnd = CreateWindowW(lpszClassName, lpszTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void SetupPixelFormat(HDC hDC)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
256,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0 };
pfd.cStencilBits = 8;
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
int InitGL(GLvoid)
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 255.0f, 244.0f, 244.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
return TRUE;
}
void ChangeSize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
w = width;
h = height;
}
void RenderScene()
{
static bool runned = false;
if (!runned)
{
runned = true;
//#ifdef DEBUG
FILE* fpDebugOut = NULL;
FILE* fpDebugIn = NULL;
if (!AllocConsole()) MessageBox(NULL, _T("Failed to generate console."), NULL, 0);
SetConsoleTitle(_T("Debug Window"));
_tfreopen_s(&fpDebugOut, _T("CONOUT$"), _T("w"), stdout);
_tfreopen_s(&fpDebugIn, _T("CONIN$"), _T("r"), stdin);
//#endif // DEBUG
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-2.0f, -0.0f, -5.0f);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnableClientState(GL_VERTEX_ARRAY);
const GLfloat toradix = 3.14159265358979324 / 180;
int stepper = 2, r = 2, n_triple = 0;
GLfloat *triple = (GLfloat*)malloc(sizeof(GLfloat) * 4000000);//384480
for (int j = -90 + stepper; j < 90 - stepper;j += stepper)
for (int i = -180; i <= 180;i += stepper)
{
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
j += stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
i += stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
j -= stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
}
program = InitShader("vshader.glsl", "fshader.glsl");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n_triple, triple, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(0));
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, n_triple / 3);
glFlush();
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HGLRC hRC;
static HDC hDC;
switch (message) {
case WM_CREATE: {
hDC = GetDC(hwnd);
SetupPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
InitGL();
return 0;
}
break;
case WM_DESTROY:
{
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
}
break;
case WM_SIZE:
{
ChangeSize(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_PAINT:
{
RenderScene();
SwapBuffers(hDC);
ValidateRect(hwnd, NULL);
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
在OpenGL中,每个顶点属性(以及统一变量)都有其唯一的位置,一种指向该属性的指针。您可以将该位置硬编码为某个值,或者让OpenGL为您决定。
// Hardcode locations in vertex shader:
layout(location = 0) in vec3 Position; // This attribute will always have the location 0
layout(location = 1) in vec2 TexCoord; // This one will use location 1
// Any location / hardcoded in program:
attribute vec4 Normal;
更多关于顶点属性的使用在这里。
当使用“属性”来定义你的顶点属性,你可以使用你的程序进行硬编码它的位置glBindAttribLocation(见链接)。如果不这样做,您将不知道它将占据什么位置。然后,您需要使用glGetAttribLocation查询其位置。
在程序中,您正在搜索称为“ vPosition”的顶点属性的位置,该属性在顶点着色器中不存在。在顶点着色器中,定义一个名为“ VertexPosition”的属性,并将其分配给位置0。在glGetAttribLocation函数中尝试将“ vPosition”替换为“ VertexPosition” 。这样,glGetAttribLocation应该返回0,因为“ VertexPosition”已分配给顶点着色器中的该位置,并且输入应该起作用。
您也可以尝试在程序中将值“ 0”硬编码为变量“ loc”。这样,glEnableVertexAttribArray和glVertexAttribPointer将使用位置“ 0”,该位置在顶点着色器中为其分配了属性“ VertexPosition”。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句